From a776c5d61592d93a64a9a5dce70cdcfd5ce70a81 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Wed, 19 Aug 2026 22:25:54 +0200 Subject: [PATCH] Update next breaking (#12666) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * build(docker): compile backend translations during image build (#12203) * build(docker): compile backend trasnlations during image build * test(docker): verify compiled backend translations exist in image Add checks to the "Test Docker Image" step that assert the compiled django.mo files are present for a few representative languages (de, fr, ru, zh_Hans). This guards the newly added backend translation compilation step in the production Dockerfile, ensuring the multilingual artifacts are produced at the expected locale paths. * test(docker): verify compiled frontend translations exist in image * Add meaningful message on CSRF failure (#12216) * Add meaningful message on CSRF failure * Add link to CSRF_FAILURE_VIEW * Add unit test for new CSRF feedback * devops: fix chromium test uploads to flakiness.io (#12219) Currently, only Firefox test results get uploaded to Flakiness.io. This patch fixes the upload for chromium results as well, per https://docs.flakiness.io/ci/github-actions-setup/ * Bump ty (#12211) * bump ty * various fixes * fix settings * bump stubs * update pre-commit setup * update ignore * fix various issues * fix style * fix ignores * fix wrong ty warnings * color scheme: Use the users prefered mode by default (#12227) * color scheme: Use the users prefered colour scheme if one isn't defined in the store * fix style --------- Co-authored-by: Matthias Mair * chore(deps): bump the dependencies group with 3 updates (#12220) Bumps the dependencies group with 3 updates: [oasdiff/oasdiff-action](https://github.com/oasdiff/oasdiff-action), [CodSpeedHQ/action](https://github.com/codspeedhq/action) and [crowdin/github-action](https://github.com/crowdin/github-action). Updates `oasdiff/oasdiff-action` from 0.0.57 to 0.1.1 - [Release notes](https://github.com/oasdiff/oasdiff-action/releases) - [Commits](https://github.com/oasdiff/oasdiff-action/compare/3530478ec30f84adedbfeb28f0d9527a290f50a9...5fbe96ede8d0c53aeadef122d7a0abb79152d493) Updates `CodSpeedHQ/action` from 4.17.0 to 4.17.5 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/9d332c4d90b43981c3e55ae8e38e68709996240f...c145068895e045cc725ee76fcd2307624b65c3af) Updates `crowdin/github-action` from 2.16.2 to 2.16.3 - [Release notes](https://github.com/crowdin/github-action/releases) - [Commits](https://github.com/crowdin/github-action/compare/8868a33591d21088edfc398968173a3b98d51706...52aa776766211d83d975df51f3b9c53c2f8ba35f) --- updated-dependencies: - dependency-name: oasdiff/oasdiff-action dependency-version: 0.1.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: CodSpeedHQ/action dependency-version: 4.17.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: crowdin/github-action dependency-version: 2.16.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * extend barcode scans API (#12233) * extend barcode scans with user perm check * fix import * fix call * align error message * add missing permissions to test * remove erronous assign * ensure permission erros knock through * New Crowdin translations by GitHub Action (#12192) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * [UI] Tweak today color (#12235) - Make "today" more obvious in calendar views * [UI] Tweak "order parts" wizard (#12236) - Order supplier parts by "primary" value - Attempt to auto-fill primary supplier part * [bug] Allocated query fix (#12234) * Fix BuildLineFilter.filter_allocated - Required for mysql backend * Spoecify output field * 1.5.0 (#12239) * Add release entry for 1.4.0 * Add blank entry for 1.5.0 * Bump version to 1.5.0 dev * [report] Tweak datamatrix helper (#12240) * [report] Tweak datamatrix helper - Add support for "rectangular" display - Support different image output formats * Fix unit tests * !feat(backend): bump minimum python version (#12223) * bump ci versions * bump installer version * bump tooling version ref * bump doc refs * bump / refactor code refs * bump debug ref * remove now unneeded deps * bump release version * remove distutils * fix finder call * remove old compat code * add changelog entry * lower cov target for now * Update devcontainer Dockerfile (#12244) - Update to python 3.14 - Fix base packages * Allow stock transfer to merge into existing stock (optional) #6951 (#12022) * working on merge transfer * fix history when merging * update messaging, add 'added' line in history * reworked history logic * removed old transfer logic * remove formatting changes from vite file * Bumped API version, added entry in docs for new global setting * removed the tracking item overwrite, Use existing tracking event from transfer * run pre-commit checks --------- Co-authored-by: Matthias Mair * New Crowdin translations by GitHub Action (#12238) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Revert devcontainer to python 3.12 (#12249) * Project code active (#12250) * Add 'active' field to the ProjectCode model - Allows retiring of old project codes without deleting * Update UI table * Refactor ProjectCodeField * Add unit test * Bump API version and CHANGELOG * fix js-yaml, esbuild vulns (#12190) * fix js-yaml, esbuild vulns * update bump * upgrade vite * Skip "many" fields in DataExport (#12255) - Exporting multi-dimensional datasets requires a custom exporter * [UI] Improve revision selector (#12254) - Display upstream revisions too * Bug fix for exception handler (#12257) * chore(backend): typing fixes (#12247) * bump ty * various fixes * fix settings * bump stubs * update pre-commit setup * update ignore * fix various issues * fix style * fix ignores * fix wrong ty warnings * ignore __class__ type checking errors see https://github.com/astral-sh/ty/issues/3122 * fix exception logging * update ignoring * bump ty further * add cleanup cmd * Merge branch 'master' of https://github.com/inventree/InvenTree into typechecking-remove-ignore * bump ty * remove now unused class ignores * chore(backend): harden gh setup (#12262) * pin plugin creator version * hard pin install script * chore(backend): dep bump (#12258) * general deps bump * cleanup other dep files * [UI] Stock column fix (#12268) * [UI] Fix StockColumn component * stock table rendering tweaks * chore(backend): Remove devops (#12265) * update sponsored ressources * remove az devops * update sponsored ressources (#12264) * [UI] Table tweaks (#12271) * [UI] Make part cell text copyable * Reduce text size * Reduce text size * [UI] Fix stock dates (#12272) * [UI] Fix stock dates - Display creation date - Display stocktake date * Switch to date type * fix: preserve supplier import stock workflow (#12215) Co-authored-by: Oliver * Fix dashboard issue (#12275) * chore(deps): bump the dependencies group with 5 updates (#12278) * chore(deps): bump the dependencies group with 5 updates Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `6.0.3` | `7.0.0` | | [oasdiff/oasdiff-action/diff](https://github.com/oasdiff/oasdiff-action) | `0.1.1` | `0.1.3` | | [CodSpeedHQ/action](https://github.com/codspeedhq/action) | `4.17.5` | `4.17.6` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.6` | `0.5.7` | | [pkgr/action/publish](https://github.com/pkgr/action) | `3bce081ae512c5020856e237d37b3f5479d4aa71` | `c5666febcd31750da6428042193fc5b2fb765435` | Updates `actions/checkout` from 6.0.3 to 7.0.0 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) Updates `oasdiff/oasdiff-action/diff` from 0.1.1 to 0.1.3 - [Release notes](https://github.com/oasdiff/oasdiff-action/releases) - [Commits](https://github.com/oasdiff/oasdiff-action/compare/5fbe96ede8d0c53aeadef122d7a0abb79152d493...ccc2442df0d99f8c419ed73e3de88641c91b3bc6) Updates `CodSpeedHQ/action` from 4.17.5 to 4.17.6 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/c145068895e045cc725ee76fcd2307624b65c3af...63f3e98b61959fe67f146a3ff022e4136fe9bb9c) Updates `zizmorcore/zizmor-action` from 0.5.6 to 0.5.7 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/5f14fd08f7cf1cb1609c1e344975f152c7ee938d...192e21d79ab29983730a13d1382995c2307fbcaa) Updates `pkgr/action/publish` from 3bce081ae512c5020856e237d37b3f5479d4aa71 to c5666febcd31750da6428042193fc5b2fb765435 - [Release notes](https://github.com/pkgr/action/releases) - [Commits](https://github.com/pkgr/action/compare/3bce081ae512c5020856e237d37b3f5479d4aa71...c5666febcd31750da6428042193fc5b2fb765435) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: oasdiff/oasdiff-action/diff dependency-version: 0.1.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: CodSpeedHQ/action dependency-version: 4.17.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: pkgr/action/publish dependency-version: c5666febcd31750da6428042193fc5b2fb765435 dependency-type: direct:production dependency-group: dependencies ... Signed-off-by: dependabot[bot] * Update checkout action version comment in workflow * fix pins * change pin * fix pin --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * [UI] Fix 'available' display (#12279) - Hide entirely for items not "in_stock" * Fix stocktake bug for counting serialized items (#12280) * Fix stocktake bug for counting serialized items * Add unit test * [UI] Table field refactor (#12274) * Use callback funcs * Don't use idx to identify rows * Add debug function for finding why a component re-rendered * Do not pass 'control' through to each row * Prevent unnecessary re-rendering of table rows * Adjust order of operations for hooks * Keep props hidden * Use lightweight NumberInput * Use NumberInput elsewhere * Add comment * use rowId instead of idx * Generic row memos * Compare errors too * Fix for BomItemSubstituteRow * Adjust more forms * memoize quantity * Memoize build lines * Fix re-rendering issues for build allocation * Fix for useConsumeBuildLinesForm * Fix for transfer order table * Fix useReceiveLineItems * Remove memoized pattern * Fix row keys * Cleanup * Create useStockItems hook for memoizing items * Refactoring * More refactoring * Remove obj reference - preventing shallow comparison from working * Add error message to useWhyDidYouUpdate * Cleanup * Cleanup dead code * Adjust modal width * Change attr name * Remove autoFillFilters prop * Adjustments for serialized stock * Fix typing * Bump frontend version * Adjustments for playwright testing * Fix ref issue * Remove debug entry * Update CHANGELOG.md * Reintroduce index to table header * Refactor common component * Fix for STOCK_COUNT event (#12281) * Fix for STOCK_COUNT event - Prevent double emission of event type string * adjust unit test * Allow stock adjustment from "category" detail view (#12256) * New Crowdin translations by GitHub Action (#12251) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * [UI] Tree select in form fields (#12217) * Add TreeField component * Add chevrons in dropdown menu * Custom node rendering * Add childIdentifier * Ensure full value gets displayed * Fix for search results * Refactor old renderers * Override field types * use definition filters * Better location validation messages * Tweaks * Fix unit test * Include icon * Fix playwright test * Fix call to onValueChange * Updated playwright tests * Use pathstring in selectedLabel (if available) * Mark structural nodes * Retain selected value when dropdown open * Add better placeholder values * Simplify field selection * Check build complete (#12289) * Display non-field errors in table field * Refactor validation for build output completion - Run validation BEFORE trying to complete (serializer validation) - Refactor and simplify common code * Adjust unit tests * Fix typing * Remove debug * Display login errors to user (#12288) * Improved error message extraction * Updated playwright test * Add playwright test for part image upload (#11597) * fix pin syntax (#12287) * fix pin syntax * make pins precise * update target name and version * [UI] Fix imports (#12292) - Adjust import structure - Prevent wall-of-text warnings from vite * [UI] Tweak unique keys (#12293) - Reduce reliance on mutable idx * chore(deps): bump the dependencies group across 1 directory with 27 updates (#12260) * chore(deps): bump the dependencies group across 1 directory with 27 updates Bumps the dependencies group with 27 updates in the /src/frontend directory: | Package | From | To | | --- | --- | --- | | [@codemirror/search](https://github.com/codemirror/search) | `6.7.0` | `6.7.1` | | [@fullcalendar/core](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/core) | `6.1.20` | `6.1.21` | | [@fullcalendar/daygrid](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/daygrid) | `6.1.20` | `6.1.21` | | [@fullcalendar/interaction](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/interaction) | `6.1.20` | `6.1.21` | | [@fullcalendar/react](https://github.com/fullcalendar/fullcalendar-react) | `6.1.20` | `6.1.21` | | [@mantine/carousel](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/carousel) | `9.2.1` | `9.3.2` | | [@mantine/charts](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/charts) | `9.2.1` | `9.3.2` | | [@mantine/core](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/core) | `9.2.1` | `9.3.2` | | [@mantine/dates](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dates) | `9.2.1` | `9.3.2` | | [@mantine/dropzone](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dropzone) | `9.2.1` | `9.3.2` | | [@mantine/form](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/form) | `9.2.1` | `9.3.2` | | [@mantine/hooks](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/hooks) | `9.2.1` | `9.3.2` | | [@mantine/modals](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/modals) | `9.2.1` | `9.3.2` | | [@mantine/notifications](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/notifications) | `9.2.1` | `9.3.2` | | [@mantine/spotlight](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/spotlight) | `9.2.1` | `9.3.2` | | [@mantine/vanilla-extract](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/vanilla-extract) | `9.2.1` | `9.3.2` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.57.0` | `10.58.0` | | [mantine-contextmenu](https://github.com/icflorescu/mantine-contextmenu) | `9.2.1` | `9.3.0` | | [mantine-datatable](https://github.com/icflorescu/mantine-datatable) | `9.2.2` | `9.3.0` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.78.0` | `7.79.0` | | [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.29.7` | `8.0.1` | | [@babel/preset-react](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react) | `7.29.7` | `8.0.1` | | [@babel/preset-typescript](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-typescript) | `7.29.7` | `8.0.1` | | [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) | `7.29.7` | `8.0.0` | | [@playwright/test](https://github.com/microsoft/playwright) | `1.60.0` | `1.61.0` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.9.2` | `25.9.3` | | [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `5.2.0` | `6.0.2` | Updates `@codemirror/search` from 6.7.0 to 6.7.1 - [Changelog](https://github.com/codemirror/search/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/search/commits) Updates `@fullcalendar/core` from 6.1.20 to 6.1.21 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/v6.1.21/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.21/packages/core) Updates `@fullcalendar/daygrid` from 6.1.20 to 6.1.21 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/v6.1.21/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.21/packages/daygrid) Updates `@fullcalendar/interaction` from 6.1.20 to 6.1.21 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/v6.1.21/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v6.1.21/packages/interaction) Updates `@fullcalendar/react` from 6.1.20 to 6.1.21 - [Release notes](https://github.com/fullcalendar/fullcalendar-react/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar-react/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar-react/compare/v6.1.20...v6.1.21) Updates `@mantine/carousel` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/carousel) Updates `@mantine/charts` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/charts) Updates `@mantine/core` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/core) Updates `@mantine/dates` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/dates) Updates `@mantine/dropzone` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/dropzone) Updates `@mantine/form` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/form) Updates `@mantine/hooks` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/hooks) Updates `@mantine/modals` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/modals) Updates `@mantine/notifications` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/notifications) Updates `@mantine/spotlight` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/spotlight) Updates `@mantine/vanilla-extract` from 9.2.1 to 9.3.2 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.3.2/packages/@mantine/vanilla-extract) Updates `@sentry/react` from 10.57.0 to 10.58.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.57.0...10.58.0) Updates `mantine-contextmenu` from 9.2.1 to 9.3.0 - [Changelog](https://github.com/icflorescu/mantine-contextmenu/blob/main/CHANGELOG.md) - [Commits](https://github.com/icflorescu/mantine-contextmenu/commits) Updates `mantine-datatable` from 9.2.2 to 9.3.0 - [Changelog](https://github.com/icflorescu/mantine-datatable/blob/main/CHANGELOG.md) - [Commits](https://github.com/icflorescu/mantine-datatable/commits) Updates `react-hook-form` from 7.78.0 to 7.79.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.78.0...v7.79.0) Updates `@babel/core` from 7.29.7 to 8.0.1 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v8.0.1/packages/babel-core) Updates `@babel/preset-react` from 7.29.7 to 8.0.1 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v8.0.1/packages/babel-preset-react) Updates `@babel/preset-typescript` from 7.29.7 to 8.0.1 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v8.0.1/packages/babel-preset-typescript) Updates `@babel/runtime` from 7.29.7 to 8.0.0 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v8.0.0/packages/babel-runtime) Updates `@playwright/test` from 1.60.0 to 1.61.0 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.60.0...v1.61.0) Updates `@types/node` from 25.9.2 to 25.9.3 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `@vitejs/plugin-react` from 5.2.0 to 6.0.2 - [Release notes](https://github.com/vitejs/vite-plugin-react/releases) - [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.2/packages/plugin-react) --- updated-dependencies: - dependency-name: "@codemirror/search" dependency-version: 6.7.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fullcalendar/core" dependency-version: 6.1.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fullcalendar/daygrid" dependency-version: 6.1.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fullcalendar/interaction" dependency-version: 6.1.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fullcalendar/react" dependency-version: 6.1.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/carousel" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/charts" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/core" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/dates" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/dropzone" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/form" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/hooks" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/modals" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/notifications" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/spotlight" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/vanilla-extract" dependency-version: 9.3.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@sentry/react" dependency-version: 10.58.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: mantine-contextmenu dependency-version: 9.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: mantine-datatable dependency-version: 9.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: react-hook-form dependency-version: 7.79.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@babel/core" dependency-version: 8.0.1 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@babel/preset-react" dependency-version: 8.0.1 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@babel/preset-typescript" dependency-version: 8.0.1 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@babel/runtime" dependency-version: 8.0.0 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@playwright/test" dependency-version: 1.61.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@types/node" dependency-version: 25.9.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@vitejs/plugin-react" dependency-version: 6.0.2 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies ... Signed-off-by: dependabot[bot] * lower @vitejs/plugin-react * fix matching * temp fix for the non-loading of plugin settings * remove loading badge for now * fix test * make test more precise * fix syntax * fix memo issues * remove wasLoaded hack --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * fix test assumption (#12296) * [API] Refactor API for duplicating objects (#12294) * Implement generic serializer for custom model duplication * Apply pattern to BuildOrder * Add more generic options * Bump API version * Adjust default option * Refactor existing implementations * Dynamic class typing * Add duplicate field to more model types - Company - ManufacturerPart - SupplierPart - SalesOrderShipment * Implement parameter duplication for more models: - Company - ManufacturerPart - SupplierPart * Simplify code * Refactor * [UI] Snippet editor (#12299) * Implement admin editor for report snippets * Report asset management * Add playwright test for report snippets * Add playwright test for "Report Assets" panel * Updated docs * [UI] Add "IPN" column to installed items table (#12297) * [docs] Report helper docs (#12300) * [docs] Report helper docs * Split out docs for assets and snippets * Updates * [db] Fix for UUID fields (#12301) * Fix OpenAPI multipart file fields to use binary format (#12298) * Fix OpenAPI multipart file fields to use binary format Fixes #11246 * Update API version * fix api version --------- Co-authored-by: Matthias Mair * reduce duplication (#12302) * [UI] Pricing override (#12306) * Correct display of pricing overrides * Add min/max override reference lines * Fix BarChart component * [feature] Consumable part (#12295) * Add "consumable" field to the Part model * Add frontend integration * Add badge * Add docs * Updated docs * Add API filtering for new field * Adjust API filters * Update backend logic * Adjust frontend * Additional unit tests * Update API version * update test * Add consumable icon --------- Co-authored-by: Matthias Mair * Order click-through on pricing panel (#12307) * Pricing bugs (#12305) * bug fix for get_price method - Remove unused argument moq - Allow case where 'multiples' = False * Error handling for convert_to * Error handling for PartPricing.save * Remove unused function * Revert function definition * coverage ignore * Add --keep option to setup-test task (#12308) Allow keeping existing data * Table refactor (#12309) * Refactor table components - Move underlying components into src/components/tables - Actual table implementation stay in src/tables * Fix vite warnings * chore(deps): bump python in /contrib/container (#12276) Bumps python from `44dd044` to `b877e50`. --- updated-dependencies: - dependency-name: python dependency-version: 3.14.6-slim-trixie dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the dependencies group across 1 directory with 31 updates (#12316) Bumps the dependencies group with 31 updates in the /src/frontend directory: | Package | From | To | | --- | --- | --- | | [@codemirror/language](https://github.com/codemirror/language) | `6.12.3` | `6.12.4` | | [@codemirror/state](https://github.com/codemirror/state) | `6.6.0` | `6.7.0` | | [@codemirror/view](https://github.com/codemirror/view) | `6.43.1` | `6.43.4` | | [@fortawesome/fontawesome-svg-core](https://github.com/FortAwesome/Font-Awesome) | `7.2.0` | `7.3.0` | | [@fortawesome/free-regular-svg-icons](https://github.com/FortAwesome/Font-Awesome) | `7.2.0` | `7.3.0` | | [@fortawesome/free-solid-svg-icons](https://github.com/FortAwesome/Font-Awesome) | `7.2.0` | `7.3.0` | | [@mantine/carousel](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/carousel) | `9.3.2` | `9.4.1` | | [@mantine/charts](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/charts) | `9.3.2` | `9.4.1` | | [@mantine/core](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/core) | `9.3.2` | `9.4.1` | | [@mantine/dates](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dates) | `9.3.2` | `9.4.1` | | [@mantine/dropzone](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dropzone) | `9.3.2` | `9.4.1` | | [@mantine/form](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/form) | `9.3.2` | `9.4.1` | | [@mantine/hooks](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/hooks) | `9.3.2` | `9.4.1` | | [@mantine/modals](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/modals) | `9.3.2` | `9.4.1` | | [@mantine/notifications](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/notifications) | `9.3.2` | `9.4.1` | | [@mantine/spotlight](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/spotlight) | `9.3.2` | `9.4.1` | | [@mantine/vanilla-extract](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/vanilla-extract) | `9.3.2` | `9.4.1` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.58.0` | `10.62.0` | | [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.101.0` | `5.101.2` | | [@vanilla-extract/css](https://github.com/vanilla-extract-css/vanilla-extract/tree/HEAD/packages/css) | `1.20.1` | `1.21.0` | | [mantine-contextmenu](https://github.com/icflorescu/mantine-contextmenu) | `9.3.0` | `9.3.1` | | [mantine-datatable](https://github.com/icflorescu/mantine-datatable) | `9.3.0` | `9.3.1` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.79.0` | `7.80.0` | | [recharts](https://github.com/recharts/recharts) | `3.8.1` | `3.9.0` | | [styled-components](https://github.com/styled-components/styled-components) | `6.4.2` | `6.4.3` | | [@flakiness/playwright](https://github.com/flakiness/playwright) | `1.15.0` | `1.16.0` | | [@playwright/test](https://github.com/microsoft/playwright) | `1.61.0` | `1.61.1` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.9.3` | `26.0.1` | | [@vanilla-extract/vite-plugin](https://github.com/vanilla-extract-css/vanilla-extract/tree/HEAD/packages/vite-plugin) | `5.2.2` | `5.2.3` | | [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `7.3.5` | `7.3.6` | | [vite-plugin-dts](https://github.com/qmhc/unplugin-dts/tree/HEAD/packages/vite-plugin-dts) | `5.0.2` | `5.0.3` | Updates `@codemirror/language` from 6.12.3 to 6.12.4 - [Changelog](https://github.com/codemirror/language/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/language/commits) Updates `@codemirror/state` from 6.6.0 to 6.7.0 - [Changelog](https://github.com/codemirror/state/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/state/commits) Updates `@codemirror/view` from 6.43.1 to 6.43.4 - [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/view/commits) Updates `@fortawesome/fontawesome-svg-core` from 7.2.0 to 7.3.0 - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/7.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/7.2.0...7.3.0) Updates `@fortawesome/free-regular-svg-icons` from 7.2.0 to 7.3.0 - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/7.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/7.2.0...7.3.0) Updates `@fortawesome/free-solid-svg-icons` from 7.2.0 to 7.3.0 - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/7.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/7.2.0...7.3.0) Updates `@mantine/carousel` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/carousel) Updates `@mantine/charts` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/charts) Updates `@mantine/core` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/core) Updates `@mantine/dates` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/dates) Updates `@mantine/dropzone` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/dropzone) Updates `@mantine/form` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/form) Updates `@mantine/hooks` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/hooks) Updates `@mantine/modals` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/modals) Updates `@mantine/notifications` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/notifications) Updates `@mantine/spotlight` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/spotlight) Updates `@mantine/vanilla-extract` from 9.3.2 to 9.4.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.4.1/packages/@mantine/vanilla-extract) Updates `@sentry/react` from 10.58.0 to 10.62.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.58.0...10.62.0) Updates `@tanstack/react-query` from 5.101.0 to 5.101.2 - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.2/packages/react-query) Updates `@vanilla-extract/css` from 1.20.1 to 1.21.0 - [Release notes](https://github.com/vanilla-extract-css/vanilla-extract/releases) - [Changelog](https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/css/CHANGELOG.md) - [Commits](https://github.com/vanilla-extract-css/vanilla-extract/commits/@vanilla-extract/css@1.21.0/packages/css) Updates `mantine-contextmenu` from 9.3.0 to 9.3.1 - [Changelog](https://github.com/icflorescu/mantine-contextmenu/blob/main/CHANGELOG.md) - [Commits](https://github.com/icflorescu/mantine-contextmenu/commits) Updates `mantine-datatable` from 9.3.0 to 9.3.1 - [Changelog](https://github.com/icflorescu/mantine-datatable/blob/main/CHANGELOG.md) - [Commits](https://github.com/icflorescu/mantine-datatable/commits) Updates `react-hook-form` from 7.79.0 to 7.80.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.79.0...v7.80.0) Updates `recharts` from 3.8.1 to 3.9.0 - [Release notes](https://github.com/recharts/recharts/releases) - [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md) - [Commits](https://github.com/recharts/recharts/compare/v3.8.1...v3.9.0) Updates `styled-components` from 6.4.2 to 6.4.3 - [Release notes](https://github.com/styled-components/styled-components/releases) - [Commits](https://github.com/styled-components/styled-components/compare/styled-components@6.4.2...styled-components@6.4.3) Updates `@flakiness/playwright` from 1.15.0 to 1.16.0 - [Release notes](https://github.com/flakiness/playwright/releases) - [Commits](https://github.com/flakiness/playwright/compare/v1.15.0...v1.16.0) Updates `@playwright/test` from 1.61.0 to 1.61.1 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.61.0...v1.61.1) Updates `@types/node` from 25.9.3 to 26.0.1 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `@vanilla-extract/vite-plugin` from 5.2.2 to 5.2.3 - [Release notes](https://github.com/vanilla-extract-css/vanilla-extract/releases) - [Changelog](https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/vite-plugin/CHANGELOG.md) - [Commits](https://github.com/vanilla-extract-css/vanilla-extract/commits/@vanilla-extract/vite-plugin@5.2.3/packages/vite-plugin) Updates `vite` from 7.3.5 to 7.3.6 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v7.3.6/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v7.3.6/packages/vite) Updates `vite-plugin-dts` from 5.0.2 to 5.0.3 - [Release notes](https://github.com/qmhc/unplugin-dts/releases) - [Changelog](https://github.com/qmhc/unplugin-dts/blob/main/packages/vite-plugin-dts/CHANGELOG.md) - [Commits](https://github.com/qmhc/unplugin-dts/commits/vite-plugin-dts@5.0.3/packages/vite-plugin-dts) --- updated-dependencies: - dependency-name: "@codemirror/language" dependency-version: 6.12.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@codemirror/state" dependency-version: 6.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@codemirror/view" dependency-version: 6.43.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fortawesome/fontawesome-svg-core" dependency-version: 7.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@fortawesome/free-regular-svg-icons" dependency-version: 7.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@fortawesome/free-solid-svg-icons" dependency-version: 7.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/carousel" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/charts" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/core" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/dates" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/dropzone" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/form" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/hooks" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/modals" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/notifications" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/spotlight" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/vanilla-extract" dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@sentry/react" dependency-version: 10.62.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@tanstack/react-query" dependency-version: 5.101.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@vanilla-extract/css" dependency-version: 1.21.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: mantine-contextmenu dependency-version: 9.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: mantine-datatable dependency-version: 9.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: react-hook-form dependency-version: 7.80.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: recharts dependency-version: 3.9.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: styled-components dependency-version: 6.4.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@flakiness/playwright" dependency-version: 1.16.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@playwright/test" dependency-version: 1.61.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@types/node" dependency-version: 26.0.1 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@vanilla-extract/vite-plugin" dependency-version: 5.2.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: vite dependency-version: 7.3.6 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: vite-plugin-dts dependency-version: 5.0.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * New Crowdin translations by GitHub Action (#12284) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * chore(deps): bump the dependencies group with 4 updates (#12312) Bumps the dependencies group with 4 updates: [actions/setup-python](https://github.com/actions/setup-python), [actions/cache](https://github.com/actions/cache), [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) and [CodSpeedHQ/action](https://github.com/codspeedhq/action). Updates `actions/setup-python` from 6.2.0 to 6.3.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...ece7cb06caefa5fff74198d8649806c4678c61a1) Updates `actions/cache` from 5.0.5 to 6.1.0 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9) Updates `stefanzweifel/git-auto-commit-action` from 7.1.0 to 7.2.0 - [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases) - [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/04702edda442b2e678b25b537cec683a1493fcb9...4a55954c782fc1ea30b9056cd3e7a2b40ca8887d) Updates `CodSpeedHQ/action` from 4.17.6 to 4.18.1 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/63f3e98b61959fe67f146a3ff022e4136fe9bb9c...a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: actions/cache dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: stefanzweifel/git-auto-commit-action dependency-version: 7.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: CodSpeedHQ/action dependency-version: 4.18.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [bug] Barcode bug fix (#12319) * [bug] Check for null line_item when receiving items * Additional unit testing * Additional context * Fix tests * Fix for stocktake exporter (#12324) * Robustify playwright tests (#12331) * Robustify playwright tests * More test tweaks * [UI] Add form submission shortcut (#12328) - Ctrl + enter submits the form * Fix currency choices for PartPricing model (#12336) * Fix currency choices for PartPricing model - Remove dynamic choices from model definition - Move validation step to the serializer - Add validator to ensure only valid currencies can be used * Add regression test * Bump API version * Fix notes on part creation (#12332) Co-authored-by: Oliver * [bug] Plugin load fix (#12329) * Update plugin name * Backup accessor for plugin name * Add null check for plg_db * Adjust default behavior of "migrate" command (#12320) * Adjust default behavior of "migrate" command - Does not create new migration files automatically * Add dummy field - ensure detected by CI * Revert "Add dummy field - ensure detected by CI" This reverts commit e7a101fe8798456c573bb6479c7f6b554a33eb78. * Fix typo * Adjust contributing docs * Add CHANGELOG entry * Import internal price (#12341) * Enable download from frontend panels * Enable data import for part internal pricing * Bump API version * Update CHANGELOG * [UI] Docs links (#12342) * Simplify navigation links * simplify version.py * Simplify docs links * Consolidate * [docs] Admin docs (#12345) * Enhanced documentation for admin center and django-admin * Fix links and wording * remove placeholders * Fix links * Fix more links * Currency options fix (#12343) - Ensure currency options are loaded dynamically * Add IPN column to BOM pricing panel (#12344) * [UI] Form fix (#12348) * Refactor API form fields - Prevent reconstruction of all fields when single value changes - Memoize components more intelligently - Fix enter key callback ref * memoize other field types too * More memo * Prevent duplicate API calls for related model field * Add aria-label for IconField * add playwright tests for form field coverage * [UI] Page Load Improvements (#12334) * Parallel initial requests * Remove debouncing * Refactor lazy loading of desktop / mobile view * Reduce initial waiting for loadable components * Fix duplication of API calls * Further reduce duplicate calls * Combine user roles into /user/me/ endpoint * lazy load global import drawer * lazy load table in plugin context * Patch ScanButton * Added playwright tests for login * Adjust thresholds * Bug fixes for PO receive (#12349) * Bug fixes for PO receive - Fix shadowed variable - Notify listeners for all received items * Cache part subs * Improved error context (#12350) - More useful error messaging if a task fails * Fix data import bug (#12355) - Fixes bug where imported data headers get out of sync - Additional unit tests * Remove dead pricing code on Part model (#12357) * [refactor] Refactor StockItem methods (#12358) * Refactor StockItem methods - Refactor out common functionality - Code cleanup * Cleanup * Prevent override of existing deltas * [feature] Break apart assemblies (#12310) * Implement API endpoint for stock disassembly * Add basic frontend implementation * Adjust required user permission * Add preFormContent * Read-only if serialized * Adjust location and status of each subcomponent * Handle null value * display installed items in frontend form * More unit tests * Traceability * Add docs * Exclude virtual / consumable stock * Additional docs * Added bundled items docs * More docs * more docs tweaks * Updated part docs * Add playwright tests * Robustify test * suppress certain warnings in schema * Adjust playwright tests * bug fix * Tweak playwright tests * [refactor] Bulk actions (#12359) * Add helper to bulk offload task * bulk offload events * Add unit test for bulk_offload_task * Add context wrapper for bulk event creation inside looped funcs * Add batching for stock tracking events * Context wrapper for capturing offloaded tasks * apply batching to other stock adjustment endpoints * Add benchmarking tests for other API endpoints * Benchmark test for serialize stock * Reduce commet verbosity * Apply benchmark to PO receive * Refactor benchmarking * PrefetchedPrimaryKeyRelatedField - Provides O(1) lookup for serializer validation - Significant improvements for large datasets * Adjust unit test code * Check for correct order of tracking operations * [UI] Preview Drawer (#12117) * Add component * Allow plugins to interact * provide either pk or instance data * open preview drawer from calendar views * Launch preview drawer directly from tables * Add preview types * Fix types * CLear data on close * Fix transition * Allow caller to pass preview component * AttributeGrid * Use a table component * Display info items * Navigate to detail page from drawer * Updates * Refactor to use part detail view * Display parameters * Fix image caching * Apply same to StockItem * Remove old component * Refactor details grid component * Preview panel for PurchaseOrder model * Implement for SalesOrder * Support ReturnOrder * SupplierPart and ManufacturerPart * Support preview in parameteric tables * support Company and BuildOrder * Fix numbervalue * BuildOrder and SalesOrderShipment * location and category * add user setting * Fix typing * Handle link clicks within preview drawer * fixes * Implement onClose callback * Handle row click when panel preview is disabled * Support custom detail links * update playwright tests * UI tweaks * Add CHANGELOG entry * docs * define default API params per model type * Split out more docs pages * Simplify state ref * Refactoring * Simplify PreviewDrawer component * observe user setting in calendar view * Enable PreviewDrawer from RowViewAction * Push render functions onto ModelInformation dict * Fix lib compilation * Refactor internal uses of RowViewAction * typescript fixes * Simplify PreviewDrawer component structure * remove TODO placeholders * [bug] prevent double-complete of shipments (#12366) * [bug] Transfer order fixes (#12367) * Handle failed transfer order transaction * Prevent duplicate completion of transfer order * Progressive falloff for delay (#12369) * Prevent duplicate receive operation on ReturnOrder (#12368) * [refactor] Remove MPTT mixin from StockItem model (#12360) * Remove MPTT from StockItem model * cleanup stock fixture file * Remove tree rebuild code for StockItem * Adjust API * Update CHANGELOG and API version * remove tree references * Additional checks * Remove unused tests * Add data migration test * fix fk fields * Cleanup * Tweak unit test * Revert bulk-create in unit test * Don't rebuild StockItem models * Add bulk_create_and_fetch helper model - Overcome limitations of mysql * Add unit test for new bulk-create helper * Apply new helper to codebase * Adjust unit test * bug fix * Adjust query limits * Remove assert * [bug] Child fix (#12374) * Remove outdated helper * Fix children prop and add regression test * Hardening build outputs (#12376) - ensure outputs cannot be double completed * fix concurrent update issues (#12380) - Ensure database values are used for delta updates - Regression tests * use new helper func (#12373) * Uninstall fix (#12378) * Prevent uninstall into structural location * Regression tests * [bug] Quantity fixes (#12375) - Ensure valid quantity values on stock operations - Regression testing * [refactor] SalesOrder allocation fixes (#12379) * Use API for unit test * Refactor SalesOrderSerialAllocationSerializer - Move business logic into the SalesOrder model * Add unit testing for serial allocation * Apply row-level locking when updating stock item quantity (#12385) * Prevent duplication completion of ReturnOrder (#12386) * Fix for BuildItem with zero quantity (#12387) * [feature] Unique parameters (#12388) * Add uniqueness requirement for parameter values * Add documentation * Do not copy unique parameters * Updated playwright tests * Enhanced validation checks for uniqueness * Update documentation * Update CHANGELOG * Bump API version * Bug fixes (#12365) * Bug fixes: - Enforce serial number requirements when receiving items - Stricter merge checking - Fix count-into-location bug - Unit testing * Additional unit tests * Fix StockItem parent update on delete (#12377) * Fix StockItem parent update on delete * Check for null parents * Add revision to SO and BO tables (#12398) * Add a Revision column renderer * Add Revision to SO and BO tables * Move Description column after IPN and Revision to be consistent with other tables * [bug] Tree parent fix (#12401) * Refactor * row locking on bulk-update * Rebuild tree in background task * Regression testing * Fix unit test * Allow more generous timeout * Bulk delete line items (#12391) * Add bulk-delete mixin for order line items * Add unit tests * Enable frontend support * Add CHANGELOG entry * Add locking control for TransferOrder * Fix playwright tests * Fix playwright tests * prevent duplicate save event when creating a part (#12406) * Bulk create events (#12405) * Add initial benchmark test * Enable event batching for BulkdCreate API mixin * Fix duplicate save event for Parameter * Apply event batching for bulk_update * Similar testing for bulk_delete * [UI] Display error information in boundary (#12403) * Display error information in boundary * Fix SecurityContext * New Crowdin translations by GitHub Action (#12318) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix docs reqs (#12407) * bump soupsieve * general deps bump * feat(ui): show variant stock indicator in parts table (#5959) (#12413) * Fix update notification deduplication and release link (#12424) * New Crowdin translations by GitHub Action (#12408) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fix creation date formatting on part detail page (#12423) Co-authored-by: Oliver * fix(ui): show initial stock fields when PART_CREATE_INITIAL enabled (#12415) * fix(ui): show initial stock fields when PART_CREATE_INITIAL enabled (#12266) * Fix Docker setup for local Windows deployment. Disable Redis disk persistence to avoid bind-mount permission errors that caused login 500s, and configure localhost as the default site URL. * Apply Biome formatting to Playwright test file. Fixes Style [prek] CI failure on PR #12415. * Use specific locators in initial stock Playwright tests. Avoid strict-mode violations from getByText('Initial Stock') matching multiple form elements. * Scope initial stock Playwright test to part detail Stock tab. Avoid strict-mode violations from duplicate Stock tabs on the part page. * Use raw SQL inserts in MPTT migration test setup. Avoid duplicate status_custom_key ORM bug in historical StockItem models. * [feature] Line discount (#12393) * Add "discount" support to order line items * Fix total_price annotation for ExtraLineItem * Add regression tests * Add frontend support * Updated documentation * Added docs * Bump API version and CHANGELOG * Remove 'total_price' annotation - Can be achieved using in-memory python methods * Apply fix for migration testing * Revert "Apply fix for migration testing" This reverts commit 8d9f2dce8cc4a150ffc614d0ace47c886ca43e06. * Different approach * Adjust playwright threshold * Improve request caching for plugin config objects (#12430) * Improve request caching for plugin config objects * Cache configs dict further * New Crowdin translations by GitHub Action (#12425) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * [bug] Bom table fix (#12436) * Fix logic for table context menu * Memoize handleCellContextMenu * Locking fixes (#12435) * Secure row locks when trimming allocated stock * Secure row locks when completing a SalesOrder * Regression testing * Further improvements and regression testing * Ignore locking test for sqlite * chore(deps): bump the dependencies group across 1 directory with 9 updates (#12428) Bumps the dependencies group with 9 updates in the / directory: | Package | From | To | | --- | --- | --- | | [dorny/paths-filter](https://github.com/dorny/paths-filter) | `4.0.1` | `4.0.2` | | [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `4.1.0` | `4.2.0` | | [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.1.0` | `4.2.0` | | [docker/login-action](https://github.com/docker/login-action) | `4.2.0` | `4.4.0` | | [docker/metadata-action](https://github.com/docker/metadata-action) | `6.1.0` | `6.2.0` | | [oasdiff/oasdiff-action/diff](https://github.com/oasdiff/oasdiff-action) | `3e9d440d37f468355457604348009f50e0cddbf3` | `024f6c399f9a21ada1addb0f9a36ce1bfac995f1` | | [CodSpeedHQ/action](https://github.com/codspeedhq/action) | `4.18.1` | `4.18.5` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.36.2` | `4.37.0` | | [actions/stale](https://github.com/actions/stale) | `10.3.0` | `10.4.0` | Updates `dorny/paths-filter` from 4.0.1 to 4.0.2 - [Release notes](https://github.com/dorny/paths-filter/releases) - [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) - [Commits](https://github.com/dorny/paths-filter/compare/fbd0ab8f3e69293af611ebaee6363fc25e6d187d...7b450fff21473bca461d4b92ce414b9d0420d706) Updates `docker/setup-qemu-action` from 4.1.0 to 4.2.0 - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/06116385d9baf250c9f4dcb4858b16962ea869c3...96fe6ef7f33517b61c61be40b68a1882f3264fb8) Updates `docker/setup-buildx-action` from 4.1.0 to 4.2.0 - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5...bb05f3f5519dd87d3ba754cc423b652a5edd6d2c) Updates `docker/login-action` from 4.2.0 to 4.4.0 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/650006c6eb7dba73a995cc03b0b2d7f5ca915bee...af1e73f918a031802d376d3c8bbc3fe56130a9b0) Updates `docker/metadata-action` from 6.1.0 to 6.2.0 - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9...dc802804100637a589fabce1cb79ff13a1411302) Updates `oasdiff/oasdiff-action/diff` from 3e9d440d37f468355457604348009f50e0cddbf3 to 024f6c399f9a21ada1addb0f9a36ce1bfac995f1 - [Release notes](https://github.com/oasdiff/oasdiff-action/releases) - [Commits](https://github.com/oasdiff/oasdiff-action/compare/3e9d440d37f468355457604348009f50e0cddbf3...024f6c399f9a21ada1addb0f9a36ce1bfac995f1) Updates `CodSpeedHQ/action` from 4.18.1 to 4.18.5 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f...f99becdce5e5d51fd556489ebef684f4ecfd6286) Updates `github/codeql-action/upload-sarif` from 4.36.2 to 4.37.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...99df26d4f13ea111d4ec1a7dddef6063f76b97e9) Updates `actions/stale` from 10.3.0 to 10.4.0 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899...1e223db275d687790206a7acac4d1a11bd6fe629) --- updated-dependencies: - dependency-name: dorny/paths-filter dependency-version: 4.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: docker/setup-qemu-action dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: docker/setup-buildx-action dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: docker/login-action dependency-version: 4.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: docker/metadata-action dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: oasdiff/oasdiff-action/diff dependency-version: 024f6c399f9a21ada1addb0f9a36ce1bfac995f1 dependency-type: direct:production dependency-group: dependencies - dependency-name: CodSpeedHQ/action dependency-version: 4.18.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: actions/stale dependency-version: 10.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Read report/label templates in binary mode (#12432) * Read report/label templates in binary mode file_from_template read the template in text mode and wrapped the string in a ContentFile. The ContentFile size then reflected the character count, which differs from the UTF-8 byte length for any template that contains multi-byte characters. Strict S3 implementations such as Backblaze B2 validate the Content-Length header and reject the upload with an IncompleteBody error. AWS S3 tolerates the mismatch, so the problem is not visible there. inventree_transfer_order_report.html is 1458 characters but 1460 bytes. Its upload fails during create_default_reports, the transaction rolls back, and the default template is recreated and fails again on every startup. Use Path.read_bytes() so the ContentFile size matches the uploaded bytes and the file handle is closed. Add a regression test asserting the size equals the file's byte length. * Test file_from_template across text encodings * chore(deps): bump brace-expansion from 5.0.6 to 5.0.7 in /src/frontend (#12439) Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 5.0.6 to 5.0.7. - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.6...v5.0.7) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 5.0.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump pillow from 12.2.0 to 12.3.0 in /src/backend (#12438) * chore(deps): bump pillow from 12.2.0 to 12.3.0 in /src/backend Bumps [pillow](https://github.com/python-pillow/Pillow) from 12.2.0 to 12.3.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/12.2.0...12.3.0) --- updated-dependencies: - dependency-name: pillow dependency-version: 12.3.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump the dependencies group across 2 directories with 22 updates (#12417) * chore(deps): bump the dependencies group across 2 directories with 22 updates Bumps the dependencies group with 1 update in the /docs directory: [mkdocstrings](https://github.com/mkdocstrings/mkdocstrings). Bumps the dependencies group with 21 updates in the /src/backend directory: | Package | From | To | | --- | --- | --- | | [blessed](https://github.com/jquast/blessed) | `1.44.0` | `1.47.0` | | [boto3](https://github.com/boto/boto3) | `1.43.36` | `1.43.45` | | [botocore](https://github.com/boto/botocore) | `1.43.36` | `1.43.45` | | [cffi](https://github.com/python-cffi/cffi) | `2.0.0` | `2.1.0` | | [charset-normalizer](https://github.com/jawah/charset_normalizer) | `3.4.7` | `3.4.9` | | [drf-spectacular](https://github.com/tfranzel/drf-spectacular) | `0.29.0` | `0.30.0` | | [dulwich](https://github.com/dulwich/dulwich) | `1.2.6` | `1.2.10` | | [fido2](https://github.com/Yubico/python-fido2) | `2.2.0` | `2.2.1` | | [grpcio](https://github.com/grpc/grpc) | `1.81.1` | `1.82.1` | | [jinxed](https://github.com/Rockhopper-Technologies/jinxed) | `2.0.4` | `2.1.0` | | [pillow](https://github.com/python-pillow/Pillow) | `12.2.0` | `12.3.0` | | [python-fsutil](https://github.com/fabiocaccamo/python-fsutil) | `0.16.1` | `0.17.0` | | [rpds-py](https://github.com/crate-py/rpds) | `2026.5.1` | `2026.6.3` | | [sentry-sdk](https://github.com/getsentry/sentry-python) | `2.63.0` | `2.64.0` | | [setuptools](https://github.com/pypa/setuptools) | `82.0.1` | `83.0.0` | | [tqdm](https://github.com/tqdm/tqdm) | `4.68.3` | `4.68.4` | | [typing-extensions](https://github.com/python/typing_extensions) | `4.15.0` | `4.16.0` | | [tzdata](https://github.com/python/tzdata) | `2026.2` | `2026.3` | | [wcwidth](https://github.com/jquast/wcwidth) | `0.8.1` | `0.8.2` | | [coverage](https://github.com/coveragepy/coveragepy) | `7.14.3` | `7.15.0` | | [prek](https://github.com/j178/prek) | `0.4.5` | `0.4.8` | Updates `mkdocstrings` from 1.0.4 to 1.0.5 - [Release notes](https://github.com/mkdocstrings/mkdocstrings/releases) - [Changelog](https://github.com/mkdocstrings/mkdocstrings/blob/main/CHANGELOG.md) - [Commits](https://github.com/mkdocstrings/mkdocstrings/compare/1.0.4...1.0.5) Updates `blessed` from 1.44.0 to 1.47.0 - [Release notes](https://github.com/jquast/blessed/releases) - [Changelog](https://github.com/jquast/blessed/blob/master/docs/history.rst) - [Commits](https://github.com/jquast/blessed/commits) Updates `boto3` from 1.43.36 to 1.43.45 - [Release notes](https://github.com/boto/boto3/releases) - [Commits](https://github.com/boto/boto3/compare/1.43.36...1.43.45) Updates `botocore` from 1.43.36 to 1.43.45 - [Commits](https://github.com/boto/botocore/compare/1.43.36...1.43.45) Updates `cffi` from 2.0.0 to 2.1.0 - [Release notes](https://github.com/python-cffi/cffi/releases) - [Commits](https://github.com/python-cffi/cffi/compare/v2.0.0...v2.1.0) Updates `charset-normalizer` from 3.4.7 to 3.4.9 - [Release notes](https://github.com/jawah/charset_normalizer/releases) - [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md) - [Commits](https://github.com/jawah/charset_normalizer/compare/3.4.7...3.4.9) Updates `drf-spectacular` from 0.29.0 to 0.30.0 - [Release notes](https://github.com/tfranzel/drf-spectacular/releases) - [Changelog](https://github.com/tfranzel/drf-spectacular/blob/master/CHANGELOG.rst) - [Commits](https://github.com/tfranzel/drf-spectacular/compare/0.29.0...0.30.0) Updates `dulwich` from 1.2.6 to 1.2.10 - [Release notes](https://github.com/dulwich/dulwich/releases) - [Changelog](https://github.com/jelmer/dulwich/blob/main/NEWS) - [Commits](https://github.com/dulwich/dulwich/compare/dulwich-1.2.6...dulwich-1.2.10) Updates `fido2` from 2.2.0 to 2.2.1 - [Release notes](https://github.com/Yubico/python-fido2/releases) - [Changelog](https://github.com/Yubico/python-fido2/blob/main/NEWS) - [Commits](https://github.com/Yubico/python-fido2/compare/2.2.0...2.2.1) Updates `grpcio` from 1.81.1 to 1.82.1 - [Release notes](https://github.com/grpc/grpc/releases) - [Commits](https://github.com/grpc/grpc/compare/v1.81.1...v1.82.1) Updates `jinxed` from 2.0.4 to 2.1.0 - [Release notes](https://github.com/Rockhopper-Technologies/jinxed/releases) - [Commits](https://github.com/Rockhopper-Technologies/jinxed/compare/2.0.4...2.1.0) Updates `pillow` from 12.2.0 to 12.3.0 - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/12.2.0...12.3.0) Updates `python-fsutil` from 0.16.1 to 0.17.0 - [Release notes](https://github.com/fabiocaccamo/python-fsutil/releases) - [Changelog](https://github.com/fabiocaccamo/python-fsutil/blob/main/CHANGELOG.md) - [Commits](https://github.com/fabiocaccamo/python-fsutil/compare/0.16.1...0.17.0) Updates `rpds-py` from 2026.5.1 to 2026.6.3 - [Release notes](https://github.com/crate-py/rpds/releases) - [Changelog](https://github.com/crate-py/rpds/blob/main/release.toml) - [Commits](https://github.com/crate-py/rpds/compare/v2026.5.1...v2026.6.3) Updates `sentry-sdk` from 2.63.0 to 2.64.0 - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.63.0...2.64.0) Updates `setuptools` from 82.0.1 to 83.0.0 - [Release notes](https://github.com/pypa/setuptools/releases) - [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/setuptools/compare/v82.0.1...v83.0.0) Updates `tqdm` from 4.68.3 to 4.68.4 - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.68.3...v4.68.4) Updates `typing-extensions` from 4.15.0 to 4.16.0 - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.15.0...4.16.0) Updates `tzdata` from 2026.2 to 2026.3 - [Release notes](https://github.com/python/tzdata/releases) - [Changelog](https://github.com/python/tzdata/blob/master/NEWS.md) - [Commits](https://github.com/python/tzdata/compare/2026.2...2026.3) Updates `wcwidth` from 0.8.1 to 0.8.2 - [Release notes](https://github.com/jquast/wcwidth/releases) - [Commits](https://github.com/jquast/wcwidth/compare/0.8.1...0.8.2) Updates `coverage` from 7.14.3 to 7.15.0 - [Release notes](https://github.com/coveragepy/coveragepy/releases) - [Changelog](https://github.com/coveragepy/coveragepy/blob/main/CHANGES.rst) - [Commits](https://github.com/coveragepy/coveragepy/compare/7.14.3...7.15.0) Updates `prek` from 0.4.5 to 0.4.8 - [Release notes](https://github.com/j178/prek/releases) - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md) - [Commits](https://github.com/j178/prek/compare/v0.4.5...v0.4.8) --- updated-dependencies: - dependency-name: mkdocstrings dependency-version: 1.0.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: blessed dependency-version: 1.47.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: boto3 dependency-version: 1.43.45 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: botocore dependency-version: 1.43.45 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: cffi dependency-version: 2.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: charset-normalizer dependency-version: 3.4.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: drf-spectacular dependency-version: 0.30.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: dulwich dependency-version: 1.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: fido2 dependency-version: 2.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: grpcio dependency-version: 1.82.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: jinxed dependency-version: 2.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: pillow dependency-version: 12.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: python-fsutil dependency-version: 0.17.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: rpds-py dependency-version: 2026.6.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: sentry-sdk dependency-version: 2.64.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: setuptools dependency-version: 83.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: tqdm dependency-version: 4.68.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: typing-extensions dependency-version: 4.16.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: tzdata dependency-version: '2026.3' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: wcwidth dependency-version: 0.8.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: coverage dependency-version: 7.15.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: prek dependency-version: 0.4.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix style * lower drf-spectacular to remove api diff --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair Co-authored-by: Oliver * Fix typo in terminology.md (#12452) Corrected the spelling of 'shelf life' in the IMS section. * Fix admin search for Address and Contact models (#12440) * chore(deps): bump dompurify from 3.4.11 to 3.4.12 in /src/frontend (#12448) Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.11 to 3.4.12. - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.4.11...3.4.12) --- updated-dependencies: - dependency-name: dompurify dependency-version: 3.4.12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * general deps bump (#12409) * chore(deps): bump the dependencies group across 1 directory with 13 updates Bumps the dependencies group with 13 updates in the /src/backend directory: | Package | From | To | | --- | --- | --- | | [coverage](https://github.com/coveragepy/coveragepy) | `7.14.3` | `7.15.0` | | [prek](https://github.com/j178/prek) | `0.4.5` | `0.4.6` | | [typing-extensions](https://github.com/python/typing_extensions) | `4.15.0` | `4.16.0` | | [blessed](https://github.com/jquast/blessed) | `1.44.0` | `1.45.0` | | [boto3](https://github.com/boto/boto3) | `1.43.36` | `1.43.40` | | [botocore](https://github.com/boto/botocore) | `1.43.36` | `1.43.40` | | [dulwich](https://github.com/dulwich/dulwich) | `1.2.6` | `1.2.7` | | [fido2](https://github.com/Yubico/python-fido2) | `2.2.0` | `2.2.1` | | [jinxed](https://github.com/Rockhopper-Technologies/jinxed) | `2.0.4` | `2.1.0` | | [pillow](https://github.com/python-pillow/Pillow) | `12.2.0` | `12.3.0` | | [rpds-py](https://github.com/crate-py/rpds) | `2026.5.1` | `2026.6.3` | | [sentry-sdk](https://github.com/getsentry/sentry-python) | `2.63.0` | `2.64.0` | | [wcwidth](https://github.com/jquast/wcwidth) | `0.8.1` | `0.8.2` | Updates `coverage` from 7.14.3 to 7.15.0 - [Release notes](https://github.com/coveragepy/coveragepy/releases) - [Changelog](https://github.com/coveragepy/coveragepy/blob/main/CHANGES.rst) - [Commits](https://github.com/coveragepy/coveragepy/compare/7.14.3...7.15.0) Updates `prek` from 0.4.5 to 0.4.6 - [Release notes](https://github.com/j178/prek/releases) - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md) - [Commits](https://github.com/j178/prek/compare/v0.4.5...v0.4.6) Updates `typing-extensions` from 4.15.0 to 4.16.0 - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.15.0...4.16.0) Updates `blessed` from 1.44.0 to 1.45.0 - [Release notes](https://github.com/jquast/blessed/releases) - [Changelog](https://github.com/jquast/blessed/blob/master/docs/history.rst) - [Commits](https://github.com/jquast/blessed/commits) Updates `boto3` from 1.43.36 to 1.43.40 - [Release notes](https://github.com/boto/boto3/releases) - [Commits](https://github.com/boto/boto3/compare/1.43.36...1.43.40) Updates `botocore` from 1.43.36 to 1.43.40 - [Commits](https://github.com/boto/botocore/compare/1.43.36...1.43.40) Updates `dulwich` from 1.2.6 to 1.2.7 - [Release notes](https://github.com/dulwich/dulwich/releases) - [Changelog](https://github.com/jelmer/dulwich/blob/main/NEWS) - [Commits](https://github.com/dulwich/dulwich/compare/dulwich-1.2.6...dulwich-1.2.7) Updates `fido2` from 2.2.0 to 2.2.1 - [Release notes](https://github.com/Yubico/python-fido2/releases) - [Changelog](https://github.com/Yubico/python-fido2/blob/main/NEWS) - [Commits](https://github.com/Yubico/python-fido2/compare/2.2.0...2.2.1) Updates `jinxed` from 2.0.4 to 2.1.0 - [Release notes](https://github.com/Rockhopper-Technologies/jinxed/releases) - [Commits](https://github.com/Rockhopper-Technologies/jinxed/compare/2.0.4...2.1.0) Updates `pillow` from 12.2.0 to 12.3.0 - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/12.2.0...12.3.0) Updates `rpds-py` from 2026.5.1 to 2026.6.3 - [Release notes](https://github.com/crate-py/rpds/releases) - [Changelog](https://github.com/crate-py/rpds/blob/main/release.toml) - [Commits](https://github.com/crate-py/rpds/compare/v2026.5.1...v2026.6.3) Updates `sentry-sdk` from 2.63.0 to 2.64.0 - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/2.63.0...2.64.0) Updates `wcwidth` from 0.8.1 to 0.8.2 - [Release notes](https://github.com/jquast/wcwidth/releases) - [Commits](https://github.com/jquast/wcwidth/compare/0.8.1...0.8.2) --- updated-dependencies: - dependency-name: coverage dependency-version: 7.15.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: prek dependency-version: 0.4.6 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: typing-extensions dependency-version: 4.16.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: blessed dependency-version: 1.45.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: boto3 dependency-version: 1.43.40 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: botocore dependency-version: 1.43.40 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: dulwich dependency-version: 1.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: fido2 dependency-version: 2.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: jinxed dependency-version: 2.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: pillow dependency-version: 12.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: rpds-py dependency-version: 2026.6.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: sentry-sdk dependency-version: 2.64.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: wcwidth dependency-version: 0.8.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix style * master bump * api bump * bump a bit further --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Improvements to `PrintingOptionsSerializer` (#12434) * Fixed issue with default `driver_options on `InvenTreeLabelPlugin` * Provide current `machine` to `LabelPrinterBaseDriver.get_printing_options_serializer` * [docs] Report discovery (#12449) * Adds decorator to mark an attribute for report context discovery * Update context variables in docs * Include fields captured against each model type * Expose more properties * Image URL tags * Add more attributes * Rearrange docs * Simplify docs * Enforce type hinting for reportable properties * Expose more properties for the Order model * Auto-discover related / linked models * Remove extra text * Collapsible blocks * Reduce boilerplate * Remove cruft * Enhance documentation for filename generation * Cleanup * [bug] BOM checksum fix (#12455) * Enforce ordering of BOM items * Add prefetch to getRequiredParts * Add regression test * [refactor] Complete shipment API endpoint (#12363) * Use API for unit test * Loop unrolling is super effective * Additional unit testing * Fix for bulk_create - use bulk_create_and_fetch * Fix unit tests * Fix unit tests * Adjust unit test * Revert return type on helper func * Evaluate returned QuerySet * Adjust unit tests * Adjust complete_allocations * Fix for bulk_create in unit test * Reimplement complete_allocation for compatibility --------- Co-authored-by: Matthias Mair * [bug] Attachment str fix (#12461) * Fix stringify for Attachment model * Add regression tests * Bug fix for exporting SalesOrderAllocation data (#12463) * Bug fix for exporting SalesOrderAllocation data * Regression test * Bump API version * Bug fix for unit test * chore(backend): major allauth bump (#12454) * mayjor allauth bump * add PR link * [refactor] Build allocation endpoints (#12361) * Create benchmark for completing a build and consuming all items * Refactor build consume task * Add benchmarking * Unroll allocate-stock serializer * Complete build only after allocations are consumed * re-export batch_events * Add BulkPrefetchSerializerMixin * Reduce queries even further * Refactoring * Unroll code and use bulk operations * Refactoring for auto-allocation * Add more test coverage for auto-allocation * Fix model_reference_fields * adjust unit test * Apply concurrency protection * Additional unit tests * Remove per-line validation * Fix unit test * Adjust unit test * Use bulk_create_and_fetch * Cleanup * Reimplement wrapper func for backwards compatibility * Fix unit test * Increase max query time * Fix serializer * Enforce pk ordering * FIx for mysql * chore(deps): bump the dependencies group across 1 directory with 2 updates (#12465) * chore(deps): bump the dependencies group across 1 directory with 2 updates Bumps the dependencies group with 2 updates in the /docs directory: [mkdocs-material](https://github.com/squidfunk/mkdocs-material) and [mkdocstrings](https://github.com/mkdocstrings/mkdocstrings). Updates `mkdocs-material` from 9.7.6 to 9.7.7 - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.7.6...9.7.7) Updates `mkdocstrings` from 1.0.5 to 1.0.6 - [Release notes](https://github.com/mkdocstrings/mkdocstrings/releases) - [Changelog](https://github.com/mkdocstrings/mkdocstrings/blob/main/CHANGELOG.md) - [Commits](https://github.com/mkdocstrings/mkdocstrings/compare/1.0.5...1.0.6) --- updated-dependencies: - dependency-name: mkdocs-material dependency-version: 9.7.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: mkdocstrings dependency-version: 1.0.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix style * update pin --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump the dependencies group across 1 directory with 17 updates (#12427) * chore(deps): bump the dependencies group across 1 directory with 17 updates Bumps the dependencies group with 17 updates in the /src/frontend directory: | Package | From | To | | --- | --- | --- | | [@codemirror/view](https://github.com/codemirror/view) | `6.43.4` | `6.43.6` | | [@fortawesome/react-fontawesome](https://github.com/FortAwesome/react-fontawesome) | `3.3.1` | `3.4.0` | | [@fullcalendar/core](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/core-types) | `6.1.21` | `7.0.0` | | [@fullcalendar/react](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/react) | `6.1.21` | `7.0.0` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.62.0` | `10.65.0` | | [@uiw/codemirror-theme-vscode](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` | | [@uiw/react-codemirror](https://github.com/uiwjs/react-codemirror) | `4.25.10` | `4.25.11` | | [@vanilla-extract/css](https://github.com/vanilla-extract-css/vanilla-extract/tree/HEAD/packages/css) | `1.21.0` | `1.21.1` | | [dompurify](https://github.com/cure53/DOMPurify) | `3.4.11` | `3.4.12` | | [fuse.js](https://github.com/krisk/Fuse) | `7.4.2` | `7.5.0` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.80.0` | `7.81.0` | | [recharts](https://github.com/recharts/recharts) | `3.9.0` | `3.9.2` | | [undici](https://github.com/nodejs/undici) | `8.5.0` | `8.7.0` | | [@flakiness/playwright](https://github.com/flakiness/playwright) | `1.16.0` | `1.18.0` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `26.0.1` | `26.1.1` | | [@vanilla-extract/vite-plugin](https://github.com/vanilla-extract-css/vanilla-extract/tree/HEAD/packages/vite-plugin) | `5.2.3` | `5.2.4` | | [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `7.0.2` | Updates `@codemirror/view` from 6.43.4 to 6.43.6 - [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/view/commits) Updates `@fortawesome/react-fontawesome` from 3.3.1 to 3.4.0 - [Release notes](https://github.com/FortAwesome/react-fontawesome/releases) - [Changelog](https://github.com/FortAwesome/react-fontawesome/blob/main/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/react-fontawesome/compare/v3.3.1...v3.4.0) Updates `@fullcalendar/core` from 6.1.21 to 7.0.0 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v7.0.0/packages/core-types) Updates `@fullcalendar/react` from 6.1.21 to 7.0.0 - [Release notes](https://github.com/fullcalendar/fullcalendar/releases) - [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md) - [Commits](https://github.com/fullcalendar/fullcalendar/commits/v7.0.0/packages/react) Updates `@sentry/react` from 10.62.0 to 10.65.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.62.0...10.65.0) Updates `@uiw/codemirror-theme-vscode` from 4.25.10 to 4.25.11 - [Release notes](https://github.com/uiwjs/react-codemirror/releases) - [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11) Updates `@uiw/react-codemirror` from 4.25.10 to 4.25.11 - [Release notes](https://github.com/uiwjs/react-codemirror/releases) - [Commits](https://github.com/uiwjs/react-codemirror/compare/v4.25.10...v4.25.11) Updates `@vanilla-extract/css` from 1.21.0 to 1.21.1 - [Release notes](https://github.com/vanilla-extract-css/vanilla-extract/releases) - [Changelog](https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/css/CHANGELOG.md) - [Commits](https://github.com/vanilla-extract-css/vanilla-extract/commits/@vanilla-extract/css@1.21.1/packages/css) Updates `dompurify` from 3.4.11 to 3.4.12 - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.4.11...3.4.12) Updates `fuse.js` from 7.4.2 to 7.5.0 - [Release notes](https://github.com/krisk/Fuse/releases) - [Changelog](https://github.com/krisk/Fuse/blob/main/CHANGELOG.md) - [Commits](https://github.com/krisk/Fuse/compare/v7.4.2...v7.5.0) Updates `react-hook-form` from 7.80.0 to 7.81.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.80.0...v7.81.0) Updates `recharts` from 3.9.0 to 3.9.2 - [Release notes](https://github.com/recharts/recharts/releases) - [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md) - [Commits](https://github.com/recharts/recharts/compare/v3.9.0...v3.9.2) Updates `undici` from 8.5.0 to 8.7.0 - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v8.5.0...v8.7.0) Updates `@flakiness/playwright` from 1.16.0 to 1.18.0 - [Release notes](https://github.com/flakiness/playwright/releases) - [Commits](https://github.com/flakiness/playwright/compare/v1.16.0...v1.18.0) Updates `@types/node` from 26.0.1 to 26.1.1 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `@vanilla-extract/vite-plugin` from 5.2.3 to 5.2.4 - [Release notes](https://github.com/vanilla-extract-css/vanilla-extract/releases) - [Changelog](https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/vite-plugin/CHANGELOG.md) - [Commits](https://github.com/vanilla-extract-css/vanilla-extract/commits/@vanilla-extract/vite-plugin@5.2.4/packages/vite-plugin) Updates `typescript` from 5.9.3 to 7.0.2 - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Commits](https://github.com/microsoft/TypeScript/commits) --- updated-dependencies: - dependency-name: "@codemirror/view" dependency-version: 6.43.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fortawesome/react-fontawesome" dependency-version: 3.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@fullcalendar/core" dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@fullcalendar/react" dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@sentry/react" dependency-version: 10.65.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@uiw/codemirror-theme-vscode" dependency-version: 4.25.11 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@uiw/react-codemirror" dependency-version: 4.25.11 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@vanilla-extract/css" dependency-version: 1.21.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: dompurify dependency-version: 3.4.12 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: fuse.js dependency-version: 7.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: react-hook-form dependency-version: 7.81.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: recharts dependency-version: 3.9.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: undici dependency-version: 8.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@flakiness/playwright" dependency-version: 1.18.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@types/node" dependency-version: 26.1.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@vanilla-extract/vite-plugin" dependency-version: 5.2.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: typescript dependency-version: 7.0.2 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix tsconfig * fix setup for build - lower typescript * fix resolution * lower fullcalendar --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump gitpython from 3.1.52 to 3.1.54 in /docs (#12467) * chore(deps): bump gitpython from 3.1.52 to 3.1.54 in /docs Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.52 to 3.1.54. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.52...3.1.54) --- updated-dependencies: - dependency-name: gitpython dependency-version: 3.1.54 dependency-type: indirect ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * Add order sorting for sales order allocation tables (#12468) * Fix part SalesOrder table (#12469) * Fix part SalesOrder table - Show line item quantity, not number of lines * add regression test * Bump API version * Fix Redis write failures on Windows Docker bind mounts (#12418) * Fix Docker setup for local Windows deployment. Disable Redis disk persistence to avoid bind-mount permission errors that caused login 500s, and configure localhost as the default site URL. * Fix Redis write failures on Windows Docker bind mounts. Disable RDB persistence for the cache container so login and other cache writes do not fail when the Redis data volume cannot be written on Windows hosts. * Keep Redis volume mount while disabling disk persistence. Addresses review feedback on #12418: retain the external /data volume from #11100 but disable RDB/AOF writes so Windows bind mounts no longer trigger MISCONF errors. * Offfload email notification (#12470) * Offfload email notification * Run email sync in testing * Add configurable default for PO line item merging (#12472) * Add configurable default for PO line item merging Introduce PURCHASEORDER_MERGE_LINE_ITEMS global setting to control the default state of the merge_items option when creating purchase order lines. Fixes #10947 * Apply ruff and biome formatting for CI * On order filter (#12476) * Add "on order" filter for Part model - Added API filter - Added table filter - Added table column * Bump API version * Add table sorting * Adjust API text * [UI] Add search result preview (#12475) * [UI] Add search result preview * Updated search docs * [UI] Display all error table field error messages (#12456) * Display all error table field error messages * Adjust playwright test * Refactor sales order methods: (#12477) - Cancel sales order - Assign serial numbers * chore(deps): bump python in /contrib/container (#12479) Bumps python from `b877e50` to `cea0e60`. --- updated-dependencies: - dependency-name: python dependency-version: 3.14.6-slim-trixie dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(backend): registry install command (#11657) * Unable to install plugins through web UI using custom registry and/or Python wheel files. Fixes #11460 * use more fitting variable name * add typing * clean up logic flow - make easier to understand * make check easier to understand * reduce complexity * ensure user is tested * add more tests * add user validation * move test * disable uninstall in test * Update test_api.py * style fix * fix typing * check if pip exsists * fix gate * fix typo * reference pip instead * make test more tolerant * revert permission check change * remove new test --------- Co-authored-by: Oliver * chore(deps): bump the dependencies group with 7 updates (#12480) * chore(deps): bump the dependencies group with 7 updates Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `7.0.0` | `7.0.1` | | [actions/setup-python](https://github.com/actions/setup-python) | `6.3.0` | `7.0.0` | | [j178/prek-action](https://github.com/j178/prek-action) | `2.0.5` | `2.0.6` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.7` | `0.6.0` | | [actions/attest](https://github.com/actions/attest) | `4.1.1` | `4.2.0` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.0` | `4.37.1` | | [crowdin/github-action](https://github.com/crowdin/github-action) | `2.16.3` | `2.16.4` | Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1) Updates `actions/setup-python` from 6.3.0 to 7.0.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/ece7cb06caefa5fff74198d8649806c4678c61a1...5fda3b95a4ea91299a34e894583c3862153e4b97) Updates `j178/prek-action` from 2.0.5 to 2.0.6 - [Release notes](https://github.com/j178/prek-action/releases) - [Commits](https://github.com/j178/prek-action/compare/e98a699c41eb69ab013a45817a0406469a748f8d...5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16) Updates `zizmorcore/zizmor-action` from 0.5.7 to 0.6.0 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/192e21d79ab29983730a13d1382995c2307fbcaa...6599ee8b7a49aef6a770f63d261d214911a7ce02) Updates `actions/attest` from 4.1.1 to 4.2.0 - [Release notes](https://github.com/actions/attest/releases) - [Changelog](https://github.com/actions/attest/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest/compare/a1948c3f048ba23858d222213b7c278aabede763...f7c74d28b9d84cb8768d0b8ca14a4bac6ef463e6) Updates `github/codeql-action/upload-sarif` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a) Updates `crowdin/github-action` from 2.16.3 to 2.16.4 - [Release notes](https://github.com/crowdin/github-action/releases) - [Commits](https://github.com/crowdin/github-action/compare/52aa776766211d83d975df51f3b9c53c2f8ba35f...e0c8f73cdc0fafde9396e056c5038217000a32d1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: actions/setup-python dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: j178/prek-action dependency-version: 2.0.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: zizmorcore/zizmor-action dependency-version: 0.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: actions/attest dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: crowdin/github-action dependency-version: 2.16.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix pin --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump postcss from 8.5.15 to 8.5.23 in /src/frontend (#12466) Bumps [postcss](https://github.com/postcss/postcss) from 8.5.15 to 8.5.23. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.5.15...8.5.23) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump the dependencies group across 1 directory with 14 updates (#12485) Bumps the dependencies group with 14 updates in the /src/frontend directory: | Package | From | To | | --- | --- | --- | | [@fortawesome/fontawesome-svg-core](https://github.com/FortAwesome/Font-Awesome) | `7.3.0` | `7.3.1` | | [@fortawesome/free-regular-svg-icons](https://github.com/FortAwesome/Font-Awesome) | `7.3.0` | `7.3.1` | | [@fortawesome/free-solid-svg-icons](https://github.com/FortAwesome/Font-Awesome) | `7.3.0` | `7.3.1` | | [@fortawesome/react-fontawesome](https://github.com/FortAwesome/react-fontawesome) | `3.4.0` | `3.5.0` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.65.0` | `10.67.0` | | [@tabler/icons-react](https://github.com/tabler/tabler-icons/tree/HEAD/packages/icons-react) | `3.44.0` | `3.45.0` | | [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.101.2` | `5.101.3` | | [mantine-contextmenu](https://github.com/icflorescu/mantine-contextmenu) | `9.3.1` | `9.4.0` | | [mantine-datatable](https://github.com/icflorescu/mantine-datatable) | `9.3.1` | `9.4.0` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.81.0` | `7.82.0` | | [recharts](https://github.com/recharts/recharts) | `3.9.2` | `3.10.0` | | [styled-components](https://github.com/styled-components/styled-components) | `6.4.3` | `6.4.4` | | [undici](https://github.com/nodejs/undici) | `8.7.0` | `8.8.0` | | [@vanilla-extract/vite-plugin](https://github.com/vanilla-extract-css/vanilla-extract/tree/HEAD/packages/vite-plugin) | `5.2.4` | `5.2.5` | Updates `@fortawesome/fontawesome-svg-core` from 7.3.0 to 7.3.1 - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/7.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/7.3.0...7.3.1) Updates `@fortawesome/free-regular-svg-icons` from 7.3.0 to 7.3.1 - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/7.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/7.3.0...7.3.1) Updates `@fortawesome/free-solid-svg-icons` from 7.3.0 to 7.3.1 - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/7.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/7.3.0...7.3.1) Updates `@fortawesome/react-fontawesome` from 3.4.0 to 3.5.0 - [Release notes](https://github.com/FortAwesome/react-fontawesome/releases) - [Changelog](https://github.com/FortAwesome/react-fontawesome/blob/main/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/react-fontawesome/compare/v3.4.0...v3.5.0) Updates `@sentry/react` from 10.65.0 to 10.67.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.65.0...10.67.0) Updates `@tabler/icons-react` from 3.44.0 to 3.45.0 - [Release notes](https://github.com/tabler/tabler-icons/releases) - [Commits](https://github.com/tabler/tabler-icons/commits/v3.45.0/packages/icons-react) Updates `@tanstack/react-query` from 5.101.2 to 5.101.3 - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.3/packages/react-query) Updates `mantine-contextmenu` from 9.3.1 to 9.4.0 - [Changelog](https://github.com/icflorescu/mantine-contextmenu/blob/main/CHANGELOG.md) - [Commits](https://github.com/icflorescu/mantine-contextmenu/commits) Updates `mantine-datatable` from 9.3.1 to 9.4.0 - [Changelog](https://github.com/icflorescu/mantine-datatable/blob/main/CHANGELOG.md) - [Commits](https://github.com/icflorescu/mantine-datatable/commits) Updates `react-hook-form` from 7.81.0 to 7.82.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.81.0...v7.82.0) Updates `recharts` from 3.9.2 to 3.10.0 - [Release notes](https://github.com/recharts/recharts/releases) - [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md) - [Commits](https://github.com/recharts/recharts/compare/v3.9.2...v3.10.0) Updates `styled-components` from 6.4.3 to 6.4.4 - [Release notes](https://github.com/styled-components/styled-components/releases) - [Commits](https://github.com/styled-components/styled-components/compare/styled-components@6.4.3...styled-components@6.4.4) Updates `undici` from 8.7.0 to 8.8.0 - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v8.7.0...v8.8.0) Updates `@vanilla-extract/vite-plugin` from 5.2.4 to 5.2.5 - [Release notes](https://github.com/vanilla-extract-css/vanilla-extract/releases) - [Changelog](https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/vite-plugin/CHANGELOG.md) - [Commits](https://github.com/vanilla-extract-css/vanilla-extract/commits/@vanilla-extract/vite-plugin@5.2.5/packages/vite-plugin) --- updated-dependencies: - dependency-name: "@fortawesome/fontawesome-svg-core" dependency-version: 7.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fortawesome/free-regular-svg-icons" dependency-version: 7.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fortawesome/free-solid-svg-icons" dependency-version: 7.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@fortawesome/react-fontawesome" dependency-version: 3.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@sentry/react" dependency-version: 10.67.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@tabler/icons-react" dependency-version: 3.45.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@tanstack/react-query" dependency-version: 5.101.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: mantine-contextmenu dependency-version: 9.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: mantine-datatable dependency-version: 9.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: react-hook-form dependency-version: 7.82.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: recharts dependency-version: 3.10.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: styled-components dependency-version: 6.4.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: undici dependency-version: 8.8.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@vanilla-extract/vite-plugin" dependency-version: 5.2.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [bug] Fix concurrency issues for allocation (#12478) * Fix concurrency issues for allocation * Remove duplicate atomic call * Reduce query count * [bug] Unique constraint for serial numbers (#12483) * Unique constraint for serial numbers * Revert unrelated changes * Updated tests * Build output serial number docs (#12486) * Remove serial number restriction when creating build outputs * Updated docs * additional docs * [API] Refactor stock adjustment endpoints (#12488) * Filtering for report snippets (#12487) * Filtering for report snippets * Bump API version * Token save fix (#12491) - Only update 'last_seen' field * Improve validation for import session (#12492) - Ensure that validated data is a dict shape * Concurrency fix for scheduled tasks (#12493) - Prevent multiple instances of scheduled tasks from plugins * remove errant test report (#12496) * Adjust demo-dataset for CI (#12500) * New Crowdin translations by GitHub Action (#12437) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fix admin search for PurchaseOrderLineItem (#12508) Expand search_fields on PurchaseOrderLineItemAdmin to allow searching by part name, part description, supplier SKU, order reference, and supplier name. Previously, only the optional 'reference' field was searchable, making it impossible to find line items by part or order details. - part__part__name: search by underlying Part name - part__part__description: search by Part description - part__SKU: search by Supplier SKU - order__reference: search by Purchase Order reference - order__supplier__name: search by Supplier name Also adds a unit test to verify the search_fields are correctly configured. * Fix for data import "update" (#12513) - Use partial update on serializer - Mark other fields as not required (pk only) * Handle report error on missing svg data (#12514) * Handle report error on missing svg data * Add regression tests * Row locking for data import / update (#12515) - Concurrency protection for data imports * Fix for TreeFieldComponent (#12519) - Prevent deselect by clicking on same entry - Updated playwright tests * Robustify playwright test (#12522) * [UI] Keep Add Parts button visible in Parametric View (#12392) * [UI] Keep Add Parts button visible in Parametric View * [UI] Add PartCreationMenu component for shared part creation actions * [UI] Fix unused imports and import ordering in PartTable and ParametricDataTable * [UI] Fix ambiguous text locator in parametric view test * [UI] Fix import formatting in PartTable --------- Co-authored-by: Hana Co-authored-by: Oliver * New Crowdin translations by GitHub Action (#12512) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Demo ci check (#12530) * Remove branch checking in workflow files * Detect demo branch based on software version * Fix typo * Fix for N+1 issues in stock item serializing (#12534) * chore(deps): bump the dependencies group across 1 directory with 9 updates (#12526) * chore(deps): bump the dependencies group across 1 directory with 9 updates Bumps the dependencies group with 9 updates in the /src/backend directory: | Package | From | To | | --- | --- | --- | | [boto3](https://github.com/boto/boto3) | `1.43.53` | `1.43.55` | | [botocore](https://github.com/boto/botocore) | `1.43.53` | `1.43.55` | | [django-oauth-toolkit](https://github.com/django-oauth/django-oauth-toolkit) | `3.3.0` | `3.4.0` | | [grpcio](https://github.com/grpc/grpc) | `1.82.1` | `1.83.0` | | [s3transfer](https://github.com/boto/s3transfer) | `0.19.1` | `0.19.2` | | [tqdm](https://github.com/tqdm/tqdm) | `4.69.0` | `4.69.1` | | [prek](https://github.com/j178/prek) | `0.4.10` | `0.4.11` | | [types-psycopg2](https://github.com/python/typeshed) | `2.9.21.20260712` | `2.9.21.20260724` | | [types-pyyaml](https://github.com/python/typeshed) | `6.0.12.20260518` | `6.0.12.20260724` | Updates `boto3` from 1.43.53 to 1.43.55 - [Release notes](https://github.com/boto/boto3/releases) - [Commits](https://github.com/boto/boto3/compare/1.43.53...1.43.55) Updates `botocore` from 1.43.53 to 1.43.55 - [Commits](https://github.com/boto/botocore/compare/1.43.53...1.43.55) Updates `django-oauth-toolkit` from 3.3.0 to 3.4.0 - [Release notes](https://github.com/django-oauth/django-oauth-toolkit/releases) - [Changelog](https://github.com/django-oauth/django-oauth-toolkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/django-oauth/django-oauth-toolkit/compare/3.3.0...3.4.0) Updates `grpcio` from 1.82.1 to 1.83.0 - [Release notes](https://github.com/grpc/grpc/releases) - [Commits](https://github.com/grpc/grpc/compare/v1.82.1...v1.83.0) Updates `s3transfer` from 0.19.1 to 0.19.2 - [Changelog](https://github.com/boto/s3transfer/blob/develop/CHANGELOG.rst) - [Commits](https://github.com/boto/s3transfer/compare/0.19.1...0.19.2) Updates `tqdm` from 4.69.0 to 4.69.1 - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.69.0...v4.69.1) Updates `prek` from 0.4.10 to 0.4.11 - [Release notes](https://github.com/j178/prek/releases) - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md) - [Commits](https://github.com/j178/prek/compare/v0.4.10...v0.4.11) Updates `types-psycopg2` from 2.9.21.20260712 to 2.9.21.20260724 - [Commits](https://github.com/python/typeshed/commits) Updates `types-pyyaml` from 6.0.12.20260518 to 6.0.12.20260724 - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: boto3 dependency-version: 1.43.55 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: botocore dependency-version: 1.43.55 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: django-oauth-toolkit dependency-version: 3.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: grpcio dependency-version: 1.83.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: s3transfer dependency-version: 0.19.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: tqdm dependency-version: 4.69.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: prek dependency-version: 0.4.11 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: types-psycopg2 dependency-version: 2.9.21.20260724 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: types-pyyaml dependency-version: 6.0.12.20260724 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * [API] Optional field permissions (#12529) * Add permissions check for OptionalField * Adjust existing unit tests * Add caching * Additional tests * Additional testing * Add exclusions for owner and group models * Bump CHANGELOG * Detect demo branch based on software version * Updated docstrings * chore(deps): bump undici from 8.8.0 to 8.9.0 in /src/frontend (#12543) Bumps [undici](https://github.com/nodejs/undici) from 8.8.0 to 8.9.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v8.8.0...v8.9.0) --- updated-dependencies: - dependency-name: undici dependency-version: 8.9.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump gitpython from 3.1.54 to 3.1.57 in /docs (#12545) * chore(deps): bump gitpython from 3.1.54 to 3.1.57 in /docs Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.54 to 3.1.57. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.54...3.1.57) --- updated-dependencies: - dependency-name: gitpython dependency-version: 3.1.57 dependency-type: indirect ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump the dependencies group across 1 directory with 23 updates (#12547) Bumps the dependencies group with 23 updates in the /src/frontend directory: | Package | From | To | | --- | --- | --- | | [@codemirror/view](https://github.com/codemirror/view) | `6.43.6` | `6.43.7` | | [@mantine/carousel](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/carousel) | `9.4.1` | `9.5.0` | | [@mantine/charts](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/charts) | `9.4.1` | `9.5.0` | | [@mantine/core](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/core) | `9.4.1` | `9.5.0` | | [@mantine/dates](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dates) | `9.4.1` | `9.5.0` | | [@mantine/dropzone](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dropzone) | `9.4.1` | `9.5.0` | | [@mantine/form](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/form) | `9.4.1` | `9.5.0` | | [@mantine/hooks](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/hooks) | `9.4.1` | `9.5.0` | | [@mantine/modals](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/modals) | `9.4.1` | `9.5.0` | | [@mantine/notifications](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/notifications) | `9.4.1` | `9.5.0` | | [@mantine/spotlight](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/spotlight) | `9.4.1` | `9.5.0` | | [@mantine/vanilla-extract](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/vanilla-extract) | `9.4.1` | `9.5.0` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.67.0` | `10.68.0` | | [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.101.3` | `5.101.4` | | [@vanilla-extract/css](https://github.com/vanilla-extract-css/vanilla-extract/tree/HEAD/packages/css) | `1.21.1` | `1.21.2` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.82.0` | `7.83.0` | | [react-is](https://github.com/react/react/tree/HEAD/packages/react-is) | `19.2.7` | `19.2.8` | | [recharts](https://github.com/recharts/recharts) | `3.10.0` | `3.10.1` | | [@flakiness/playwright](https://github.com/flakiness/playwright) | `1.18.0` | `2.0.0` | | [@playwright/test](https://github.com/microsoft/playwright) | `1.61.1` | `1.62.0` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `26.1.1` | `26.1.2` | | [@vanilla-extract/vite-plugin](https://github.com/vanilla-extract-css/vanilla-extract/tree/HEAD/packages/vite-plugin) | `5.2.5` | `5.2.6` | | [rollup](https://github.com/rollup/rollup) | `4.62.2` | `4.62.3` | Updates `@codemirror/view` from 6.43.6 to 6.43.7 - [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/view/commits) Updates `@mantine/carousel` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/carousel) Updates `@mantine/charts` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/charts) Updates `@mantine/core` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/core) Updates `@mantine/dates` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/dates) Updates `@mantine/dropzone` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/dropzone) Updates `@mantine/form` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/form) Updates `@mantine/hooks` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/hooks) Updates `@mantine/modals` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/modals) Updates `@mantine/notifications` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/notifications) Updates `@mantine/spotlight` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/spotlight) Updates `@mantine/vanilla-extract` from 9.4.1 to 9.5.0 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.0/packages/@mantine/vanilla-extract) Updates `@sentry/react` from 10.67.0 to 10.68.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/10.68.0/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.67.0...10.68.0) Updates `@tanstack/react-query` from 5.101.3 to 5.101.4 - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.4/packages/react-query) Updates `@vanilla-extract/css` from 1.21.1 to 1.21.2 - [Release notes](https://github.com/vanilla-extract-css/vanilla-extract/releases) - [Changelog](https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/css/CHANGELOG.md) - [Commits](https://github.com/vanilla-extract-css/vanilla-extract/commits/@vanilla-extract/css@1.21.2/packages/css) Updates `react-hook-form` from 7.82.0 to 7.83.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.82.0...v7.83.0) Updates `react-is` from 19.2.7 to 19.2.8 - [Release notes](https://github.com/react/react/releases) - [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/react/react/commits/v19.2.8/packages/react-is) Updates `recharts` from 3.10.0 to 3.10.1 - [Release notes](https://github.com/recharts/recharts/releases) - [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md) - [Commits](https://github.com/recharts/recharts/compare/v3.10.0...v3.10.1) Updates `@flakiness/playwright` from 1.18.0 to 2.0.0 - [Release notes](https://github.com/flakiness/playwright/releases) - [Commits](https://github.com/flakiness/playwright/compare/v1.18.0...v2.0.0) Updates `@playwright/test` from 1.61.1 to 1.62.0 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.61.1...v1.62.0) Updates `@types/node` from 26.1.1 to 26.1.2 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `@vanilla-extract/vite-plugin` from 5.2.5 to 5.2.6 - [Release notes](https://github.com/vanilla-extract-css/vanilla-extract/releases) - [Changelog](https://github.com/vanilla-extract-css/vanilla-extract/blob/master/packages/vite-plugin/CHANGELOG.md) - [Commits](https://github.com/vanilla-extract-css/vanilla-extract/commits/@vanilla-extract/vite-plugin@5.2.6/packages/vite-plugin) Updates `rollup` from 4.62.2 to 4.62.3 - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.62.2...v4.62.3) --- updated-dependencies: - dependency-name: "@codemirror/view" dependency-version: 6.43.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/carousel" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/charts" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/core" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/dates" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/dropzone" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/form" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/hooks" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/modals" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/notifications" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/spotlight" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@mantine/vanilla-extract" dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@sentry/react" dependency-version: 10.68.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@tanstack/react-query" dependency-version: 5.101.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@vanilla-extract/css" dependency-version: 1.21.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: react-hook-form dependency-version: 7.83.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: react-is dependency-version: 19.2.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: recharts dependency-version: 3.10.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@flakiness/playwright" dependency-version: 2.0.0 dependency-type: direct:development update-type: version-update:semver-major dependency-group: dependencies - dependency-name: "@playwright/test" dependency-version: 1.62.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@types/node" dependency-version: 26.1.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@vanilla-extract/vite-plugin" dependency-version: 5.2.6 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: rollup dependency-version: 4.62.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump undici from 6.27.0 to 8.10.0 in /src/frontend (#12544) Bumps [undici](https://github.com/nodejs/undici) from 6.27.0 to 8.10.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.27.0...v8.10.0) --- updated-dependencies: - dependency-name: undici dependency-version: 8.10.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the dependencies group with 7 updates (#12541) * chore(deps): bump the dependencies group with 7 updates Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | [docker/login-action](https://github.com/docker/login-action) | `4.4.0` | `4.5.2` | | [oasdiff/oasdiff-action/diff](https://github.com/oasdiff/oasdiff-action) | `0.1.6` | `0.1.10` | | [CodSpeedHQ/action](https://github.com/codspeedhq/action) | `4.18.5` | `4.19.1` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.6.0` | `0.6.1` | | [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.3` | `2.4.4` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.1` | `4.37.3` | | [actions/stale](https://github.com/actions/stale) | `10.4.0` | `11.0.0` | Updates `docker/login-action` from 4.4.0 to 4.5.2 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/af1e73f918a031802d376d3c8bbc3fe56130a9b0...371161bbe7024a29a25c5e19bfcbc0804fe9ad2c) Updates `oasdiff/oasdiff-action/diff` from 0.1.6 to 0.1.10 - [Release notes](https://github.com/oasdiff/oasdiff-action/releases) - [Commits](https://github.com/oasdiff/oasdiff-action/compare/024f6c399f9a21ada1addb0f9a36ce1bfac995f1...0ab8ad204b00d25acc5ae87106281433e288d0c1) Updates `CodSpeedHQ/action` from 4.18.5 to 4.19.1 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/f99becdce5e5d51fd556489ebef684f4ecfd6286...f22792bfac16f3e14eb9fbea76f4a48e9cc22b93) Updates `zizmorcore/zizmor-action` from 0.6.0 to 0.6.1 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/6599ee8b7a49aef6a770f63d261d214911a7ce02...6fc4b006235f201fdab3722e17240ab420d580e5) Updates `ossf/scorecard-action` from 2.4.3 to 2.4.4 - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/4eaacf0543bb3f2c246792bd56e8cdeffafb205a...2d1146689b8cda280b9bc96326124645441f03bc) Updates `github/codeql-action/upload-sarif` from 4.37.1 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) Updates `actions/stale` from 10.4.0 to 11.0.0 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/1e223db275d687790206a7acac4d1a11bd6fe629...4391f3da665fdf50b6810c1a66712fb9ba21aa93) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.5.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: oasdiff/oasdiff-action/diff dependency-version: 0.1.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: CodSpeedHQ/action dependency-version: 4.19.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: zizmorcore/zizmor-action dependency-version: 0.6.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: ossf/scorecard-action dependency-version: 2.4.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: actions/stale dependency-version: 11.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies ... Signed-off-by: dependabot[bot] * Update qc_checks.yaml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump cryptography from 49.0.0 to 50.0.0 in /src/backend (#12546) * chore(deps): bump cryptography from 49.0.0 to 50.0.0 in /src/backend Bumps [cryptography](https://github.com/pyca/cryptography) from 49.0.0 to 50.0.0. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/49.0.0...50.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-version: 50.0.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * Fix permissions for group and RuleSet endpoints (#12563) - Require StaffRole in addition to is_staff * Handle missing part (#12566) Part instance may have already been deleted in post_delete hook for related models. * Deduplicate part pricing updates per session (#12564) * Barcode API bugs (#12565) * Add explicit permission checks for barcode scanning - Previous role_required attribute did not do anything * Additional unit tests * [API] Handle AppRegistryNotReady (#12571) Explicit handling for AppRegistryNotReady error * [refactor] Improve efficiency of check_missing_pricing (#12572) * [bug] excel encoding for data import (#12576) - Handle different encoding types for excel import - Fail cleanly if cannot read file * [bug] Fix post-delete actions (#12575) - Check that underlying part is still available * [bug] Fix getLogoImage helper (#12577) * [bug] Fix getLogoImage helper - Do not return a file:// URI * cleanup code * [bug] Fix part duplicate checks (#12574) * [bug] Fix part duplicate checks * Additional unit tests * Fix flaky test on sqlite (#12582) * [sentry] Do not report MethodNotAllowed (#12584) * [bug] Handle deleted Part (#12578) * [API] Restrict barcode scan history (#12569) - A non-staff user can only view their own results * [bug] Validate location when completing build outputs (#12570) * [bug] Validate location when completing build outputs - Cannot be structural * Fix unit test --------- Co-authored-by: Matthias Mair * [bug] Fix PartStocktakeSerializer (#12587) Closes https://github.com/inventree/InvenTree/issues/12555 * [docs] Improve setup guide for non-standard hosting (#12588) * [docs] Updated docs for complex server setups Ref: https://github.com/inventree/InvenTree/discussions/12538 * Add FAQ entry * [docker] Include pip license file (#12583) * [docker] Include pip license file This file has been missing in production builds * Add CI test * Update contrib/container/Dockerfile Co-authored-by: Matthias Mair * Fix typo * path fix * More pathing fixes --------- Co-authored-by: Matthias Mair * [bug] Fix for plugin fetching (#12590) - Prevent operation on stale plugin * Data import fix (#12568) * Specify JSON encoder for data import fields - Fixes encoding issues when importing from XLSX file * Add regression test * Fix faulty error handler * Fix for unit test * Fix test result ordering by test timestamps (#12533) * Fix test result ordering by test timestamps * Refractor test result comparison helper * Apply formatting fixes * Fix frontend formatting * Avoid mutating test result records * Add migration for test result ordering * Retry documentation build --------- Co-authored-by: jayasree723 Co-authored-by: Oliver * Fix Install Stock Items shows only selected parts (#12596) * Bug Fix Install Stock Item showing variant stock when BOM disallows variants * Add regression test for include_variants stock filter --------- Co-authored-by: Siddhartha Ravilla * [UI] Bulk Delete Enhancements (#12601) * Add optional filtering for bulkDelete * Enhanced pre-form content * chore(deps): bump gitpython from 3.1.57 to 3.1.58 in /docs (#12593) * chore(deps): bump gitpython from 3.1.57 to 3.1.58 in /docs Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.57 to 3.1.58. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.57...3.1.58) --- updated-dependencies: - dependency-name: gitpython dependency-version: 3.1.58 dependency-type: indirect ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * chore(deps): bump pypdf from 6.14.2 to 6.15.0 in /src/backend (#12594) * chore(deps): bump pypdf from 6.14.2 to 6.15.0 in /src/backend Bumps [pypdf](https://github.com/py-pdf/pypdf) from 6.14.2 to 6.15.0. - [Release notes](https://github.com/py-pdf/pypdf/releases) - [Changelog](https://github.com/py-pdf/pypdf/blob/main/CHANGELOG.md) - [Commits](https://github.com/py-pdf/pypdf/compare/6.14.2...6.15.0) --- updated-dependencies: - dependency-name: pypdf dependency-version: 6.15.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * [security] Additional SSRF protections (#12595) Tighten SSRF protections when fetching from external URLs * feat(backend): add throtteling by default (#11951) * feat(backend): add throtteling by default * add changelog entry * ignore throtetling in debug mode * increase threshold * chore(deps): bump the dependencies group across 1 directory with 10 updates (#12561) * chore(deps): bump the dependencies group across 1 directory with 10 updates Bumps the dependencies group with 10 updates in the /src/backend directory: | Package | From | To | | --- | --- | --- | | [boto3](https://github.com/boto/boto3) | `1.43.55` | `1.43.61` | | [botocore](https://github.com/boto/botocore) | `1.43.55` | `1.43.61` | | [django-anymail](https://github.com/anymail/django-anymail) | `15.0` | `15.1` | | [feedparser](https://github.com/kurtmckee/feedparser) | `6.0.12` | `6.0.14` | | [markdown](https://github.com/Python-Markdown/markdown) | `3.10.2` | `3.10.3` | | [redis](https://github.com/redis/redis-py) | `8.0.1` | `8.1.0` | | [tablib](https://github.com/jazzband/tablib) | `3.9.0` | `3.10.0` | | [tqdm](https://github.com/tqdm/tqdm) | `4.69.1` | `4.70.0` | | [wrapt](https://github.com/GrahamDumpleton/wrapt) | `2.2.2` | `2.3.0` | | [pip](https://github.com/pypa/pip) | `26.1.2` | `26.2` | Updates `boto3` from 1.43.55 to 1.43.61 - [Release notes](https://github.com/boto/boto3/releases) - [Commits](https://github.com/boto/boto3/compare/1.43.55...1.43.61) Updates `botocore` from 1.43.55 to 1.43.61 - [Commits](https://github.com/boto/botocore/compare/1.43.55...1.43.61) Updates `django-anymail` from 15.0 to 15.1 - [Release notes](https://github.com/anymail/django-anymail/releases) - [Changelog](https://github.com/anymail/django-anymail/blob/main/CHANGELOG.rst) - [Commits](https://github.com/anymail/django-anymail/compare/v15.0...v15.1) Updates `feedparser` from 6.0.12 to 6.0.14 - [Release notes](https://github.com/kurtmckee/feedparser/releases) - [Changelog](https://github.com/kurtmckee/feedparser/blob/main/CHANGELOG.rst) - [Commits](https://github.com/kurtmckee/feedparser/compare/v6.0.12...v6.0.14) Updates `markdown` from 3.10.2 to 3.10.3 - [Release notes](https://github.com/Python-Markdown/markdown/releases) - [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md) - [Commits](https://github.com/Python-Markdown/markdown/compare/3.10.2...3.10.3) Updates `redis` from 8.0.1 to 8.1.0 - [Release notes](https://github.com/redis/redis-py/releases) - [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES) - [Commits](https://github.com/redis/redis-py/compare/v8.0.1...v8.1.0) Updates `tablib` from 3.9.0 to 3.10.0 - [Release notes](https://github.com/jazzband/tablib/releases) - [Changelog](https://github.com/jazzband/tablib/blob/master/HISTORY.md) - [Commits](https://github.com/jazzband/tablib/compare/v3.9.0...v3.10.0) Updates `tqdm` from 4.69.1 to 4.70.0 - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.69.1...v4.70.0) Updates `wrapt` from 2.2.2 to 2.3.0 - [Release notes](https://github.com/GrahamDumpleton/wrapt/releases) - [Changelog](https://github.com/GrahamDumpleton/wrapt/blob/develop/docs/changes.rst) - [Commits](https://github.com/GrahamDumpleton/wrapt/compare/2.2.2...2.3.0) Updates `pip` from 26.1.2 to 26.2 - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/26.1.2...26.2) --- updated-dependencies: - dependency-name: boto3 dependency-version: 1.43.61 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: botocore dependency-version: 1.43.61 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: django-anymail dependency-version: '15.1' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: feedparser dependency-version: 6.0.14 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: markdown dependency-version: 3.10.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: redis dependency-version: 8.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: tablib dependency-version: 3.10.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: tqdm dependency-version: 4.70.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: wrapt dependency-version: 2.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: pip dependency-version: '26.2' dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * Bump version number to 1.6.0-rev (#12603) * Bump version number to 1.6.0-rev * Add release date * Add next version entry * Fix for API exception_handler (#12604) - Only log unhandled exceptions to sentry.io - Check for valid handling first - Report second * chore(deps): bump dompurify from 3.4.12 to 3.4.13 in /src/frontend (#12592) Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.12 to 3.4.13. - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.4.12...3.4.13) --- updated-dependencies: - dependency-name: dompurify dependency-version: 3.4.13 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Oliver * chore(deps): bump the dependencies group with 7 updates (#12608) Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | [docker/login-action](https://github.com/docker/login-action) | `4.5.2` | `4.6.0` | | [j178/prek-action](https://github.com/j178/prek-action) | `2.0.6` | `3.0.0` | | [tcort/github-action-markdown-link-check](https://github.com/tcort/github-action-markdown-link-check) | `1.1.2` | `1.1.3` | | [CodSpeedHQ/action](https://github.com/codspeedhq/action) | `4.19.1` | `5.0.2` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.6.1` | `0.6.2` | | [actions/attest](https://github.com/actions/attest) | `4.2.0` | `4.2.1` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.3` | `4.37.5` | Updates `docker/login-action` from 4.5.2 to 4.6.0 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/371161bbe7024a29a25c5e19bfcbc0804fe9ad2c...dbcb813823bdd20940b903addbd779551569679f) Updates `j178/prek-action` from 2.0.6 to 3.0.0 - [Release notes](https://github.com/j178/prek-action/releases) - [Commits](https://github.com/j178/prek-action/compare/5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16...4e14d07f9231acabce116ccfca13b13dd9755ece) Updates `tcort/github-action-markdown-link-check` from 1.1.2 to 1.1.3 - [Release notes](https://github.com/tcort/github-action-markdown-link-check/releases) - [Changelog](https://github.com/tcort/github-action-markdown-link-check/blob/master/CHANGELOG.md) - [Commits](https://github.com/tcort/github-action-markdown-link-check/compare/e7c7a18363c842693fadde5d41a3bd3573a7a225...e047c5b37f24ab722bbef1a27b6fab7f96bc4068) Updates `CodSpeedHQ/action` from 4.19.1 to 5.0.2 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/f22792bfac16f3e14eb9fbea76f4a48e9cc22b93...0ca9cbbf4623b599a6c3ed4fc8a922942705d9f1) Updates `zizmorcore/zizmor-action` from 0.6.1 to 0.6.2 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/6fc4b006235f201fdab3722e17240ab420d580e5...3dc1ecc9bcb9e94e9b2c709687979e1298497054) Updates `actions/attest` from 4.2.0 to 4.2.1 - [Release notes](https://github.com/actions/attest/releases) - [Changelog](https://github.com/actions/attest/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest/compare/f7c74d28b9d84cb8768d0b8ca14a4bac6ef463e6...508db95dd578ae2727ebd6217d5ba78e4fbda05d) Updates `github/codeql-action/upload-sarif` from 4.37.3 to 4.37.5 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...d1ba80a13dd99fba24a470575428917156a28b43) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: j178/prek-action dependency-version: 3.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: tcort/github-action-markdown-link-check dependency-version: 1.1.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: CodSpeedHQ/action dependency-version: 5.0.2 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dependencies - dependency-name: zizmorcore/zizmor-action dependency-version: 0.6.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: actions/attest dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the dependencies group across 1 directory with 18 updates (#12609) Bumps the dependencies group with 18 updates in the /src/frontend directory: | Package | From | To | | --- | --- | --- | | [@mantine/carousel](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/carousel) | `9.5.0` | `9.5.1` | | [@mantine/charts](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/charts) | `9.5.0` | `9.5.1` | | [@mantine/core](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/core) | `9.5.0` | `9.5.1` | | [@mantine/dates](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dates) | `9.5.0` | `9.5.1` | | [@mantine/dropzone](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/dropzone) | `9.5.0` | `9.5.1` | | [@mantine/form](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/form) | `9.5.0` | `9.5.1` | | [@mantine/hooks](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/hooks) | `9.5.0` | `9.5.1` | | [@mantine/modals](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/modals) | `9.5.0` | `9.5.1` | | [@mantine/notifications](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/notifications) | `9.5.0` | `9.5.1` | | [@mantine/spotlight](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/spotlight) | `9.5.0` | `9.5.1` | | [@mantine/vanilla-extract](https://github.com/mantinedev/mantine/tree/HEAD/packages/@mantine/vanilla-extract) | `9.5.0` | `9.5.1` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.68.0` | `10.69.0` | | [@tabler/icons-react](https://github.com/tabler/tabler-icons/tree/HEAD/packages/icons-react) | `3.45.0` | `3.46.0` | | [axios](https://github.com/axios/axios) | `1.18.1` | `1.19.0` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.83.0` | `7.84.0` | | [@flakiness/playwright](https://github.com/flakiness/playwright) | `2.0.0` | `2.0.1` | | [@playwright/test](https://github.com/microsoft/playwright) | `1.62.0` | `1.62.1` | | [rollup](https://github.com/rollup/rollup) | `4.62.3` | `4.62.4` | Updates `@mantine/carousel` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/carousel) Updates `@mantine/charts` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/charts) Updates `@mantine/core` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/core) Updates `@mantine/dates` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/dates) Updates `@mantine/dropzone` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/dropzone) Updates `@mantine/form` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/form) Updates `@mantine/hooks` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/hooks) Updates `@mantine/modals` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/modals) Updates `@mantine/notifications` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/notifications) Updates `@mantine/spotlight` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/spotlight) Updates `@mantine/vanilla-extract` from 9.5.0 to 9.5.1 - [Release notes](https://github.com/mantinedev/mantine/releases) - [Changelog](https://github.com/mantinedev/mantine/blob/master/CHANGELOG.md) - [Commits](https://github.com/mantinedev/mantine/commits/9.5.1/packages/@mantine/vanilla-extract) Updates `@sentry/react` from 10.68.0 to 10.69.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/10.69.0/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.68.0...10.69.0) Updates `@tabler/icons-react` from 3.45.0 to 3.46.0 - [Release notes](https://github.com/tabler/tabler-icons/releases) - [Commits](https://github.com/tabler/tabler-icons/commits/v3.46.0/packages/icons-react) Updates `axios` from 1.18.1 to 1.19.0 - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.18.1...v1.19.0) Updates `react-hook-form` from 7.83.0 to 7.84.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.83.0...v7.84.0) Updates `@flakiness/playwright` from 2.0.0 to 2.0.1 - [Release notes](https://github.com/flakiness/playwright/releases) - [Commits](https://github.com/flakiness/playwright/compare/v2.0.0...v2.0.1) Updates `@playwright/test` from 1.62.0 to 1.62.1 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.62.0...v1.62.1) Updates `rollup` from 4.62.3 to 4.62.4 - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.62.3...v4.62.4) --- updated-dependencies: - dependency-name: "@mantine/carousel" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/charts" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/core" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/dates" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/dropzone" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/form" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/hooks" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/modals" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/notifications" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/spotlight" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@mantine/vanilla-extract" dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@sentry/react" dependency-version: 10.69.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@tabler/icons-react" dependency-version: 3.46.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: axios dependency-version: 1.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: react-hook-form dependency-version: 7.84.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@flakiness/playwright" dependency-version: 2.0.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@playwright/test" dependency-version: 1.62.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: rollup dependency-version: 4.62.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [CI] Improve robustness for playwright test (#12612) * Update version for @inventreedb/ui (#12611) * Update version for @inventreedb/ui * Revert yarn.lock changes * Bump version number for UI (#12615) * New Crowdin translations by GitHub Action (#12535) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(frontend): Improve flakiness issues (#12617) * small improvements to reduce flakiness * disable throtteling to fix flaking tests * [bug] Handle duplicate email addresses for magic links (#12621) * refactor(backend): remove network dep from test (#12624) * feat(backend): switch to a more formal FSM approach (#12507) * full fsm implementation closes https://github.com/inventree/InvenTree/issues/12314 based on https://github.com/matmair/InvenTree/pull/721 * update assertations * refactor to reduce duplication * move for cleaner diff * more moving stuff around * fix assingment * remove skip * merge test classes * re-enable transition plugin tests * fix docstrings * add depreciation warning * fix type * nitpicks * small cleanup * ensure we alwas pass a str * add backport * fix marker position * full fsm implementation closes https://github.com/inventree/InvenTree/issues/12314 based on https://github.com/matmair/InvenTree/pull/721 * update assertations * refactor to reduce duplication * move for cleaner diff * more moving stuff around * fix assingment * remove skip * merge test classes * re-enable transition plugin tests * fix docstrings * add depreciation warning * fix type * nitpicks * small cleanup * ensure we alwas pass a str * add backport * fix marker position * fix ty issue * ignore this corner case * ensure invalid transitions can raise a nice validation error * compact code * add depreciation mark * make raise_error default (#754) * fix merge * adjust test as this is now not a no-op but a raised error * fix assertations * fix test to not take a broken path * remove unused test statements * converge * add test branch for actually working transition * reduce uneeded code * ignore depreceated methods * fix missing coverage * add prefetch * reduce diff * refactor fail limit to match allauth defaults more closely (#12623) * fix: support UUID notification references (#12616) * fix: support UUID notification references * test: update notification uid expectation --------- Co-authored-by: FurinaDog * [bug] OptionalField race condition (#12627) * [bug] OptionalField race condition Fixes subtle bug where OptionalField entries can be silenty dropped from an API request due to concurrent requests / race conditions * Additional unit tests * Additional guard in metadata.py * include extra kwargs * Adjust import/exporting options * Fix attribute sharing across class instances * reset errors on update (#12550) * reset errors on update * add empty line --------- Co-authored-by: Oliver * Add docs for return order (#12632) * [bug] Fix ReturnOrder event registration (#12633) * Allow bulk-edit for ReturnOrderLineItem (#12635) * Allow bulk-edit for ReturnOrderLineItem - Allow bulk change of line item outcome * Update API version documentation with pull request links * [bug] Fix broken user setting (#12638) - Closes https://github.com/inventree/InvenTree/issues/12637 * try fixing this flaky test on firefox (#12640) * feat: add piece_count and piece_size fields to BomItem for cut-to-length parts (#12422) * feat: add piece_count and piece_size fields to BomItem for cut-to-length parts Manufacturing BOMs frequently require multiple pieces of a specific size cut from continuous stock (cables, tubing, structural profiles). Currently the only way to express "10 pieces of 250mm cable" is to enter the total length (2.5m) as quantity, which loses the piece-count information that purchasing and production need. This adds two optional fields to BomItem: - piece_count: number of discrete pieces required (default: 1) - piece_size: size/length of each piece (e.g. "250 mm") When piece_size is specified, the total quantity is auto-calculated as piece_count × piece_size, maintaining full backward compatibility (existing items effectively have piece_count=1 and empty piece_size). Changes: - Backend: new model fields, migration, updated recalculate_quantity() logic, hash_fields for BOM validation - API: serializer exposes piece_count and piece_size - Frontend: BOM form includes the new fields, BOM table shows them as optional columns Addresses #10274 * refactor: simplify to single piece_count field per reviewer feedback Remove the piece_size field entirely. The existing quantity field already represents the per-piece size/length, so piece_count multiplied by quantity gives the total material requirement. Example: quantity=200mm, piece_count=10 → total 2m of wire in 10 pieces. Changes: - Remove piece_size model field, serializer field, and frontend column/form - Update migration to only add piece_count - Update get_required_quantity() to multiply by piece_count - Restore original recalculate_quantity() without piece_size logic * test/docs: add unit tests and documentation for piece_count field * style: replace ambiguous × with x to fix RUF002 lint error * Address review feedback: api_version bump, changelog, style fix - Bump INVENTREE_API_VERSION to 531 with entry for piece_count field - Add CHANGELOG.md entry under Unreleased > Added - Fix RUF001: replace ambiguous × with x in serializers.py help_text * fix: align piece_count migration help_text with model (RUF001) The 0153 AddField recorded help_text with a Unicode multiplication sign (×), while the model field uses plain 'x' after the RUF001 fix. This mismatch made makemigrations --check flag an unstaged 0154_alter_bomitem_piece_count migration, failing the DB test CI jobs. Update the original migration's help_text (and docstring) to plain 'x' so the field definition matches the model, keeping a single clean migration instead of add-then-alter. * fix: use set_quantity() in piece_count tests BomItem.quantity is a derived field, recalculated from raw_amount on every save() via recalculate_quantity(). Setting item.quantity directly was overwritten back to the fixture value on save, so the tests computed against quantity=3 and failed. Use set_quantity() (which sets raw_amount) to match how quantity is meant to be updated. * ci: re-trigger CI to confirm Firefox E2E failures are transient --------- Co-authored-by: Aman Jain * Improve error handling for unit registry (#12643) * New Crowdin translations by GitHub Action (#12625) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * chore(deps): bump the dependencies group across 1 directory with 6 updates (#12651) Bumps the dependencies group with 6 updates in the /src/frontend directory: | Package | From | To | | --- | --- | --- | | [@codemirror/view](https://github.com/codemirror/view) | `6.43.7` | `6.43.8` | | [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.69.0` | `10.70.0` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.84.0` | `7.85.0` | | [styled-components](https://github.com/styled-components/styled-components) | `6.4.4` | `6.5.1` | | [@flakiness/playwright](https://github.com/flakiness/playwright) | `2.0.1` | `2.0.2` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `26.1.2` | `26.2.0` | Updates `@codemirror/view` from 6.43.7 to 6.43.8 - [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/view/commits) Updates `@sentry/react` from 10.69.0 to 10.70.0 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/10.70.0/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/10.69.0...10.70.0) Updates `react-hook-form` from 7.84.0 to 7.85.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.84.0...v7.85.0) Updates `styled-components` from 6.4.4 to 6.5.1 - [Release notes](https://github.com/styled-components/styled-components/releases) - [Commits](https://github.com/styled-components/styled-components/compare/styled-components@6.4.4...styled-components@6.5.1) Updates `@flakiness/playwright` from 2.0.1 to 2.0.2 - [Release notes](https://github.com/flakiness/playwright/releases) - [Commits](https://github.com/flakiness/playwright/compare/v2.0.1...v2.0.2) Updates `@types/node` from 26.1.2 to 26.2.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@codemirror/view" dependency-version: 6.43.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@sentry/react" dependency-version: 10.70.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: react-hook-form dependency-version: 7.85.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: styled-components dependency-version: 6.5.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: "@flakiness/playwright" dependency-version: 2.0.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: "@types/node" dependency-version: 26.2.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the dependencies group with 5 updates (#12652) Bumps the dependencies group with 5 updates: | Package | From | To | | --- | --- | --- | | [dorny/paths-filter](https://github.com/dorny/paths-filter) | `4.0.2` | `4.0.3` | | [oasdiff/oasdiff-action/diff](https://github.com/oasdiff/oasdiff-action) | `0.1.11` | `0.1.12` | | [CodSpeedHQ/action](https://github.com/codspeedhq/action) | `5.0.2` | `5.0.3` | | [actions/attest](https://github.com/actions/attest) | `4.2.1` | `4.2.2` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.5` | `4.37.6` | Updates `dorny/paths-filter` from 4.0.2 to 4.0.3 - [Release notes](https://github.com/dorny/paths-filter/releases) - [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) - [Commits](https://github.com/dorny/paths-filter/compare/7b450fff21473bca461d4b92ce414b9d0420d706...ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d) Updates `oasdiff/oasdiff-action/diff` from 0.1.11 to 0.1.12 - [Release notes](https://github.com/oasdiff/oasdiff-action/releases) - [Commits](https://github.com/oasdiff/oasdiff-action/compare/b7c3adeb54330db1903d27c61db520e5661ad55b...033c15c845bef10f148afb0fa781bf1b2a7fe1bf) Updates `CodSpeedHQ/action` from 5.0.2 to 5.0.3 - [Release notes](https://github.com/codspeedhq/action/releases) - [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codspeedhq/action/compare/0ca9cbbf4623b599a6c3ed4fc8a922942705d9f1...4296e51e7041e24dadb86d1d6e8b9320d223dbe8) Updates `actions/attest` from 4.2.1 to 4.2.2 - [Release notes](https://github.com/actions/attest/releases) - [Changelog](https://github.com/actions/attest/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest/compare/508db95dd578ae2727ebd6217d5ba78e4fbda05d...1e69f48acb82d1966a394da916b4c1698aa569d6) Updates `github/codeql-action/upload-sarif` from 4.37.5 to 4.37.6 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/d1ba80a13dd99fba24a470575428917156a28b43...5595ccaf912efad79be6eef63a5619ff05969be3) --- updated-dependencies: - dependency-name: dorny/paths-filter dependency-version: 4.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: oasdiff/oasdiff-action/diff dependency-version: 0.1.12 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: CodSpeedHQ/action dependency-version: 5.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: actions/attest dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the dependencies group across 1 directory with 14 updates (#12642) * chore(deps): bump the dependencies group across 1 directory with 14 updates Bumps the dependencies group with 14 updates in the /src/backend directory: | Package | From | To | | --- | --- | --- | | [cffi](https://github.com/python-cffi/cffi) | `2.1.0` | `2.1.1` | | [coverage](https://github.com/coveragepy/coveragepy) | `7.15.2` | `7.15.4` | | [django-stubs](https://github.com/typeddjango/django-stubs) | `6.0.7` | `6.0.9` | | [django-stubs-ext](https://github.com/typeddjango/django-stubs) | `6.0.6` | `6.0.9` | | [django-test-migrations](https://github.com/wemake-services/django-test-migrations) | `1.5.0` | `1.6.0` | | [packaging](https://github.com/pypa/packaging) | `26.2` | `26.3` | | [pip](https://github.com/pypa/pip) | `26.2` | `26.2.1` | | [prek](https://github.com/j178/prek) | `0.4.11` | `0.4.12` | | [pytest-django](https://github.com/pytest-dev/pytest-django) | `4.12.0` | `4.13.0` | | [blessed](https://github.com/jquast/blessed) | `1.47.0` | `1.48.0` | | [boto3](https://github.com/boto/boto3) | `1.43.61` | `1.43.66` | | [botocore](https://github.com/boto/botocore) | `1.43.61` | `1.43.66` | | [djangorestframework](https://github.com/encode/django-rest-framework) | `3.17.1` | `3.18.0` | | [googleapis-common-protos](https://github.com/googleapis/google-cloud-python) | `1.75.0` | `1.75.1` | Updates `cffi` from 2.1.0 to 2.1.1 - [Release notes](https://github.com/python-cffi/cffi/releases) - [Commits](https://github.com/python-cffi/cffi/compare/v2.1.0...v2.1.1) Updates `coverage` from 7.15.2 to 7.15.4 - [Release notes](https://github.com/coveragepy/coveragepy/releases) - [Changelog](https://github.com/coveragepy/coveragepy/blob/main/CHANGES.rst) - [Commits](https://github.com/coveragepy/coveragepy/compare/7.15.2...7.15.4) Updates `django-stubs` from 6.0.7 to 6.0.9 - [Release notes](https://github.com/typeddjango/django-stubs/releases) - [Commits](https://github.com/typeddjango/django-stubs/compare/6.0.7...6.0.9) Updates `django-stubs-ext` from 6.0.6 to 6.0.9 - [Release notes](https://github.com/typeddjango/django-stubs/releases) - [Commits](https://github.com/typeddjango/django-stubs/compare/6.0.6...6.0.9) Updates `django-test-migrations` from 1.5.0 to 1.6.0 - [Release notes](https://github.com/wemake-services/django-test-migrations/releases) - [Changelog](https://github.com/wemake-services/django-test-migrations/blob/master/CHANGELOG.md) - [Commits](https://github.com/wemake-services/django-test-migrations/compare/1.5.0...1.6.0) Updates `packaging` from 26.2 to 26.3 - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/26.2...26.3) Updates `pip` from 26.2 to 26.2.1 - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/26.2...26.2.1) Updates `prek` from 0.4.11 to 0.4.12 - [Release notes](https://github.com/j178/prek/releases) - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md) - [Commits](https://github.com/j178/prek/compare/v0.4.11...v0.4.12) Updates `pytest-django` from 4.12.0 to 4.13.0 - [Release notes](https://github.com/pytest-dev/pytest-django/releases) - [Changelog](https://github.com/pytest-dev/pytest-django/blob/main/docs/changelog.rst) - [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.12.0...v4.13.0) Updates `blessed` from 1.47.0 to 1.48.0 - [Release notes](https://github.com/jquast/blessed/releases) - [Changelog](https://github.com/jquast/blessed/blob/master/docs/history.rst) - [Commits](https://github.com/jquast/blessed/commits/1.48) Updates `boto3` from 1.43.61 to 1.43.66 - [Release notes](https://github.com/boto/boto3/releases) - [Commits](https://github.com/boto/boto3/compare/1.43.61...1.43.66) Updates `botocore` from 1.43.61 to 1.43.66 - [Commits](https://github.com/boto/botocore/compare/1.43.61...1.43.66) Updates `djangorestframework` from 3.17.1 to 3.18.0 - [Release notes](https://github.com/encode/django-rest-framework/releases) - [Commits](https://github.com/encode/django-rest-framework/compare/3.17.1...3.18.0) Updates `googleapis-common-protos` from 1.75.0 to 1.75.1 - [Release notes](https://github.com/googleapis/google-cloud-python/releases) - [Changelog](https://github.com/googleapis/google-cloud-python/blob/main/packages/google-cloud-documentai/CHANGELOG.md) - [Commits](https://github.com/googleapis/google-cloud-python/compare/googleapis-common-protos-v1.75.0...googleapis-common-protos-v1.75.1) --- updated-dependencies: - dependency-name: cffi dependency-version: 2.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: coverage dependency-version: 7.15.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: django-stubs dependency-version: 6.0.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: django-stubs-ext dependency-version: 6.0.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: django-test-migrations dependency-version: 1.6.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: packaging dependency-version: '26.3' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: pip dependency-version: 26.2.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: prek dependency-version: 0.4.12 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: pytest-django dependency-version: 4.13.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: blessed dependency-version: 1.48.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: boto3 dependency-version: 1.43.66 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: botocore dependency-version: 1.43.66 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: djangorestframework dependency-version: 3.18.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: googleapis-common-protos dependency-version: 1.75.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * Fix issue 10769 (#12286) * fix: Show badges for flagged stock items * Updated badge logic to only display on build order and sales order * refactor: Remove unused modelRenderer for RenderStockItem in BuildForms and SalesOrderForms * chore(deps): bump python in /contrib/container (#12650) Bumps python from 3.14.6-slim-trixie to 3.14.7-slim-trixie. --- updated-dependencies: - dependency-name: python dependency-version: 3.14.7-slim-trixie dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump sqlparse from 0.5.5 to 0.6.0 in /src/backend (#12653) * chore(deps): bump sqlparse from 0.5.5 to 0.6.0 in /src/backend Bumps [sqlparse](https://github.com/andialbrecht/sqlparse) from 0.5.5 to 0.6.0. - [Changelog](https://github.com/andialbrecht/sqlparse/blob/master/CHANGELOG) - [Commits](https://github.com/andialbrecht/sqlparse/compare/0.5.5...0.6.0) --- updated-dependencies: - dependency-name: sqlparse dependency-version: 0.6.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] * fix style --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthias Mair * [FR] stop shipping docs with packages (#12657) Fixes #12610 * feat(frontend): Add persistant filtered detail navigation in the url (#12585) * Add filtered detail navigation * Satisfy navigation lint checks * Fix missing Fragment import in PageDetail * Address detail navigation review feedback * Move detail navigation into breadcrumb bar * Address URL and layout review feedback * Address detail navigation review feedback * fix doclinks * test: update stock return validation assertion * fix: keep detail navigation actions stable * style: apply biome formatting * fix: use ActionIcon disabled state * test: use ActionIcon disabled state * fix: isolate detail navigation query params --------- Co-authored-by: Matthias Mair Co-authored-by: Oliver --------- Signed-off-by: dependabot[bot] Co-authored-by: 开源斗士 <43269525+geekcj12@users.noreply.github.com> Co-authored-by: Oliver Co-authored-by: Andrey Lushnikov Co-authored-by: Phil Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Neil Beukes Co-authored-by: suzunn Co-authored-by: Miklós Márton Co-authored-by: Petr Ledvina Co-authored-by: gunstr <41468206+gunstr@users.noreply.github.com> Co-authored-by: br413 Co-authored-by: Leonid Zaliubovskyi Co-authored-by: Λamir <86316974+aamirasmal15@users.noreply.github.com> Co-authored-by: Alex K Co-authored-by: snipe Co-authored-by: Bhumin Paladiya <139330832+bhumin18@users.noreply.github.com> Co-authored-by: Dean Co-authored-by: Hana Lee <47701469+hanielee@users.noreply.github.com> Co-authored-by: Hana Co-authored-by: Jayasree Co-authored-by: jayasree723 Co-authored-by: siddhartha28 <31231363+siddhartha928@users.noreply.github.com> Co-authored-by: Siddhartha Ravilla Co-authored-by: FurinaDog Co-authored-by: FurinaDog Co-authored-by: ribsey Co-authored-by: amanjain57-gif Co-authored-by: Aman Jain Co-authored-by: Alonso Lopez-Valdez Co-authored-by: Jɤ KέϞϞψ --- .devcontainer/Dockerfile | 10 +- .devops/test_stats.yml | 79 - .github/actions/setup/action.yaml | 8 +- .github/workflows/backport.yaml | 2 +- .github/workflows/check_translations.yaml | 8 +- .github/workflows/docker.yaml | 47 +- .github/workflows/frontend.yaml | 312 + .github/workflows/import_export.yaml | 10 +- .github/workflows/qc_checks.yaml | 186 +- .github/workflows/release.yaml | 78 +- .github/workflows/scorecard.yaml | 6 +- .github/workflows/stale.yaml | 2 +- .github/workflows/translations.yaml | 6 +- .github/workflows/update.yml.disabled | 4 +- .gitignore | 3 +- .pkgr.yml | 10 +- .pre-commit-config.yaml | 4 +- .vscode/launch.json | 2 +- AGENTS.md | 5 + CHANGELOG.md | 63 +- CLAUDE.md | 5 + CONTRIBUTING.md | 219 +- README.md | 2 +- codecov.yml | 7 +- contrib/container/.env | 20 +- contrib/container/Dockerfile | 26 +- contrib/container/docker-compose.yml | 3 + contrib/container/gunicorn.conf.py | 10 +- contrib/container/requirements.in | 14 +- contrib/container/requirements.txt | 216 +- contrib/dev_reqs/requirements.in | 4 +- contrib/dev_reqs/requirements.txt | 248 +- contrib/packager.io/functions.sh | 2 +- contrib/packager.io/postinstall.sh | 2 +- docs/docs/api/index.md | 2 +- docs/docs/app/barcode.md | 4 + .../images/concepts/ui_navigation_tree.png | Bin 25041 -> 41520 bytes .../concepts/ui_preview_details_link.png | Bin 0 -> 76761 bytes .../images/concepts/ui_preview_drawer.png | Bin 0 -> 155287 bytes .../ui_table_column_filter_popover.png | Bin 0 -> 72592 bytes .../images/concepts/ui_table_filter_group.png | Bin 0 -> 29037 bytes docs/docs/barcodes/custom.md | 2 +- docs/docs/barcodes/index.md | 2 +- docs/docs/concepts/data_import.md | 4 +- docs/docs/concepts/parameters.md | 42 +- docs/docs/concepts/pricing.md | 36 + docs/docs/concepts/tags.md | 82 + docs/docs/concepts/terminology.md | 2 +- docs/docs/concepts/ui/forms.md | 37 + docs/docs/concepts/ui/global_search.md | 42 + docs/docs/concepts/ui/index.md | 190 + docs/docs/concepts/ui/preview_panels.md | 37 + docs/docs/concepts/ui/tables.md | 149 + docs/docs/develop/contributing.md | 20 +- docs/docs/faq.md | 24 +- docs/docs/hooks.py | 4 +- docs/docs/manufacturing/allocate.md | 51 +- docs/docs/manufacturing/bom.md | 43 + docs/docs/manufacturing/external.md | 2 + docs/docs/manufacturing/index.md | 6 + docs/docs/manufacturing/output.md | 11 +- docs/docs/part/consumable.md | 55 + docs/docs/part/create.md | 2 +- docs/docs/part/index.md | 5 + docs/docs/part/notification.md | 2 +- docs/docs/part/pricing.md | 2 +- docs/docs/part/stocktake.md | 4 +- docs/docs/part/trackable.md | 13 +- docs/docs/part/views.md | 18 +- docs/docs/plugins/creator.md | 4 +- docs/docs/plugins/develop.md | 4 +- docs/docs/plugins/mixins/barcode.md | 4 +- docs/docs/plugins/mixins/report.md | 46 +- docs/docs/plugins/walkthrough.md | 10 +- .../{resources.md => sponsored_resources.md} | 5 +- docs/docs/purchasing/purchase_order.md | 33 + docs/docs/purchasing/supplier.md | 3 + docs/docs/report/assets.md | 45 + docs/docs/report/context_variables.md | 247 +- docs/docs/report/helpers.md | 268 +- docs/docs/report/index.md | 141 +- docs/docs/report/labels.md | 19 + docs/docs/report/model_context.md | 24 + docs/docs/report/report.md | 54 +- docs/docs/report/samples.md | 19 +- docs/docs/report/snippets.md | 52 + docs/docs/report/template_editor.md | 11 +- docs/docs/sales/return_order.md | 81 +- docs/docs/sales/sales_order.md | 80 + docs/docs/security.md | 20 +- docs/docs/settings/MFA.md | 2 +- docs/docs/settings/SSO.md | 4 +- docs/docs/settings/admin.md | 65 +- docs/docs/settings/db_admin.md | 54 + docs/docs/settings/global.md | 3 + docs/docs/settings/logs.md | 15 +- docs/docs/settings/permissions.md | 10 +- docs/docs/settings/tasks.md | 4 +- docs/docs/settings/user.md | 3 + docs/docs/start/config.md | 28 +- docs/docs/start/docker.md | 3 + docs/docs/start/docker_install.md | 19 +- docs/docs/start/processes.md | 12 +- docs/docs/stock/adjust.md | 2 + docs/docs/stock/disassemble.md | 90 + docs/docs/stock/tracking.md | 25 + docs/docs/stock/transfer_order.md | 1 + docs/main.py | 69 + docs/mkdocs.yml | 22 +- docs/mlc_config.json | 3 - docs/requirements.in | 6 +- docs/requirements.txt | 389 +- pyproject.toml | 21 +- readthedocs.yml | 4 +- src/backend/InvenTree/InvenTree/admin.py | 53 + src/backend/InvenTree/InvenTree/api.py | 87 +- .../InvenTree/InvenTree/api_version.py | 129 +- src/backend/InvenTree/InvenTree/apps.py | 24 +- .../InvenTree/InvenTree/auth_overrides.py | 9 +- src/backend/InvenTree/InvenTree/conversion.py | 3 + src/backend/InvenTree/InvenTree/exceptions.py | 47 +- src/backend/InvenTree/InvenTree/fields.py | 70 +- src/backend/InvenTree/InvenTree/format.py | 47 - src/backend/InvenTree/InvenTree/helpers.py | 73 +- src/backend/InvenTree/InvenTree/helpers_db.py | 72 + .../InvenTree/InvenTree/helpers_email.py | 16 +- .../InvenTree/InvenTree/helpers_model.py | 200 +- .../InvenTree/InvenTree/magic_login.py | 3 + .../commands/export_report_context.py | 161 +- .../management/commands/rebuild_models.py | 10 - src/backend/InvenTree/InvenTree/metadata.py | 56 +- src/backend/InvenTree/InvenTree/middleware.py | 26 + src/backend/InvenTree/InvenTree/models.py | 294 +- .../InvenTree/InvenTree/permissions.py | 1 - src/backend/InvenTree/InvenTree/schema.py | 27 +- src/backend/InvenTree/InvenTree/sentry.py | 1 + .../InvenTree/InvenTree/serializers.py | 364 +- .../InvenTree/InvenTree/setting/db_backend.py | 54 +- .../InvenTree/InvenTree/setting/ldap.py | 4 +- src/backend/InvenTree/InvenTree/settings.py | 48 +- src/backend/InvenTree/InvenTree/tasks.py | 273 +- src/backend/InvenTree/InvenTree/test_api.py | 23 + .../InvenTree/InvenTree/test_commands.py | 44 + .../InvenTree/test_helpers/__init__.py | 0 .../InvenTree/test_helpers/sample_tasks.py | 6 + .../InvenTree/InvenTree/test_helpers_db.py | 163 + .../InvenTree/InvenTree/test_middleware.py | 66 +- .../InvenTree/InvenTree/test_serializers.py | 107 +- src/backend/InvenTree/InvenTree/test_tasks.py | 287 +- src/backend/InvenTree/InvenTree/tests.py | 297 +- src/backend/InvenTree/InvenTree/tracing.py | 28 +- src/backend/InvenTree/InvenTree/unit_test.py | 25 +- src/backend/InvenTree/InvenTree/validators.py | 15 +- src/backend/InvenTree/InvenTree/version.py | 25 +- src/backend/InvenTree/build/api.py | 85 +- .../build/migrations/0059_build_tags.py | 29 + src/backend/InvenTree/build/models.py | 961 +- src/backend/InvenTree/build/serializers.py | 205 +- src/backend/InvenTree/build/tasks.py | 155 +- src/backend/InvenTree/build/test_api.py | 1244 +- src/backend/InvenTree/build/test_build.py | 799 +- src/backend/InvenTree/build/validators.py | 10 + src/backend/InvenTree/common/admin.py | 77 +- src/backend/InvenTree/common/api.py | 141 +- src/backend/InvenTree/common/currency.py | 16 +- src/backend/InvenTree/common/filters.py | 31 + .../0044_notificationmessage_charfield_pk.py | 29 + .../migrations/0045_projectcode_active.py | 22 + ...6_alter_emailmessage_global_id_and_more.py | 59 + .../0047_parametertemplate_unique.py | 23 + .../0048_notificationmessage_link.py | 24 + .../0049_notificationentry_charfield_uid.py | 18 + src/backend/InvenTree/common/models.py | 131 +- src/backend/InvenTree/common/notifications.py | 4 + src/backend/InvenTree/common/serializers.py | 125 +- .../InvenTree/common/setting/system.py | 39 + src/backend/InvenTree/common/setting/type.py | 14 +- src/backend/InvenTree/common/setting/user.py | 20 + src/backend/InvenTree/common/settings.py | 22 +- src/backend/InvenTree/common/test_api.py | 555 +- src/backend/InvenTree/common/tests.py | 129 +- src/backend/InvenTree/common/validators.py | 15 + src/backend/InvenTree/company/admin.py | 4 +- src/backend/InvenTree/company/api.py | 25 +- .../migrations/0019_auto_20200413_0642.py | 2 +- .../company/migrations/0080_company_tags.py | 29 + src/backend/InvenTree/company/models.py | 83 +- src/backend/InvenTree/company/serializers.py | 72 +- src/backend/InvenTree/company/test_api.py | 2 +- src/backend/InvenTree/company/tests.py | 19 - src/backend/InvenTree/config_template.yaml | 11 + src/backend/InvenTree/data_exporter/mixins.py | 13 + .../InvenTree/data_exporter/serializers.py | 14 +- .../InvenTree/generic/states/__init__.py | 10 +- .../InvenTree/generic/states/deprecations.py | 27 + .../InvenTree/generic/states/fields.py | 93 +- .../InvenTree/generic/states/states.py | 20 +- .../generic/states/test_transition.py | 162 +- .../InvenTree/generic/states/transition.py | 288 +- src/backend/InvenTree/importer/api.py | 46 +- .../0006_dataimportcolumnmap_lookup_field.py | 24 + ...on_completed_row_count_history_and_more.py | 23 + ...ata_alter_dataimportrow_errors_and_more.py | 88 + src/backend/InvenTree/importer/mixins.py | 10 + src/backend/InvenTree/importer/models.py | 327 +- src/backend/InvenTree/importer/operations.py | 38 +- src/backend/InvenTree/importer/serializers.py | 51 +- src/backend/InvenTree/importer/tests.py | 706 +- src/backend/InvenTree/importer/validators.py | 9 +- .../InvenTree/locale/ar/LC_MESSAGES/django.po | 10419 ++++++------- .../InvenTree/locale/bg/LC_MESSAGES/django.po | 5295 ++++--- .../InvenTree/locale/cs/LC_MESSAGES/django.po | 4987 ++++--- .../InvenTree/locale/da/LC_MESSAGES/django.po | 5293 ++++--- .../InvenTree/locale/de/LC_MESSAGES/django.po | 5081 ++++--- .../InvenTree/locale/el/LC_MESSAGES/django.po | 4979 ++++--- .../InvenTree/locale/en/LC_MESSAGES/django.po | 5293 ++++--- .../InvenTree/locale/es/LC_MESSAGES/django.po | 5109 ++++--- .../locale/es_MX/LC_MESSAGES/django.po | 5109 ++++--- .../InvenTree/locale/et/LC_MESSAGES/django.po | 5333 ++++--- .../InvenTree/locale/fa/LC_MESSAGES/django.po | 5295 ++++--- .../InvenTree/locale/fi/LC_MESSAGES/django.po | 5191 ++++--- .../InvenTree/locale/fr/LC_MESSAGES/django.po | 4977 ++++--- .../InvenTree/locale/he/LC_MESSAGES/django.po | 5295 ++++--- .../InvenTree/locale/hi/LC_MESSAGES/django.po | 5295 ++++--- .../InvenTree/locale/hu/LC_MESSAGES/django.po | 4979 ++++--- .../InvenTree/locale/id/LC_MESSAGES/django.po | 5301 ++++--- .../InvenTree/locale/it/LC_MESSAGES/django.po | 4977 ++++--- .../InvenTree/locale/ja/LC_MESSAGES/django.po | 5231 ++++--- .../InvenTree/locale/ko/LC_MESSAGES/django.po | 5128 ++++--- .../InvenTree/locale/lt/LC_MESSAGES/django.po | 5005 ++++--- .../InvenTree/locale/lv/LC_MESSAGES/django.po | 5295 ++++--- .../InvenTree/locale/nl/LC_MESSAGES/django.po | 4999 ++++--- .../InvenTree/locale/no/LC_MESSAGES/django.po | 5099 ++++--- .../InvenTree/locale/pl/LC_MESSAGES/django.po | 5181 ++++--- .../InvenTree/locale/pt/LC_MESSAGES/django.po | 5083 ++++--- .../locale/pt_BR/LC_MESSAGES/django.po | 8159 ++++++----- .../InvenTree/locale/ro/LC_MESSAGES/django.po | 5279 ++++--- .../InvenTree/locale/ru/LC_MESSAGES/django.po | 5145 ++++--- .../InvenTree/locale/sk/LC_MESSAGES/django.po | 5295 ++++--- .../InvenTree/locale/sl/LC_MESSAGES/django.po | 5293 ++++--- .../InvenTree/locale/sr/LC_MESSAGES/django.po | 5001 ++++--- .../InvenTree/locale/sv/LC_MESSAGES/django.po | 5309 ++++--- .../InvenTree/locale/th/LC_MESSAGES/django.po | 5295 ++++--- .../InvenTree/locale/tr/LC_MESSAGES/django.po | 5439 +++---- .../InvenTree/locale/uk/LC_MESSAGES/django.po | 5297 ++++--- .../InvenTree/locale/vi/LC_MESSAGES/django.po | 5101 ++++--- .../locale/zh_Hans/LC_MESSAGES/django.po | 4973 ++++--- .../locale/zh_Hant/LC_MESSAGES/django.po | 4967 ++++--- src/backend/InvenTree/machine/api.py | 6 +- .../machine/machine_types/label_printer.py | 6 +- .../migrations/0002_alter_machineconfig_id.py | 28 + src/backend/InvenTree/machine/models.py | 5 +- src/backend/InvenTree/machine/test_api.py | 15 +- src/backend/InvenTree/machine/tests.py | 110 +- src/backend/InvenTree/order/admin.py | 9 +- src/backend/InvenTree/order/api.py | 221 +- src/backend/InvenTree/order/events.py | 4 +- .../InvenTree/order/fixtures/sales_order.yaml | 8 + ...turnorder_tags_salesorder_tags_and_more.py | 73 + .../migrations/0121_add_line_item_discount.py | 119 + src/backend/InvenTree/order/models.py | 1495 +- src/backend/InvenTree/order/serializers.py | 546 +- src/backend/InvenTree/order/status_codes.py | 3 +- src/backend/InvenTree/order/tasks.py | 65 +- src/backend/InvenTree/order/test_api.py | 1781 ++- .../InvenTree/order/test_sales_order.py | 730 +- src/backend/InvenTree/order/tests.py | 12 +- src/backend/InvenTree/part/api.py | 102 +- .../migrations/0067_partinternalpricebreak.py | 1 + .../part/migrations/0151_part_consumable.py | 22 + .../0152_alter_partpricing_currency.py | 26 + ..._bomitem_piece_count_bomitem_piece_size.py | 30 + src/backend/InvenTree/part/models.py | 551 +- src/backend/InvenTree/part/serializers.py | 149 +- src/backend/InvenTree/part/tasks.py | 61 +- src/backend/InvenTree/part/test_api.py | 357 +- src/backend/InvenTree/part/test_bom_item.py | 225 +- src/backend/InvenTree/part/test_param.py | 2 +- src/backend/InvenTree/part/test_part.py | 50 +- src/backend/InvenTree/part/test_pricing.py | 34 + src/backend/InvenTree/plugin/api.py | 31 +- .../InvenTree/plugin/base/barcodes/api.py | 123 +- .../InvenTree/plugin/base/barcodes/mixins.py | 59 +- .../plugin/base/barcodes/test_barcode.py | 165 +- .../InvenTree/plugin/base/event/events.py | 131 +- .../plugin/base/event/test_events.py | 134 + .../plugin/base/integration/AppMixin.py | 4 +- .../plugin/base/integration/ScheduleMixin.py | 86 +- src/backend/InvenTree/plugin/base/ui/tests.py | 21 + .../InvenTree/plugin/broken/broken_file.py | 2 +- .../builtin/barcodes/inventree_barcode.py | 14 +- .../barcodes/test_inventree_barcode.py | 1 + .../builtin/events/auto_create_builds.py | 4 +- .../builtin/exporter/stocktake_exporter.py | 52 +- .../plugin/builtin/exporter/test_exporter.py | 3 +- .../builtin/integration/core_notifications.py | 8 +- .../integration/test_core_notifications.py | 2 - .../builtin/labels/inventree_machine.py | 5 +- .../plugin/builtin/labels/label_sheet.py | 3 +- .../suppliers/test_supplier_barcodes.py | 204 + src/backend/InvenTree/plugin/events.py | 17 +- src/backend/InvenTree/plugin/helpers.py | 16 +- src/backend/InvenTree/plugin/installer.py | 94 +- src/backend/InvenTree/plugin/models.py | 37 + src/backend/InvenTree/plugin/plugin.py | 7 +- src/backend/InvenTree/plugin/registry.py | 146 +- .../integration/test_scheduled_task.py | 85 +- .../plugin/samples/integration/transition.py | 9 +- .../samples/supplier/supplier_sample.py | 2 +- src/backend/InvenTree/plugin/serializers.py | 15 +- src/backend/InvenTree/plugin/test_api.py | 200 +- src/backend/InvenTree/plugin/test_plugin.py | 24 + .../plugin/testing/label_machines.py | 48 + src/backend/InvenTree/report/api.py | 59 +- src/backend/InvenTree/report/apps.py | 6 +- src/backend/InvenTree/report/fetcher.py | 69 + src/backend/InvenTree/report/helpers.py | 28 + src/backend/InvenTree/report/mixins.py | 36 +- src/backend/InvenTree/report/models.py | 28 +- src/backend/InvenTree/report/serializers.py | 22 +- .../InvenTree/report/templatetags/barcode.py | 48 +- .../InvenTree/report/templatetags/report.py | 303 +- src/backend/InvenTree/report/test_tags.py | 306 +- src/backend/InvenTree/report/tests.py | 448 +- src/backend/InvenTree/script/update_icons.py | 2 +- src/backend/InvenTree/stock/admin.py | 14 +- src/backend/InvenTree/stock/api.py | 200 +- src/backend/InvenTree/stock/events.py | 1 + .../InvenTree/stock/fixtures/stock.yaml | 116 - .../0120_stockitem_creation_date.py | 23 + .../migrations/0121_auto_20260526_0849.py | 102 + .../0122_alter_stockitem_creation_date.py | 23 + .../0123_remove_stockitem_review_needed.py | 17 + .../migrations/0124_alter_mptt_fields.py | 34 + .../migrations/0125_remove_mptt_fields.py | 41 + .../0126_serial_number_concurrency_guard.py | 34 + .../0127_alter_stockitemtestresult_options.py | 25 + src/backend/InvenTree/stock/models.py | 1351 +- src/backend/InvenTree/stock/serializers.py | 479 +- src/backend/InvenTree/stock/status_codes.py | 4 + src/backend/InvenTree/stock/tasks.py | 61 +- src/backend/InvenTree/stock/test_api.py | 1498 +- .../InvenTree/stock/test_migrations.py | 257 +- src/backend/InvenTree/stock/tests.py | 1136 +- src/backend/InvenTree/users/admin.py | 16 +- src/backend/InvenTree/users/api.py | 42 +- src/backend/InvenTree/users/authentication.py | 4 +- src/backend/InvenTree/users/models.py | 4 +- src/backend/InvenTree/users/serializers.py | 97 +- src/backend/InvenTree/users/test_api.py | 118 + src/backend/InvenTree/web/tests.py | 2 +- src/backend/requirements-3.14.txt | 2222 ++- src/backend/requirements-dev-3.14.txt | 1111 +- src/backend/requirements-dev.txt | 1031 +- src/backend/requirements.in | 13 +- src/backend/requirements.txt | 2220 ++- src/frontend/CHANGELOG.md | 38 + src/frontend/lib/components/Boundary.tsx | 49 +- src/frontend/lib/components/RowActions.tsx | 16 +- .../lib/components/TableColumnSelect.tsx | 2 +- src/frontend/lib/components/TagsList.tsx | 27 + src/frontend/lib/enums/ApiEndpoints.tsx | 3 + src/frontend/lib/enums/ModelInformation.tsx | 70 +- src/frontend/lib/enums/ModelType.tsx | 3 +- src/frontend/lib/functions/Events.tsx | 38 + src/frontend/lib/functions/Navigation.tsx | 2 +- src/frontend/lib/hooks/UseFilterSet.tsx | 57 +- src/frontend/lib/index.ts | 9 + .../lib/plugin/InventreeHmrPlugin.tsx | 40 + .../lib/plugin/LocalizedComponent.tsx | 113 + src/frontend/lib/states/LocalLibState.tsx | 19 + src/frontend/lib/types/Filters.tsx | 19 + src/frontend/lib/types/Forms.tsx | 8 +- src/frontend/lib/types/Panel.tsx | 1 + src/frontend/lib/types/Plugins.tsx | 13 + src/frontend/lib/types/Preview.tsx | 12 + src/frontend/lib/types/Rendering.tsx | 1 + src/frontend/lib/types/Settings.tsx | 1 + src/frontend/lib/types/Tables.tsx | 18 +- src/frontend/netlify.toml | 2 +- src/frontend/package.json | 114 +- src/frontend/playwright.config.ts | 40 +- .../components/buttons/PrintingActions.tsx | 56 +- .../components/buttons/RemoveRowButton.tsx | 3 + .../src/components/buttons/ScanButton.tsx | 57 +- .../components/buttons/SpotlightButton.tsx | 10 +- .../src/components/calendar/Calendar.tsx | 140 +- .../src/components/calendar/OrderCalendar.tsx | 45 +- .../calendar/OrderCalendarToolTip.tsx | 30 +- .../components/dashboard/DashboardLayout.tsx | 6 +- .../components/dashboard/DashboardWidget.tsx | 2 + .../dashboard/DashboardWidgetDrawer.tsx | 5 +- .../dashboard/DashboardWidgetLibrary.tsx | 30 +- .../dashboard/widgets/NewsWidget.tsx | 10 +- .../widgets/QueryCountDashboardWidget.tsx | 3 + .../widgets/StocktakeDashboardWidget.tsx | 1 + .../src/components/details/Details.tsx | 41 +- .../src/components/details/DetailsImage.tsx | 4 + .../src/components/details/ItemDetails.tsx | 23 +- .../details/ParameterDetailsGrid.tsx | 54 + .../TemplateEditor/PdfPreview/PdfPreview.tsx | 10 +- .../editors/TemplateEditor/TemplateEditor.tsx | 304 +- src/frontend/src/components/forms/ApiForm.tsx | 112 +- .../src/components/forms/DateTimeField.tsx | 6 +- .../components/forms/fields/ApiFormField.tsx | 94 +- .../components/forms/fields/BooleanField.tsx | 21 +- .../components/forms/fields/ChoiceField.tsx | 10 +- .../src/components/forms/fields/DateField.tsx | 6 +- .../forms/fields/DependentField.tsx | 17 +- .../src/components/forms/fields/IconField.tsx | 14 +- .../forms/fields/NestedObjectField.tsx | 5 +- .../components/forms/fields/NumberField.tsx | 25 +- .../forms/fields/RelatedModelField.tsx | 19 +- .../components/forms/fields/TableField.tsx | 339 +- .../src/components/forms/fields/TagsField.tsx | 83 + .../src/components/forms/fields/TextField.tsx | 8 +- .../src/components/forms/fields/TreeField.tsx | 502 + .../importer/GlobalImporterDrawer.tsx | 11 +- .../importer/ImportDataSelector.tsx | 11 +- .../importer/ImporterColumnSelector.tsx | 53 + .../src/components/items/ActionDropdown.tsx | 14 +- .../src/components/items/PartCreationMenu.tsx | 109 + .../components/modals/AboutInvenTreeModal.tsx | 14 +- .../src/components/modals/HotkeyModal.tsx | 67 + .../src/components/nav/BreadcrumbList.tsx | 84 +- .../src/components/nav/DetailNavigation.tsx | 68 + src/frontend/src/components/nav/Header.tsx | 17 +- src/frontend/src/components/nav/Layout.tsx | 6 +- .../src/components/nav/NavigationDrawer.tsx | 13 +- .../src/components/nav/NavigationTree.tsx | 315 +- .../src/components/nav/PageDetail.tsx | 99 +- .../nav/PageDetailNavigationBar.tsx | 40 + .../src/components/nav/SearchDrawer.tsx | 16 +- .../src/components/panels/AttachmentPanel.tsx | 1 + .../src/components/panels/NotesPanel.tsx | 1 + .../src/components/panels/PanelGroup.tsx | 34 +- .../src/components/panels/ParametersPanel.tsx | 1 + .../src/components/plugins/PluginContext.tsx | 36 +- .../components/plugins/RemoteComponent.tsx | 157 +- .../previews/GlobalPreviewDrawer.tsx | 28 + .../components/previews/ModelPreviewShim.ts | 30 + .../src/components/previews/PreviewDrawer.tsx | 195 + .../previews/models/BuildOrderPreview.tsx | 25 + .../previews/models/CompanyPreview.tsx | 18 + .../components/previews/models/Fallback.tsx | 31 + .../models/ManufacturerPartPreview.tsx | 26 + .../previews/models/PartCategoryPreview.tsx | 18 + .../previews/models/PartPreview.tsx | 15 + .../previews/models/PurchaseOrderPreview.tsx | 25 + .../previews/models/ReturnOrderPreview.tsx | 25 + .../previews/models/SalesOrderPreview.tsx | 25 + .../models/SalesOrderShipmentPreview.tsx | 25 + .../previews/models/StockLocationPreview.tsx | 18 + .../previews/models/StockPreview.tsx | 30 + .../previews/models/SupplierPartPreview.tsx | 25 + .../previews/models/TransferOrderPreview.tsx | 18 + src/frontend/src/components/render/Build.tsx | 2 +- .../src/components/render/Generic.tsx | 6 + .../src/components/render/Instance.tsx | 200 +- .../src/components/render/ModelHoverCard.tsx | 81 + .../src/components/render/ModelRenderShim.ts | 80 + src/frontend/src/components/render/Order.tsx | 8 +- src/frontend/src/components/render/Part.tsx | 9 +- .../src/components/render/StatusRenderer.tsx | 25 + src/frontend/src/components/render/Stock.tsx | 19 +- .../src/components/settings/QuickAction.tsx | 7 +- .../src/components/settings/SettingList.tsx | 37 +- .../src/components/tables/AppRowActions.tsx | 22 + .../tables/ColumnRenderers.tsx | 77 +- .../src/{ => components}/tables/Filter.tsx | 49 +- .../components/tables/FilterSelectDrawer.tsx | 760 + .../tables/InvenTreeTable.tsx | 362 +- .../tables/InvenTreeTableHeader.tsx | 46 +- .../src/components/tables/PartStockCell.tsx | 138 + .../tables/RowExpansionIcon.tsx | 0 .../tables/TableHoverCard.tsx | 8 +- .../components/wizards/OrderPartsWizard.tsx | 15 +- src/frontend/src/contexts/LanguageContext.tsx | 9 +- src/frontend/src/contexts/ThemeContext.tsx | 4 +- src/frontend/src/contexts/colorSchema.tsx | 17 +- src/frontend/src/defaults/actions.tsx | 103 +- src/frontend/src/defaults/links.tsx | 39 +- src/frontend/src/forms/BomForms.tsx | 8 +- src/frontend/src/forms/BuildForms.tsx | 181 +- src/frontend/src/forms/CommonFields.tsx | 51 + src/frontend/src/forms/CommonForms.tsx | 274 +- src/frontend/src/forms/CompanyForms.tsx | 70 +- src/frontend/src/forms/PartForms.tsx | 17 +- src/frontend/src/forms/PurchaseOrderForms.tsx | 116 +- src/frontend/src/forms/ReturnOrderForms.tsx | 25 +- src/frontend/src/forms/SalesOrderForms.tsx | 89 +- src/frontend/src/forms/StockForms.tsx | 1058 +- src/frontend/src/forms/TransferOrderForms.tsx | 81 +- .../src/forms/selectionListFields.tsx | 118 - .../src/functions/DetailNavigation.tsx | 298 + src/frontend/src/functions/auth.tsx | 28 +- src/frontend/src/functions/comparison.tsx | 94 + src/frontend/src/functions/debug.tsx | 36 + src/frontend/src/functions/icons.tsx | 13 +- src/frontend/src/functions/loading.tsx | 61 +- src/frontend/src/functions/localeReady.ts | 24 + src/frontend/src/hooks/UseCalendar.tsx | 31 +- .../src/hooks/UseDetailNavigation.tsx | 135 + src/frontend/src/hooks/UseRemotePlugin.tsx | 157 + src/frontend/src/locales/ar/messages.po | 12030 +++++++++------- src/frontend/src/locales/bg/messages.po | 8221 ++++++----- src/frontend/src/locales/cs/messages.po | 8307 ++++++----- src/frontend/src/locales/da/messages.po | 8317 ++++++----- src/frontend/src/locales/de/messages.po | 8303 ++++++----- src/frontend/src/locales/el/messages.po | 8307 ++++++----- src/frontend/src/locales/en/messages.po | 8307 ++++++----- src/frontend/src/locales/es/messages.po | 8317 ++++++----- src/frontend/src/locales/es_MX/messages.po | 8291 ++++++----- src/frontend/src/locales/et/messages.po | 8300 ++++++----- src/frontend/src/locales/fa/messages.po | 8221 ++++++----- src/frontend/src/locales/fi/messages.po | 8221 ++++++----- src/frontend/src/locales/fr/messages.po | 8339 ++++++----- src/frontend/src/locales/he/messages.po | 8155 ++++++----- src/frontend/src/locales/hi/messages.po | 8221 ++++++----- src/frontend/src/locales/hu/messages.po | 8307 ++++++----- src/frontend/src/locales/id/messages.po | 8257 ++++++----- src/frontend/src/locales/it/messages.po | 8307 ++++++----- src/frontend/src/locales/ja/messages.po | 8525 ++++++----- src/frontend/src/locales/ko/messages.po | 8458 ++++++----- src/frontend/src/locales/lt/messages.po | 8227 ++++++----- src/frontend/src/locales/lv/messages.po | 8221 ++++++----- src/frontend/src/locales/nl/messages.po | 8307 ++++++----- src/frontend/src/locales/no/messages.po | 8290 ++++++----- src/frontend/src/locales/pl/messages.po | 8171 ++++++----- src/frontend/src/locales/pt/messages.po | 8362 ++++++----- src/frontend/src/locales/pt_BR/messages.po | 10570 +++++++------- src/frontend/src/locales/ro/messages.po | 8167 ++++++----- src/frontend/src/locales/ru/messages.po | 8419 ++++++----- src/frontend/src/locales/sk/messages.po | 8221 ++++++----- src/frontend/src/locales/sl/messages.po | 8237 ++++++----- src/frontend/src/locales/sr/messages.po | 8295 ++++++----- src/frontend/src/locales/sv/messages.po | 8322 ++++++----- src/frontend/src/locales/th/messages.po | 8221 ++++++----- src/frontend/src/locales/tr/messages.po | 8759 ++++++----- src/frontend/src/locales/uk/messages.po | 8213 ++++++----- src/frontend/src/locales/vi/messages.po | 8263 ++++++----- src/frontend/src/locales/zh_Hans/messages.po | 8307 ++++++----- src/frontend/src/locales/zh_Hant/messages.po | 8317 ++++++----- src/frontend/src/main.tsx | 21 +- src/frontend/src/pages/Auth/LoggedIn.tsx | 4 +- src/frontend/src/pages/Auth/Login.tsx | 16 +- .../AccountSettings/SecurityContent.tsx | 7 +- .../AdminCenter/CurrencyManagementPanel.tsx | 2 +- .../Index/Settings/AdminCenter/Index.tsx | 45 +- .../AdminCenter/LabelTemplatePanel.tsx | 8 +- .../AdminCenter/ReportTemplatePanel.tsx | 20 + .../AdminCenter/UnitManagementPanel.tsx | 4 +- .../Index/Settings/PluginSettingsGroup.tsx | 17 +- .../pages/Index/Settings/SystemSettings.tsx | 24 +- .../src/pages/Index/Settings/UserSettings.tsx | 6 +- src/frontend/src/pages/build/BuildDetail.tsx | 255 +- src/frontend/src/pages/build/BuildIndex.tsx | 18 +- .../pages/build/BuildOrderDetailsPanel.tsx | 262 + .../src/pages/company/CompanyDetail.tsx | 137 +- .../src/pages/company/CompanyDetailsPanel.tsx | 119 + .../pages/company/ManufacturerPartDetail.tsx | 117 +- .../company/ManufacturerPartDetailsPanel.tsx | 119 + .../src/pages/company/SupplierPartDetail.tsx | 199 +- .../company/SupplierPartDetailsPanel.tsx | 206 + src/frontend/src/pages/core/GroupDetail.tsx | 10 +- src/frontend/src/pages/core/UserDetail.tsx | 21 +- .../src/pages/part/CategoryDetail.tsx | 135 +- .../pages/part/PartCategoryDetailsPanel.tsx | 121 + src/frontend/src/pages/part/PartDetail.tsx | 499 +- .../src/pages/part/PartDetailsPanel.tsx | 370 + .../src/pages/part/PartStockHistoryDetail.tsx | 7 +- .../src/pages/part/bom/BomCompare.tsx | 2 +- .../pages/part/pricing/BomPricingPanel.tsx | 11 +- .../pages/part/pricing/PriceBreakPanel.tsx | 5 +- .../part/pricing/PricingOverviewPanel.tsx | 74 +- .../part/pricing/PurchaseHistoryPanel.tsx | 7 +- .../pages/part/pricing/SaleHistoryPanel.tsx | 9 +- .../part/pricing/SupplierPricingPanel.tsx | 5 +- .../part/pricing/VariantPricingPanel.tsx | 7 +- .../pages/purchasing/PurchaseOrderDetail.tsx | 240 +- .../purchasing/PurchaseOrderDetailsPanel.tsx | 258 + .../src/pages/purchasing/PurchasingIndex.tsx | 3 +- .../src/pages/sales/ReturnOrderDetail.tsx | 242 +- .../pages/sales/ReturnOrderDetailsPanel.tsx | 270 + src/frontend/src/pages/sales/SalesIndex.tsx | 6 +- .../src/pages/sales/SalesOrderDetail.tsx | 243 +- .../pages/sales/SalesOrderDetailsPanel.tsx | 270 + .../pages/sales/SalesOrderShipmentDetail.tsx | 198 +- .../sales/SalesOrderShipmentDetailsPanel.tsx | 205 + .../src/pages/stock/LocationDetail.tsx | 127 +- src/frontend/src/pages/stock/StockDetail.tsx | 420 +- .../src/pages/stock/StockDetailsPanel.tsx | 413 + .../pages/stock/StockLocationDetailsPanel.tsx | 106 + .../src/pages/stock/TransferOrderDetail.tsx | 192 +- .../pages/stock/TransferOrderDetailsPanel.tsx | 181 + src/frontend/src/router.tsx | 38 +- src/frontend/src/states/LocalState.tsx | 27 +- .../src/states/PreviewDrawerState.tsx | 98 + src/frontend/src/states/ServerApiState.tsx | 26 +- src/frontend/src/states/SettingsStates.tsx | 67 +- src/frontend/src/states/UserState.tsx | 69 +- src/frontend/src/states/states.tsx | 59 +- src/frontend/src/styles/overrides.css | 21 + .../src/tables/bom/BomSubassemblyTable.tsx | 8 +- src/frontend/src/tables/bom/BomTable.tsx | 54 +- src/frontend/src/tables/bom/UsedInTable.tsx | 22 +- .../tables/build/BuildAllocatedStockTable.tsx | 26 +- .../src/tables/build/BuildLineTable.tsx | 145 +- .../src/tables/build/BuildOrderFilters.tsx | 10 +- .../build/BuildOrderParametricTable.tsx | 4 +- .../src/tables/build/BuildOrderTable.tsx | 22 +- .../src/tables/build/BuildOutputTable.tsx | 51 +- .../src/tables/company/AddressTable.tsx | 4 +- .../src/tables/company/CompanyTable.tsx | 45 +- .../src/tables/company/ContactTable.tsx | 2 +- .../tables/company/ParametricCompanyTable.tsx | 5 +- .../src/tables/general/AttachmentTable.tsx | 2 +- .../src/tables/general/BarcodeScanTable.tsx | 8 +- .../src/tables/general/ExtraLineItemTable.tsx | 32 +- .../src/tables/general/ParameterTable.tsx | 25 +- .../tables/general/ParameterTemplateTable.tsx | 15 +- .../tables/general/ParametricDataTable.tsx | 81 +- .../src/tables/machine/MachineListTable.tsx | 7 +- .../src/tables/machine/MachineTypeTable.tsx | 7 +- .../notifications/NotificationTable.tsx | 2 +- .../src/tables/part/ParametricPartTable.tsx | 32 +- .../tables/part/PartBuildAllocationsTable.tsx | 15 +- .../src/tables/part/PartCategoryTable.tsx | 17 +- .../tables/part/PartCategoryTemplateTable.tsx | 28 +- .../tables/part/PartPurchaseOrdersTable.tsx | 17 +- .../tables/part/PartSalesAllocationsTable.tsx | 17 +- .../src/tables/part/PartSalesOrdersTable.tsx | 129 + src/frontend/src/tables/part/PartTable.tsx | 279 +- .../src/tables/part/PartTableFilters.tsx | 19 +- .../src/tables/part/PartTestResultTable.tsx | 26 +- .../src/tables/part/PartTestTemplateTable.tsx | 16 +- .../src/tables/part/RelatedPartTable.tsx | 4 +- .../src/tables/plugin/PluginErrorTable.tsx | 2 +- .../src/tables/plugin/PluginListTable.tsx | 15 +- .../ManufacturerPartParametricTable.tsx | 6 +- .../purchasing/ManufacturerPartTable.tsx | 30 +- .../purchasing/PurchaseOrderFilters.tsx | 6 +- .../purchasing/PurchaseOrderLineItemTable.tsx | 49 +- .../PurchaseOrderParametricTable.tsx | 2 +- .../tables/purchasing/PurchaseOrderTable.tsx | 12 +- .../SupplierPartParametricTable.tsx | 5 +- .../tables/purchasing/SupplierPartTable.tsx | 39 +- .../purchasing/SupplierPriceBreakTable.tsx | 4 +- .../src/tables/sales/ReturnOrderFilters.tsx | 6 +- .../tables/sales/ReturnOrderLineItemTable.tsx | 71 +- .../sales/ReturnOrderParametricTable.tsx | 2 +- .../src/tables/sales/ReturnOrderTable.tsx | 12 +- .../sales/SalesOrderAllocationTable.tsx | 49 +- .../src/tables/sales/SalesOrderFilters.tsx | 6 +- .../tables/sales/SalesOrderLineItemTable.tsx | 133 +- .../sales/SalesOrderParametricTable.tsx | 2 +- .../tables/sales/SalesOrderShipmentTable.tsx | 31 +- .../src/tables/sales/SalesOrderTable.tsx | 12 +- .../src/tables/settings/ApiTokenTable.tsx | 9 +- .../src/tables/settings/AssetTable.tsx | 124 + .../settings/BarcodeScanHistoryTable.tsx | 39 +- .../src/tables/settings/CustomStateTable.tsx | 2 +- .../src/tables/settings/CustomUnitsTable.tsx | 2 +- .../src/tables/settings/EmailTable.tsx | 4 +- .../src/tables/settings/ErrorTable.tsx | 2 +- .../tables/settings/ExportSessionTable.tsx | 6 +- .../src/tables/settings/FailedTasksTable.tsx | 2 +- .../src/tables/settings/GroupTable.tsx | 5 +- .../tables/settings/ImportSessionTable.tsx | 37 +- .../src/tables/settings/PendingTasksTable.tsx | 2 +- .../src/tables/settings/ProjectCodeTable.tsx | 24 +- .../tables/settings/ScheduledTasksTable.tsx | 2 +- .../tables/settings/SelectionListDrawer.tsx | 217 + .../{part => settings}/SelectionListTable.tsx | 42 +- .../src/tables/settings/SnippetTable.tsx | 239 + .../src/tables/settings/TemplateTable.tsx | 38 +- .../src/tables/settings/UserTable.tsx | 7 +- .../src/tables/stock/InstalledItemsTable.tsx | 10 +- .../src/tables/stock/LocationTypesTable.tsx | 4 +- .../src/tables/stock/StockItemTable.tsx | 102 +- .../tables/stock/StockItemTestResultTable.tsx | 52 +- .../stock/StockLocationParametricTable.tsx | 2 +- .../src/tables/stock/StockLocationTable.tsx | 8 +- .../src/tables/stock/StockTrackingTable.tsx | 6 +- .../stock/TransferOrderAllocationTable.tsx | 22 +- .../src/tables/stock/TransferOrderFilters.tsx | 79 + .../stock/TransferOrderLineItemTable.tsx | 38 +- .../stock/TransferOrderParametricTable.tsx | 7 +- .../src/tables/stock/TransferOrderTable.tsx | 73 +- src/frontend/src/views/MainView.tsx | 42 +- src/frontend/tests/baseFixtures.ts | 94 +- .../tests/customization/customization.spec.ts | 9 +- src/frontend/tests/defaults.ts | 5 + src/frontend/tests/helpers.ts | 20 + src/frontend/tests/pages/pui_build.spec.ts | 146 +- src/frontend/tests/pages/pui_company.spec.ts | 52 +- .../tests/pages/pui_dashboard.spec.ts | 2 - src/frontend/tests/pages/pui_part.spec.ts | 198 +- .../tests/pages/pui_purchasing.spec.ts | 77 +- src/frontend/tests/pages/pui_return.spec.ts | 7 +- src/frontend/tests/pages/pui_sales.spec.ts | 59 + src/frontend/tests/pages/pui_scan.spec.ts | 1 + src/frontend/tests/pages/pui_stock.spec.ts | 311 +- src/frontend/tests/pages/pui_transfer.spec.ts | 223 + src/frontend/tests/pui_exporting.spec.ts | 13 +- src/frontend/tests/pui_forms.spec.ts | 238 +- src/frontend/tests/pui_importing.spec.ts | 2 +- src/frontend/tests/pui_login.spec.ts | 369 +- src/frontend/tests/pui_machines.spec.ts | 2 +- src/frontend/tests/pui_permissions.spec.ts | 18 +- src/frontend/tests/pui_plugins.spec.ts | 65 +- src/frontend/tests/pui_printing.spec.ts | 90 +- src/frontend/tests/pui_settings.spec.ts | 145 +- src/frontend/tests/pui_tables.spec.ts | 219 + src/frontend/tsconfig.json | 4 +- src/frontend/vite.config.ts | 5 +- src/frontend/vite.lib.config.ts | 6 +- src/frontend/yarn.lock | 3310 ++--- tasks.py | 209 +- 719 files changed, 344813 insertions(+), 256901 deletions(-) delete mode 100644 .devops/test_stats.yml create mode 100644 .github/workflows/frontend.yaml create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 docs/docs/assets/images/concepts/ui_preview_details_link.png create mode 100644 docs/docs/assets/images/concepts/ui_preview_drawer.png create mode 100644 docs/docs/assets/images/concepts/ui_table_column_filter_popover.png create mode 100644 docs/docs/assets/images/concepts/ui_table_filter_group.png create mode 100644 docs/docs/concepts/tags.md create mode 100644 docs/docs/concepts/ui/forms.md create mode 100644 docs/docs/concepts/ui/global_search.md create mode 100644 docs/docs/concepts/ui/index.md create mode 100644 docs/docs/concepts/ui/preview_panels.md create mode 100644 docs/docs/concepts/ui/tables.md create mode 100644 docs/docs/part/consumable.md rename docs/docs/project/{resources.md => sponsored_resources.md} (83%) create mode 100644 docs/docs/report/assets.md create mode 100644 docs/docs/report/model_context.md create mode 100644 docs/docs/report/snippets.md create mode 100644 docs/docs/settings/db_admin.md create mode 100644 docs/docs/stock/disassemble.md create mode 100644 src/backend/InvenTree/InvenTree/helpers_db.py create mode 100644 src/backend/InvenTree/InvenTree/test_helpers/__init__.py create mode 100644 src/backend/InvenTree/InvenTree/test_helpers/sample_tasks.py create mode 100644 src/backend/InvenTree/InvenTree/test_helpers_db.py create mode 100644 src/backend/InvenTree/build/migrations/0059_build_tags.py create mode 100644 src/backend/InvenTree/common/migrations/0044_notificationmessage_charfield_pk.py create mode 100644 src/backend/InvenTree/common/migrations/0045_projectcode_active.py create mode 100644 src/backend/InvenTree/common/migrations/0046_alter_emailmessage_global_id_and_more.py create mode 100644 src/backend/InvenTree/common/migrations/0047_parametertemplate_unique.py create mode 100644 src/backend/InvenTree/common/migrations/0048_notificationmessage_link.py create mode 100644 src/backend/InvenTree/common/migrations/0049_notificationentry_charfield_uid.py create mode 100644 src/backend/InvenTree/company/migrations/0080_company_tags.py create mode 100644 src/backend/InvenTree/generic/states/deprecations.py create mode 100644 src/backend/InvenTree/importer/migrations/0006_dataimportcolumnmap_lookup_field.py create mode 100644 src/backend/InvenTree/importer/migrations/0007_dataimportsession_completed_row_count_history_and_more.py create mode 100644 src/backend/InvenTree/importer/migrations/0008_alter_dataimportrow_data_alter_dataimportrow_errors_and_more.py create mode 100644 src/backend/InvenTree/machine/migrations/0002_alter_machineconfig_id.py create mode 100644 src/backend/InvenTree/order/migrations/0120_purchaseorder_tags_returnorder_tags_salesorder_tags_and_more.py create mode 100644 src/backend/InvenTree/order/migrations/0121_add_line_item_discount.py create mode 100644 src/backend/InvenTree/part/migrations/0151_part_consumable.py create mode 100644 src/backend/InvenTree/part/migrations/0152_alter_partpricing_currency.py create mode 100644 src/backend/InvenTree/part/migrations/0153_bomitem_piece_count_bomitem_piece_size.py create mode 100644 src/backend/InvenTree/plugin/base/event/test_events.py create mode 100644 src/backend/InvenTree/report/fetcher.py create mode 100644 src/backend/InvenTree/stock/migrations/0120_stockitem_creation_date.py create mode 100644 src/backend/InvenTree/stock/migrations/0121_auto_20260526_0849.py create mode 100644 src/backend/InvenTree/stock/migrations/0122_alter_stockitem_creation_date.py create mode 100644 src/backend/InvenTree/stock/migrations/0123_remove_stockitem_review_needed.py create mode 100644 src/backend/InvenTree/stock/migrations/0124_alter_mptt_fields.py create mode 100644 src/backend/InvenTree/stock/migrations/0125_remove_mptt_fields.py create mode 100644 src/backend/InvenTree/stock/migrations/0126_serial_number_concurrency_guard.py create mode 100644 src/backend/InvenTree/stock/migrations/0127_alter_stockitemtestresult_options.py create mode 100644 src/frontend/lib/components/TagsList.tsx create mode 100644 src/frontend/lib/plugin/InventreeHmrPlugin.tsx create mode 100644 src/frontend/lib/plugin/LocalizedComponent.tsx create mode 100644 src/frontend/lib/types/Preview.tsx create mode 100644 src/frontend/src/components/details/ParameterDetailsGrid.tsx create mode 100644 src/frontend/src/components/forms/fields/TagsField.tsx create mode 100644 src/frontend/src/components/forms/fields/TreeField.tsx create mode 100644 src/frontend/src/components/items/PartCreationMenu.tsx create mode 100644 src/frontend/src/components/modals/HotkeyModal.tsx create mode 100644 src/frontend/src/components/nav/DetailNavigation.tsx create mode 100644 src/frontend/src/components/nav/PageDetailNavigationBar.tsx create mode 100644 src/frontend/src/components/previews/GlobalPreviewDrawer.tsx create mode 100644 src/frontend/src/components/previews/ModelPreviewShim.ts create mode 100644 src/frontend/src/components/previews/PreviewDrawer.tsx create mode 100644 src/frontend/src/components/previews/models/BuildOrderPreview.tsx create mode 100644 src/frontend/src/components/previews/models/CompanyPreview.tsx create mode 100644 src/frontend/src/components/previews/models/Fallback.tsx create mode 100644 src/frontend/src/components/previews/models/ManufacturerPartPreview.tsx create mode 100644 src/frontend/src/components/previews/models/PartCategoryPreview.tsx create mode 100644 src/frontend/src/components/previews/models/PartPreview.tsx create mode 100644 src/frontend/src/components/previews/models/PurchaseOrderPreview.tsx create mode 100644 src/frontend/src/components/previews/models/ReturnOrderPreview.tsx create mode 100644 src/frontend/src/components/previews/models/SalesOrderPreview.tsx create mode 100644 src/frontend/src/components/previews/models/SalesOrderShipmentPreview.tsx create mode 100644 src/frontend/src/components/previews/models/StockLocationPreview.tsx create mode 100644 src/frontend/src/components/previews/models/StockPreview.tsx create mode 100644 src/frontend/src/components/previews/models/SupplierPartPreview.tsx create mode 100644 src/frontend/src/components/previews/models/TransferOrderPreview.tsx create mode 100644 src/frontend/src/components/render/ModelHoverCard.tsx create mode 100644 src/frontend/src/components/render/ModelRenderShim.ts create mode 100644 src/frontend/src/components/tables/AppRowActions.tsx rename src/frontend/src/{ => components}/tables/ColumnRenderers.tsx (90%) rename src/frontend/src/{ => components}/tables/Filter.tsx (91%) create mode 100644 src/frontend/src/components/tables/FilterSelectDrawer.tsx rename src/frontend/src/{ => components}/tables/InvenTreeTable.tsx (72%) rename src/frontend/src/{ => components}/tables/InvenTreeTableHeader.tsx (88%) create mode 100644 src/frontend/src/components/tables/PartStockCell.tsx rename src/frontend/src/{ => components}/tables/RowExpansionIcon.tsx (100%) rename src/frontend/src/{ => components}/tables/TableHoverCard.tsx (91%) create mode 100644 src/frontend/src/forms/CommonFields.tsx delete mode 100644 src/frontend/src/forms/selectionListFields.tsx create mode 100644 src/frontend/src/functions/DetailNavigation.tsx create mode 100644 src/frontend/src/functions/comparison.tsx create mode 100644 src/frontend/src/functions/debug.tsx create mode 100644 src/frontend/src/functions/localeReady.ts create mode 100644 src/frontend/src/hooks/UseDetailNavigation.tsx create mode 100644 src/frontend/src/hooks/UseRemotePlugin.tsx create mode 100644 src/frontend/src/pages/build/BuildOrderDetailsPanel.tsx create mode 100644 src/frontend/src/pages/company/CompanyDetailsPanel.tsx create mode 100644 src/frontend/src/pages/company/ManufacturerPartDetailsPanel.tsx create mode 100644 src/frontend/src/pages/company/SupplierPartDetailsPanel.tsx create mode 100644 src/frontend/src/pages/part/PartCategoryDetailsPanel.tsx create mode 100644 src/frontend/src/pages/part/PartDetailsPanel.tsx create mode 100644 src/frontend/src/pages/purchasing/PurchaseOrderDetailsPanel.tsx create mode 100644 src/frontend/src/pages/sales/ReturnOrderDetailsPanel.tsx create mode 100644 src/frontend/src/pages/sales/SalesOrderDetailsPanel.tsx create mode 100644 src/frontend/src/pages/sales/SalesOrderShipmentDetailsPanel.tsx create mode 100644 src/frontend/src/pages/stock/StockDetailsPanel.tsx create mode 100644 src/frontend/src/pages/stock/StockLocationDetailsPanel.tsx create mode 100644 src/frontend/src/pages/stock/TransferOrderDetailsPanel.tsx create mode 100644 src/frontend/src/states/PreviewDrawerState.tsx create mode 100644 src/frontend/src/tables/part/PartSalesOrdersTable.tsx create mode 100644 src/frontend/src/tables/settings/AssetTable.tsx create mode 100644 src/frontend/src/tables/settings/SelectionListDrawer.tsx rename src/frontend/src/tables/{part => settings}/SelectionListTable.tsx (76%) create mode 100644 src/frontend/src/tables/settings/SnippetTable.tsx create mode 100644 src/frontend/src/tables/stock/TransferOrderFilters.tsx create mode 100644 src/frontend/tests/pages/pui_transfer.spec.ts diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2c7fd1a0a9..440b246f13 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,9 +1,7 @@ # Dockerfile for the InvenTree devcontainer +# This container is used for development of the InvenTree project, and includes all necessary dependencies for both backend and frontend development. -# In contrast with the "production" image (which is based on an Alpine image) -# we use a Debian-based image for the devcontainer - -FROM mcr.microsoft.com/devcontainers/python:3.11-bookworm@sha256:e754c29c4e3ffcf6c794c1020e36a0812341d88ec9569a34704b975fa89e8848 +FROM mcr.microsoft.com/devcontainers/python:3.12-trixie@sha256:5440cb68898d190ad6c6e8a4634ce89d0645bea47f9c8beb75612bb8e3983711 # InvenTree paths ENV INVENTREE_HOME="/home/inventree" @@ -25,10 +23,10 @@ RUN chmod +x init.sh # Install required base packages RUN apt update && apt install -y \ - python3.11-dev python3.11-venv \ + python3-dev python3-venv \ postgresql-client \ libldap2-dev libsasl2-dev \ - libpango1.0-0 libcairo2 \ + libpango-1.0-0 libcairo2 \ poppler-utils weasyprint # Install packages required for frontend development diff --git a/.devops/test_stats.yml b/.devops/test_stats.yml deleted file mode 100644 index a0bc7ed680..0000000000 --- a/.devops/test_stats.yml +++ /dev/null @@ -1,79 +0,0 @@ -trigger: - batch: true - branches: - include: - - master - - stable - - refs/tags/* - paths: - include: - - src/backend - -pool: - vmImage: ubuntu-latest -strategy: - matrix: - Python39: - PYTHON_VERSION: '3.11' - maxParallel: 3 - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - architecture: 'x64' - -- task: PythonScript@0 - displayName: 'Export project path' - inputs: - scriptSource: 'inline' - script: | - """Search all subdirectories for `manage.py`.""" - from glob import iglob - from os import path - # Python >= 3.5 - manage_py = next(iglob(path.join('**', 'manage.py'), recursive=True), None) - if not manage_py: - raise SystemExit('Could not find a Django project') - project_location = path.dirname(path.abspath(manage_py)) - print('Found Django project in', project_location) - print('##vso[task.setvariable variable=projectRoot]{}'.format(project_location)) - -- script: | - python -m pip install --upgrade pip setuptools wheel uv - uv pip install --require-hashes -r src/backend/requirements.txt - uv pip install --require-hashes -r src/backend/requirements-dev.txt - sudo apt-get install poppler-utils - sudo apt-get install libpoppler-dev - uv pip install unittest-xml-reporting coverage invoke - displayName: 'Install prerequisites' - env: - UV_SYSTEM_PYTHON: 1 - -- script: | - pushd '$(projectRoot)' - invoke update --uv - coverage run manage.py test --testrunner xmlrunner.extra.djangotestrunner.XMLTestRunner --no-input - coverage xml -i - displayName: 'Run tests' - env: - INVENTREE_DB_ENGINE: sqlite3 - INVENTREE_DB_NAME: inventree - INVENTREE_MEDIA_ROOT: ./media - INVENTREE_STATIC_ROOT: ./static - INVENTREE_BACKUP_DIR: ./backup - INVENTREE_SITE_URL: http://localhost:8000 - INVENTREE_PLUGINS_ENABLED: true - UV_SYSTEM_PYTHON: 1 - INVENTREE_DEBUG: true - INVENTREE_LOG_LEVEL: INFO - -- task: PublishTestResults@2 - inputs: - testResultsFiles: "**/TEST-*.xml" - testRunTitle: 'Python $(PYTHON_VERSION)' - condition: succeededOrFailed() - -- task: PublishCodeCoverageResults@2 - inputs: - summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml' diff --git a/.github/actions/setup/action.yaml b/.github/actions/setup/action.yaml index 3c7526de71..f3ffaebee8 100644 --- a/.github/actions/setup/action.yaml +++ b/.github/actions/setup/action.yaml @@ -39,14 +39,14 @@ runs: using: 'composite' steps: - name: Checkout Code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false # Python installs - name: Set up Python ${{ env.python_version }} if: ${{ inputs.python == 'true' && env.python_version != '3.14' }} - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # pin@v5.0.0 + uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 with: python-version: ${{ env.python_version }} cache: pip @@ -57,7 +57,7 @@ runs: contrib/dev_reqs/requirements.txt - name: Setup Python 3.14 if: ${{ inputs.python == 'true' && env.python_version == '3.14' }} - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # pin@v5.0.0 + uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 with: python-version: ${{ env.python_version }} - name: Install Base Python Dependencies @@ -106,7 +106,7 @@ runs: - name: Run invoke update if: ${{ inputs.update == 'true' }} shell: bash - run: invoke update --skip-backup --skip-static + run: invoke update --skip-backup --skip-static --no-frontend - name: Collect static files if: ${{ inputs.static == 'true' }} shell: bash diff --git a/.github/workflows/backport.yaml b/.github/workflows/backport.yaml index 7ac4bb2d1b..1a8a77502c 100644 --- a/.github/workflows/backport.yaml +++ b/.github/workflows/backport.yaml @@ -25,7 +25,7 @@ jobs: ) steps: - name: Backport Action - uses: sqren/backport-github-action@ad888e978060bc1b2798690dd9d03c4036560947 # pin@v9.2.2 + uses: sorenlouv/backport-github-action@8a6c0381851f43f9f1fddc7303f0e9015eb57b62 # v12.0.4 with: github_token: ${{ secrets.GITHUB_TOKEN }} auto_backport_label_prefix: backport-to- diff --git a/.github/workflows/check_translations.yaml b/.github/workflows/check_translations.yaml index 5fabe38106..44381efddf 100644 --- a/.github/workflows/check_translations.yaml +++ b/.github/workflows/check_translations.yaml @@ -9,7 +9,7 @@ on: - l10 env: - python_version: 3.11 + python_version: 3.12 permissions: contents: read @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -46,4 +46,6 @@ jobs: run: | python ./.github/scripts/check_source_strings.py --frontend --backend - name: Check Migration Files - run: python3 .github/scripts/check_migration_files.py + run: | + invoke migrate --detect + python3 .github/scripts/check_migration_files.py diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index db8dcd6785..678d924ff0 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -39,10 +39,10 @@ jobs: docker: ${{ steps.filter.outputs.docker }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # pin@v4.0.1 + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter with: filters: | @@ -62,12 +62,12 @@ jobs: contents: read env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - python_version: "3.11" + python_version: 3.12 runs-on: ubuntu-latest # in the future we can try to use alternative runners here steps: - name: Check out repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Test Docker Image @@ -84,6 +84,19 @@ jobs: docker run --rm inventree-test test -f /home/inventree/gunicorn.conf.py docker run --rm inventree-test test -f /home/inventree/src/backend/requirements.txt docker run --rm inventree-test test -f /home/inventree/src/backend/InvenTree/manage.py + # Check that license information was generated into the image + docker run --rm inventree-test test -s /home/inventree/src/backend/InvenTree/InvenTree/licenses.txt + docker run --rm inventree-test test -s /home/inventree/src/backend/InvenTree/web/static/web/.vite/dependencies.json + # Check that backend translations were compiled into the image (a few representative languages) + docker run --rm inventree-test test -f /home/inventree/src/backend/InvenTree/locale/de/LC_MESSAGES/django.mo + docker run --rm inventree-test test -f /home/inventree/src/backend/InvenTree/locale/fr/LC_MESSAGES/django.mo + docker run --rm inventree-test test -f /home/inventree/src/backend/InvenTree/locale/ru/LC_MESSAGES/django.mo + docker run --rm inventree-test test -f /home/inventree/src/backend/InvenTree/locale/zh_Hans/LC_MESSAGES/django.mo + # Check that frontend translations (lingui) were compiled into the static build output (a few representative languages) + docker run --rm inventree-test grep -q '"src/locales/de/messages.ts"' /home/inventree/src/backend/InvenTree/web/static/web/.vite/manifest.json + docker run --rm inventree-test grep -q '"src/locales/fr/messages.ts"' /home/inventree/src/backend/InvenTree/web/static/web/.vite/manifest.json + docker run --rm inventree-test grep -q '"src/locales/ru/messages.ts"' /home/inventree/src/backend/InvenTree/web/static/web/.vite/manifest.json + docker run --rm inventree-test grep -q '"src/locales/zh_Hans/messages.ts"' /home/inventree/src/backend/InvenTree/web/static/web/.vite/manifest.json - name: Build Docker Image # Build the development docker image (using docker-compose.yml) run: docker compose --project-directory . -f contrib/container/dev-docker-compose.yml build --no-cache @@ -124,12 +137,12 @@ jobs: contents: read env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - python_version: "3.11" + python_version: 3.12 runs-on: ubuntu-latest # in the future we can try to use alternative runners here steps: - name: Check out repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Run Migration Tests @@ -148,16 +161,16 @@ jobs: id-token: write env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - python_version: "3.11" + python_version: 3.12 runs-on: ubuntu-latest # in the future we can try to use alternative runners here steps: - name: Check out repo - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set Up Python ${{ env.python_version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # pin@v6.2.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ env.python_version }} - name: Version Check @@ -168,13 +181,13 @@ jobs: echo "git_commit_date=$(git show -s --format=%ci)" >> $GITHUB_ENV - name: Set up QEMU if: github.event_name != 'pull_request' - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # pin@v4.0.0 + uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0 - name: Set up Docker Buildx if: github.event_name != 'pull_request' - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # pin@v4.0.0 + uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 - name: Set up cosign if: github.event_name != 'pull_request' - uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # pin@v4.1.2 + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 - name: Check if Dockerhub login is required id: docker_login run: | @@ -185,14 +198,14 @@ jobs: fi - name: Login to Dockerhub if: github.event_name != 'pull_request' && steps.docker_login.outputs.skip_dockerhub_login != 'true' - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # pin@v4.1.0 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Log into registry ghcr.io if: github.event_name != 'pull_request' - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # pin@v4.1.0 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -201,16 +214,16 @@ jobs: - name: Extract Docker metadata if: github.event_name != 'pull_request' id: meta - uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # pin@v6.0.0 + uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 with: images: | inventree/inventree ghcr.io/${{ github.repository }} - - uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # pin@v1 + - uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1 - name: Push Docker Images id: push-docker if: github.event_name != 'pull_request' - uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # pin@v1 + uses: depot/build-push-action@98e78adca7817480b8185f474a400b451d74e287 # v1 with: project: jczzbjkk68 context: . diff --git a/.github/workflows/frontend.yaml b/.github/workflows/frontend.yaml new file mode 100644 index 0000000000..b869ec0954 --- /dev/null +++ b/.github/workflows/frontend.yaml @@ -0,0 +1,312 @@ +# Playwright testing for frontend code +# Runs the following tests: +# - Playwright tests in Firefox (against compiled frontend code) +# - Playwright tests in Chromium (coverage enabled, against vite frontend code) +# - Build frontend code and upload as artifact + +name: Frontend + +on: + push: + branches-ignore: ["l10*", "dependabot/**", "backport/**"] + pull_request: + branches-ignore: ["l10*"] + +env: + python_version: 3.12 + node_version: 24 + plugin_creator_version: 1.20.0 + # The OS version must be set per job + server_start_sleep: 60 + + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + INVENTREE_DB_ENGINE: postgresql + INVENTREE_DB_NAME: inventree + INVENTREE_DB_HOST: "127.0.0.1" + INVENTREE_DB_PORT: 5432 + INVENTREE_DB_USER: inventree_user + INVENTREE_DB_PASSWORD: inventree_password + INVENTREE_DEBUG: true + INVENTREE_PLUGINS_ENABLED: false + INVENTREE_MEDIA_ROOT: /home/runner/work/InvenTree/test_inventree_media + INVENTREE_STATIC_ROOT: /home/runner/work/InvenTree/test_inventree_static + INVENTREE_BACKUP_DIR: /home/runner/work/InvenTree/test_inventree_backup + INVENTREE_SITE_URL: http://localhost:8000 + +permissions: + contents: read + +jobs: + paths-filter: + name: Filter + runs-on: ubuntu-latest + + outputs: + frontend: ${{ steps.filter.outputs.frontend }} + force: ${{ steps.force.outputs.force }} + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 + id: filter + with: + filters: | + frontend: + - 'src/frontend/**' + - name: Is CI being forced? + run: echo "force=true" >> $GITHUB_OUTPUT + id: force + if: | + contains(github.event.pull_request.labels.*.name, 'dependency') || + contains(github.event.pull_request.labels.*.name, 'full-run') + + + build: + name: Build + runs-on: ubuntu-24.04 + timeout-minutes: 60 + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Environment Setup + uses: ./.github/actions/setup + with: + npm: true + - name: Install dependencies + run: cd src/frontend && yarn install + - name: Build frontend + run: cd src/frontend && yarn run compile && yarn run lib && yarn run build + - name: Write version file - SHA + run: cd src/backend/InvenTree/web/static/web/.vite && echo "$GITHUB_SHA" > sha.txt + - name: Zip frontend + run: | + cd src/backend/InvenTree/web/static + zip -r frontend-build.zip web/ web/.vite + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: frontend-build + path: src/backend/InvenTree/web/static/web + include-hidden-files: true + + firefox: + name: Tests [Firefox ${{ matrix.shard }} / 2] + runs-on: ubuntu-24.04 + timeout-minutes: 60 + needs: ["build", "paths-filter"] + if: github.ref == 'refs/heads/master' || needs.paths-filter.outputs.frontend == 'true' || needs.paths-filter.outputs.force == 'true' + strategy: + fail-fast: false + matrix: + shard: [1, 2] + services: + postgres: + image: postgres:17 + env: + POSTGRES_DB: inventree + POSTGRES_USER: inventree_user + POSTGRES_PASSWORD: inventree_password + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U testuser" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + permissions: + contents: read # Required for actions/checkout + id-token: write # Required for GitHub OIDC + env: + VITE_COVERAGE: false + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Environment Setup + uses: ./.github/actions/setup + with: + npm: true + install: true + update: true + apt-dependency: gettext postgresql-client libpq-dev + pip-dependency: psycopg2 + - name: Set up test data + run: | + invoke dev.setup-test -iv + invoke int.rebuild-thumbnails + - name: Install dependencies + run: invoke int.frontend-compile --extract + - name: Cache Playwright browsers + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + id: playwright-cache + with: + path: ~/.cache/ms-playwright + key: ${{ runner.os }}-playwright-${{ hashFiles('src/frontend/yarn.lock') }} + - name: Install Playwright browsers + if: steps.playwright-cache.outputs.cache-hit != 'true' + run: cd src/frontend && npx playwright install --with-deps + - name: Install Playwright OS dependencies + if: steps.playwright-cache.outputs.cache-hit == 'true' + run: cd src/frontend && npx playwright install-deps + - name: Install Sample Plugin + run: | + pip install -U inventree-plugin-creator==${{ env.plugin_creator_version }} + create-inventree-plugin --default + cd MyCustomPlugin && pip install -e . && cd frontend && npm install && npm run translate && npm run build + - name: Run Playwright tests + id: tests + run: | + cd src/frontend + cp ./tests/fixtures/playwright_custom_logo.png ../backend/InvenTree/InvenTree/static/img/playwright_custom_logo.png + cp ./tests/fixtures/playwright_custom_splash.png ../backend/InvenTree/InvenTree/static/img/playwright_custom_splash.png + invoke static + env INVENTREE_CUSTOM_SPLASH="img/playwright_custom_splash.png" INVENTREE_CUSTOM_LOGO="img/playwright_custom_logo.png" PLAYWRIGHT_BASE_URL=http://localhost:8000 npx playwright test --project=firefox --shard=${{ matrix.shard }}/2 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + if: ${{ !cancelled() && steps.tests.outcome == 'failure' }} + with: + name: playwright-report-firefox-${{ matrix.shard }} + path: src/frontend/playwright-report/ + retention-days: 14 + + chromium: + name: Tests [Chromium ${{ matrix.shard }} / 4] + runs-on: ubuntu-24.04 + timeout-minutes: 60 + needs: ["build", "paths-filter"] + if: github.ref == 'refs/heads/master' || needs.paths-filter.outputs.frontend == 'true' || needs.paths-filter.outputs.force == 'true' + strategy: + fail-fast: false + matrix: + shard: [1, 2, 3, 4] + services: + postgres: + image: postgres:17 + env: + POSTGRES_DB: inventree + POSTGRES_USER: inventree_user + POSTGRES_PASSWORD: inventree_password + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U testuser" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + permissions: + contents: read # Required for actions/checkout + id-token: write # Required for GitHub OIDC + + env: + COVERAGE: true + VITE_COVERAGE: true + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Environment Setup + uses: ./.github/actions/setup + with: + npm: true + install: true + update: true + apt-dependency: gettext postgresql-client libpq-dev + pip-dependency: psycopg2 + - name: Set up test data + run: | + invoke dev.setup-test -iv + invoke int.rebuild-thumbnails + - name: Install dependencies + run: invoke int.frontend-compile --extract + - name: Cache Playwright browsers + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + id: playwright-cache + with: + path: ~/.cache/ms-playwright + key: ${{ runner.os }}-playwright-${{ hashFiles('src/frontend/yarn.lock') }} + - name: Install Playwright browsers + if: steps.playwright-cache.outputs.cache-hit != 'true' + run: cd src/frontend && npx playwright install --with-deps + - name: Install Playwright OS dependencies + if: steps.playwright-cache.outputs.cache-hit == 'true' + run: cd src/frontend && npx playwright install-deps + - name: Install Sample Plugin + run: | + pip install -U inventree-plugin-creator==${{ env.plugin_creator_version }} + create-inventree-plugin --default + cd MyCustomPlugin && pip install -e . && cd frontend && npm install && npm run translate && npm run build + - name: Playwright [${{ matrix.shard }} / 4] + id: tests + run: | + cd src/frontend + npx nyc playwright test --project=chromium --shard=${{ matrix.shard }}/4 + - name: Playwright Report [${{ matrix.shard }} / 4] + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + if: ${{ !cancelled() && steps.tests.outcome == 'failure' }} + with: + name: playwright-report-chromium-${{ matrix.shard }} + path: src/frontend/playwright-report/ + if-no-files-found: error + retention-days: 7 + - name: Upload Coverage Artifact [${{ matrix.shard }} / 4] + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + id: coverage-upload + if: ${{ !cancelled() && steps.tests.outcome != 'failure' }} + with: + name: coverage-${{ matrix.shard }} + path: src/frontend/.nyc_output/ + if-no-files-found: error + include-hidden-files: true + retention-days: 1 + + # Recombine the coverage reports from the 4 shards, and upload to Codecov + coverage: + name: Merge coverage reports and upload to Codecov + runs-on: ubuntu-latest + needs: chromium + timeout-minutes: 30 + if: always() + + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Environment Setup + uses: ./.github/actions/setup + with: + npm: true + install: false + update: false + + - name: Download Coverage Artifacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + pattern: coverage-* + path: all-coverage/ + merge-multiple: true + + - name: Merge Coverage Reports + run: | + mkdir -p .nyc_output + cp all-coverage/*.json .nyc_output/ 2>/dev/null || true + npx nyc merge .nyc_output merged-coverage.json + npx nyc report \ + --tempdir .nyc_output \ + --reporter=lcov \ + --reporter=text-summary \ + --report-dir ./coverage \ + + - name: Upload coverage reports to Codecov + if: ${{ !cancelled() && github.ref == 'refs/heads/master' }} + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: inventree/InvenTree + flags: web + files: ./coverage/lcov.info diff --git a/.github/workflows/import_export.yaml b/.github/workflows/import_export.yaml index 6cf00b0408..18dfb0dc88 100644 --- a/.github/workflows/import_export.yaml +++ b/.github/workflows/import_export.yaml @@ -7,7 +7,7 @@ name: Import / Export on: push: - branches-ignore: ["l10*"] + branches-ignore: ["l10*", "dependabot/**", "backport/**"] pull_request: branches-ignore: ["l10*"] @@ -15,7 +15,7 @@ permissions: contents: read env: - python_version: 3.11 + python_version: 3.12 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -48,10 +48,10 @@ jobs: outputs: server: ${{ steps.filter.outputs.server }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # pin@v4.0.1 + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter with: filters: | @@ -76,7 +76,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/qc_checks.yaml b/.github/workflows/qc_checks.yaml index b877b5aff4..df60dc289f 100644 --- a/.github/workflows/qc_checks.yaml +++ b/.github/workflows/qc_checks.yaml @@ -4,12 +4,12 @@ name: QC on: push: - branches-ignore: ["l10*"] + branches-ignore: ["l10*", "dependabot/**", "backport/**"] pull_request: branches-ignore: ["l10*"] env: - python_version: 3.11 + python_version: 3.12 node_version: 24 # The OS version must be set per job server_start_sleep: 60 @@ -44,10 +44,10 @@ jobs: submit-performance: ${{ steps.runner-perf.outputs.submit-performance }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # pin@v4.0.1 + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter with: filters: | @@ -108,16 +108,16 @@ jobs: if: needs.paths-filter.outputs.cicd == 'true' || needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.frontend == 'true' || needs.paths-filter.outputs.requirements == 'true' || needs.paths-filter.outputs.force == 'true' steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Python ${{ env.python_version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # pin@v6.2.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ env.python_version }} cache: "pip" - name: Run pre commit hook Checks - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # pin@v2 + uses: j178/prek-action@4e14d07f9231acabce116ccfca13b13dd9755ece # v3.0.0 - name: Check Version run: | pip install --require-hashes -r contrib/dev_reqs/requirements.txt @@ -130,7 +130,7 @@ jobs: if: needs.paths-filter.outputs.server == 'true' || needs.paths-filter.outputs.requirements == 'true' || needs.paths-filter.outputs.force == 'true' steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -152,11 +152,11 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Python ${{ env.python_version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # pin@v6.2.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ env.python_version }} - name: Check Config @@ -165,7 +165,7 @@ jobs: pip install --require-hashes -r docs/requirements.txt python docs/ci/check_mkdocs_config.py - name: Check Links - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # pin@v1 + uses: tcort/github-action-markdown-link-check@e047c5b37f24ab722bbef1a27b6fab7f96bc4068 # v1 with: folder-path: docs config-file: docs/mlc_config.json @@ -190,7 +190,7 @@ jobs: version: ${{ steps.version.outputs.version }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -202,7 +202,7 @@ jobs: - name: Export API Documentation run: invoke dev.schema --ignore-warnings --filename src/backend/InvenTree/schema.yml - name: Upload schema - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: schema.yml path: src/backend/InvenTree/schema.yml @@ -222,7 +222,7 @@ jobs: echo "Downloaded api.yaml" - name: Running OpenAPI Spec diff action id: breaking_changes - uses: oasdiff/oasdiff-action/diff@6147a58e5d1249a12f42fc864ab791d571a30015 # pin@main + uses: oasdiff/oasdiff-action/diff@033c15c845bef10f148afb0fa781bf1b2a7fe1bf # v0.1.12 with: base: "api.yaml" revision: "src/backend/InvenTree/schema.yml" @@ -251,17 +251,17 @@ jobs: - name: Extract settings / tags run: invoke int.export-definitions --basedir docs - name: Upload settings - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: inventree_settings.json path: docs/generated/inventree_settings.json - name: Upload tags - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: inventree_tags.yml path: docs/generated/inventree_tags.yml - name: Upload filters - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: inventree_filters.yml path: docs/generated/inventree_filters.yml @@ -275,7 +275,7 @@ jobs: version: ${{ needs.schema.outputs.version }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 name: Checkout Code with: repository: inventree/schema @@ -284,7 +284,7 @@ jobs: - name: Create artifact directory run: mkdir -p artifact - name: Download schema artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # pin@v8.0.1 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: artifact merge-multiple: true @@ -301,7 +301,7 @@ jobs: echo "after move" ls -la artifact rm -rf artifact - - uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # pin@v7.1.0 + - uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0 name: Commit schema changes with: commit_message: "Update API schema for ${{ env.version }} / ${{ github.sha }}" @@ -332,7 +332,7 @@ jobs: node_version: '>=24' steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -363,7 +363,7 @@ jobs: pip install . if: needs.paths-filter.outputs.submit-performance == 'true' - name: Performance Reporting - uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # pin@v4.15.1 + uses: CodSpeedHQ/action@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3 # check if we are in inventree/inventree - reporting only works in that OIDC context if: github.repository == 'inventree/InvenTree' && needs.paths-filter.outputs.submit-performance == 'true' with: @@ -379,7 +379,7 @@ jobs: continue-on-error: true # continue if a step fails so that coverage gets pushed strategy: matrix: - python_version: [3.11, 3.14] + python_version: [3.12, 3.14] env: INVENTREE_DB_NAME: ./inventree.sqlite @@ -390,7 +390,7 @@ jobs: python_version: ${{ matrix.python_version }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -405,17 +405,19 @@ jobs: - name: Test Translations run: invoke dev.translate - name: Check Migration Files - run: python3 .github/scripts/check_migration_files.py + run: | + invoke migrate --detect + python3 .github/scripts/check_migration_files.py - name: Coverage Tests run: invoke dev.test --check --coverage --translations - name: Upload raw coverage to artifacts - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: coverage path: .coverage retention-days: 14 - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # pin@v6.0.0 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} @@ -441,7 +443,7 @@ jobs: INVENTREE_AUTO_UPDATE: true steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -454,7 +456,7 @@ jobs: env: node_version: '>=24' - name: Performance Reporting - uses: CodSpeedHQ/action@3194d9a39c4d46684cb44bf7207fc56626aad8fd # pin@v4.15.1 + uses: CodSpeedHQ/action@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3 with: mode: walltime run: inv dev.test --pytest @@ -492,7 +494,7 @@ jobs: - 6379:6379 steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -541,7 +543,7 @@ jobs: - 3306:3306 steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -584,7 +586,7 @@ jobs: - 5432:5432 steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -597,7 +599,7 @@ jobs: - name: Run Tests run: invoke dev.test --check --migrations --report --coverage --translations - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # pin@v6.0.0 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} @@ -618,7 +620,7 @@ jobs: INVENTREE_PLUGINS_ENABLED: false steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false name: Checkout Code @@ -664,118 +666,6 @@ jobs: chmod +rw /home/runner/work/InvenTree/db.sqlite3 invoke migrate - web_ui: - name: Tests - Web UI - runs-on: ubuntu-24.04 - timeout-minutes: 60 - needs: ["code-style", "paths-filter"] - if: needs.paths-filter.outputs.frontend == 'true' || needs.paths-filter.outputs.force == 'true' - services: - postgres: - image: postgres:17 - env: - POSTGRES_DB: inventree - POSTGRES_USER: inventree_user - POSTGRES_PASSWORD: inventree_password - ports: - - 5432:5432 - options: >- - --health-cmd "pg_isready -U testuser" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - env: - INVENTREE_DB_ENGINE: postgresql - INVENTREE_DB_NAME: inventree - INVENTREE_DB_HOST: "127.0.0.1" - INVENTREE_DB_PORT: 5432 - INVENTREE_DB_USER: inventree_user - INVENTREE_DB_PASSWORD: inventree_password - INVENTREE_DEBUG: true - INVENTREE_PLUGINS_ENABLED: false - VITE_COVERAGE_BUILD: true - - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 - with: - persist-credentials: false - - name: Environment Setup - uses: ./.github/actions/setup - with: - npm: true - install: true - update: true - apt-dependency: gettext postgresql-client libpq-dev - pip-dependency: psycopg2 - - name: Set up test data - run: | - invoke dev.setup-test -iv - invoke int.rebuild-thumbnails - - name: Install dependencies - run: | - invoke int.frontend-compile --extract - cd src/frontend && npx playwright install --with-deps - - name: Run Playwright tests - id: tests - run: | - cd src/frontend - cp ./tests/fixtures/playwright_custom_logo.png ../backend/InvenTree/InvenTree/static/img/playwright_custom_logo.png - cp ./tests/fixtures/playwright_custom_splash.png ../backend/InvenTree/InvenTree/static/img/playwright_custom_splash.png - invoke static - env INVENTREE_CUSTOM_SPLASH="img/playwright_custom_splash.png" INVENTREE_CUSTOM_LOGO="img/playwright_custom_logo.png" npx nyc playwright test --project=customization - npx nyc playwright test --project=chromium --project=firefox - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 - if: ${{ !cancelled() && steps.tests.outcome == 'failure' }} - with: - name: playwright-report - path: src/frontend/playwright-report/ - retention-days: 14 - - name: Report coverage - run: cd src/frontend && npx nyc report --report-dir ./coverage --temp-dir .nyc_output --reporter=lcov --exclude-after-remap false - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # pin@v6.0.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} - slug: inventree/InvenTree - flags: web - - name: Upload bundler info - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - run: | - cd src/frontend - yarn install - yarn run build - - web_ui_build: - name: Build - Web UI - runs-on: ubuntu-24.04 - timeout-minutes: 60 - - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 - with: - persist-credentials: false - - name: Environment Setup - uses: ./.github/actions/setup - with: - npm: true - - name: Install dependencies - run: cd src/frontend && yarn install - - name: Build frontend - run: cd src/frontend && yarn run compile && yarn run lib && yarn run build - - name: Write version file - SHA - run: cd src/backend/InvenTree/web/static/web/.vite && echo "$GITHUB_SHA" > sha.txt - - name: Zip frontend - run: | - cd src/backend/InvenTree/web/static - zip -r frontend-build.zip web/ web/.vite - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 - with: - name: frontend-build - path: src/backend/InvenTree/web/static/web - include-hidden-files: true - zizmor: name: Security [Zizmor] runs-on: ubuntu-24.04 @@ -786,8 +676,8 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Run zizmor 🌈 - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9cdf67065d..76394775f5 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ on: permissions: contents: read env: - python_version: 3.11 + python_version: 3.12 jobs: stable: @@ -20,7 +20,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout Code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Version Check @@ -28,7 +28,7 @@ jobs: pip install --require-hashes -r contrib/dev_reqs/requirements.txt python3 .github/scripts/version_check.py - name: Push to Stable Branch - uses: ad-m/github-push-action@4cc74773234f74829a8c21bc4d69dd4be9cfa599 # pin@v1.1.0 + uses: ad-m/github-push-action@881a6320fdb16eb5318c5054f31c218aec2b324c # v1.3.0 if: env.stable_release == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} @@ -42,8 +42,10 @@ jobs: id-token: write contents: write attestations: write + artifact-metadata: write + steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -55,7 +57,7 @@ jobs: - name: Build frontend run: cd src/frontend && npm run compile && npm run build - name: Create SBOM for frontend - uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # pin@v0 + uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0 with: artifact-name: frontend-build.spdx path: src/frontend @@ -73,7 +75,7 @@ jobs: zip -r ../frontend-build.zip * .vite - name: Attest Build Provenance id: attest - uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # pin@v1 + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 with: subject-path: "${{ github.workspace }}/src/backend/InvenTree/web/static/frontend-build.zip" @@ -83,15 +85,19 @@ jobs: REF: ${{ github.ref_name }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload frontend to artifacts - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7.0.1 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: frontend-build path: src/backend/InvenTree/web/static/frontend-build.zip + - name: Rename Attestation Bundle + run: | + mv ${BUNDLE_PATH} src/backend/InvenTree/web/static/frontend-build.intoto.jsonl + env: + BUNDLE_PATH: ${{ steps.attest.outputs.bundle-path}} - name: Upload Attestation - run: gh release upload ${REF} ${BUNDLE_PATH}#frontend-build.intoto.jsonl + run: gh release upload ${REF} src/backend/InvenTree/web/static/frontend-build.intoto.jsonl#frontend-build.intoto.jsonl env: REF: ${{ github.ref_name }} - BUNDLE_PATH: ${{ steps.attest.outputs.bundle-path}} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} docs: @@ -109,7 +115,7 @@ jobs: INVENTREE_DEBUG: true steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -145,17 +151,17 @@ jobs: fail-fast: false matrix: target: - - ubuntu:22.04 - ubuntu:24.04 - - debian:12 + - ubuntu:26.04 + - debian:13 + steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false - - name: Get frontend artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # pin@v8.0.1 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: frontend-build - name: Setup @@ -209,8 +215,14 @@ jobs: echo "calculate release channel" pip install --require-hashes -r contrib/dev_reqs/requirements.txt python3 .github/scripts/version_check.py - - name: Package - uses: pkgr/action/package@c5666febcd31750da6428042193fc5b2fb765435 # pin@main + - name: cleanup + run: | + # remove .map files from static build - these are only needed for debug + find src/backend/InvenTree/web/static/web -name "*.map" -type f -delete + # remove the whole docs dir - we are not doing anything with them + rm -rf docs + - name: Package - current release channel + uses: pkgr/action/package@c5666febcd31750da6428042193fc5b2fb765435 # main id: package with: target: ${{ matrix.target }} @@ -227,8 +239,8 @@ jobs: INVENTREE_PLUGIN_FILE=/opt/inventree/plugins.txt INVENTREE_CONFIG_FILE=/opt/inventree/config.yaml APP_REPO=inventree/InvenTree - - name: Publish to go.packager.io - uses: pkgr/action/publish@3bce081ae512c5020856e237d37b3f5479d4aa71 # pin@main + - name: Publish to go.packager.io - current release channel + uses: pkgr/action/publish@c5666febcd31750da6428042193fc5b2fb765435 # main with: target: ${{ matrix.target }} token: ${{ secrets.PACKAGER_RELEASE_TOKEN }} @@ -240,5 +252,31 @@ jobs: env: REF: ${{ github.ref_name }} PACKAGE_PATH: ${{ steps.package.outputs.package_path }} - PACKAGE_NAME: ${{ matrix.target }}-{{ steps.setup.outputs.version }}.tar.gz + PACKAGE_NAME: ${{ matrix.target }}-${{ steps.setup.outputs.version }}.tar.gz GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Package - stable release channel + uses: pkgr/action/package@c5666febcd31750da6428042193fc5b2fb765435 # main + id: package-stable + with: + target: ${{ matrix.target }} + version: ${{ steps.setup.outputs.version }} + debug: true + cache_prefix: ${{ github.ref_name }} + env: | + INVENTREE_DB_ENGINE=sqlite3 + INVENTREE_DB_NAME=database.sqlite3 + INVENTREE_PLUGINS_ENABLED=true + INVENTREE_MEDIA_ROOT=/opt/inventree/media + INVENTREE_STATIC_ROOT=/opt/inventree/static + INVENTREE_BACKUP_DIR=/opt/inventree/backup + INVENTREE_PLUGIN_FILE=/opt/inventree/plugins.txt + INVENTREE_CONFIG_FILE=/opt/inventree/config.yaml + APP_REPO=inventree/InvenTree + - name: Publish to go.packager.io - stable release channel + uses: pkgr/action/publish@c5666febcd31750da6428042193fc5b2fb765435 # main + with: + target: ${{ matrix.target }} + token: ${{ secrets.PACKAGER_RELEASE_TOKEN }} + repository: inventree/InvenTree + channel: stable + file: ${{ steps.package-stable.outputs.package_path }} diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 4d2d571f31..9bfe9496ec 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -32,12 +32,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4 with: results_file: results.sarif results_format: sarif @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: sarif_file: results.sarif diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index fc770c386e..958ab2c42d 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -16,7 +16,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # pin@v10.2.0 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: "This issue seems stale. Please react to show this is still important." diff --git a/.github/workflows/translations.yaml b/.github/workflows/translations.yaml index d619040b90..a13210d7e7 100644 --- a/.github/workflows/translations.yaml +++ b/.github/workflows/translations.yaml @@ -6,7 +6,7 @@ on: - master env: - python_version: 3.11 + python_version: 3.12 node_version: 24 permissions: @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Environment Setup @@ -56,7 +56,7 @@ jobs: echo "Resetting to HEAD~" git reset HEAD~ || true - name: crowdin action - uses: crowdin/github-action@8868a33591d21088edfc398968173a3b98d51706 # pin@v2 + uses: crowdin/github-action@c7af9bc98b01694653031fef2a0dc6c7888ce9bc # v2 with: upload_sources: true upload_translations: false diff --git a/.github/workflows/update.yml.disabled b/.github/workflows/update.yml.disabled index 900596bb09..fd97125053 100644 --- a/.github/workflows/update.yml.disabled +++ b/.github/workflows/update.yml.disabled @@ -9,7 +9,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Setup @@ -18,7 +18,7 @@ jobs: run: pip-compile --output-file=requirements.txt requirements.in -U - name: Update requirements-dev.txt run: pip-compile --generate-hashes --output-file=requirements-dev.txt requirements-dev.in -U - - uses: stefanzweifel/git-auto-commit-action@fd157da78fa13d9383e5580d1fd1184d89554b51 # pin@v4.15.1 + - uses: stefanzweifel/git-auto-commit-action@fd157da78fa13d9383e5580d1fd1184d89554b51 # v4.15.1 with: commit_message: "[Bot] Updated dependency" branch: dep-update diff --git a/.gitignore b/.gitignore index b40ddc1f67..94afc63449 100644 --- a/.gitignore +++ b/.gitignore @@ -111,5 +111,6 @@ api.yaml src/backend/InvenTree/web/static InvenTree/web/static -# performance test results +# test results and logs +_tests*.txt .codspeed/ diff --git a/.pkgr.yml b/.pkgr.yml index ac9dc06408..4be9b08a36 100644 --- a/.pkgr.yml +++ b/.pkgr.yml @@ -21,9 +21,9 @@ before: dependencies: - curl - poppler-utils - - "python3.11 | python3.12 | python3.13 | python3.14" - - "python3.11-venv | python3.12-venv | python3.13-venv | python3.14-venv" - - "python3.11-dev | python3.12-dev | python3.13-dev | python3.14-dev" + - "python3.12 | python3.13 | python3.14" + - "python3.12-venv | python3.13-venv | python3.14-venv" + - "python3.12-dev | python3.13-dev | python3.14-dev" - python3-pip - python3-cffi - python3-brotli @@ -36,6 +36,6 @@ dependencies: - jq - "libffi7 | libffi8" targets: - ubuntu-22.04: true ubuntu-24.04: true - debian-12: true + ubuntu-26.04: true + debian-13: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b140056f45..bc7e618931 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: files: src/backend/requirements-dev\.(in|txt)$ - id: pip-compile name: pip-compile requirements-dev.in 3.14 - args: [src/backend/requirements-dev.in, -o, src/backend/requirements-dev-3.14.txt, -c, src/backend/requirements-3.14.txt, --python-version=3.14, -c, src/backend/requirements.txt] + args: [src/backend/requirements-dev.in, -o, src/backend/requirements-dev-3.14.txt, -c, src/backend/requirements-3.14.txt, --python-version=3.14, -c, src/backend/requirements.txt, -c, src/backend/requirements-dev.txt] files: src/backend/requirements-dev\.(in|txt)$ - id: pip-compile name: pip-compile requirements.txt @@ -97,4 +97,4 @@ repos: rev: 0.4.3 hooks: - id: teyit - language_version: python3.11 + language_version: python3.12 diff --git a/.vscode/launch.json b/.vscode/launch.json index 17186b6d37..6405c43bd5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -47,7 +47,7 @@ "name": "InvenTree invoke schema", "type": "debugpy", "request": "launch", - "program": "${workspaceFolder}/.venv/lib/python3.11/site-packages/invoke/__main__.py", + "program": "${workspaceFolder}/.venv/lib/python3.12/site-packages/invoke/__main__.py", "cwd": "${workspaceFolder}", "args": [ "dev.schema","--ignore-warnings" diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..90afc6d2bc --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,5 @@ +See [CONTRIBUTING.md](CONTRIBUTING.md) for codebase guidance. +Security reports must follow the security policy in [SECURITY.md](docs/docs/SECURITY.md) and provide how they interact with the [threat model](docs/docs/concepts/threat_model.md). + +Do not open a pull request without manual review by a human. Do not file AI generated issues under any circumstances. +Using AI generated content in issue/PR discussions might lead to code of conduct violations and/or bans. diff --git a/CHANGELOG.md b/CHANGELOG.md index b2a9bf5eb6..28ecbb109a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,6 @@ All major notable changes to this project will be documented in this file (start The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ## 2.0 - yyyy-mm-dd ### Breaking Changes - Remove deprecated features and APIs @@ -16,15 +15,68 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#11985](https://github.com/inventree/InvenTree/pull/11985) - removes legacy user endpoint fallback -## Unreleased - YYYY-MM-DD +## Unreleased - xxxx.xx.xx ### Breaking Changes -- [#9604](https://github.com/inventree/InvenTree/pull/9604) - refactors user API endpoint to be less ambiguous -- [#11893](https://github.com/inventree/InvenTree/pull/11893) bumps Node environment to version 24 LTS - this is only relevant if you build the frontend assets yourself +- [#12507](https://github.com/inventree/InvenTree/pull/12507) calling an invalid or repeated state transition now raises a ValidationError. Plugins implementing state transitions should evaluate the PR and adapt their usage of transitions to gain the new safeguards. ### Added +### Changed + +### Removed + +## 1.5.0 - 2026-08-11 + +### Breaking Changes + +- [#12529](https://github.com/inventree/InvenTree/pull/12529) removes related detail fields on API endpoints for which the user does not have view permissions. +- [#12360](https://github.com/inventree/InvenTree/pull/12360) removes the MPTT mixin from the StockItem model, and removes the self-referential tree structure from the database. This change was made to simplify the StockItem model and improve performance, as the MPTT tree structure was causing significant overhead in certain operations. Any external client applications which made use of the MPTT functionality will need to be updated to account for this change. +- [#12320](https://github.com/inventree/InvenTree/pull/12320) changes the default behavior of the `invoke migrate` command. Now, it no longer generates new migrations by default. Instead, it will only apply existing migrations to the database. If you want to detect and generate new migrations, you must now explicitly use the `--detect` flag. This change was made to prevent accidental generation of migrations when running the command, which could lead to unexpected changes in the database schema. Additionally, `invoke update` will no longer result in new migrations being generated, and will only apply existing migrations to the database. This change was made to ensure that the update process is predictable and does not introduce unexpected changes to the database schema. +- [#12223](https://github.com/inventree/InvenTree/pull/12223) removes support for python 3.11 and stops providing packages for Debian 11 and Ubuntu 20.04. + +### Added + +- [#12422](https://github.com/inventree/InvenTree/pull/12422) adds a "piece_count" field to the BomItem model, for representing cut-to-length parts. The total material required is calculated as `quantity x piece_count`. +- Adds configurable default for merging purchase order line items via the `PURCHASEORDER_MERGE_LINE_ITEMS` global setting +- [#12393](https://github.com/inventree/InvenTree/pull/12393) adds "discount" attribute to order line items, allowing users to specify a discount for each line item on an order. The discount can be specified as either a percentage or a fixed amount, and is applied to the line item total when calculating the order total. +- [#12391](https://github.com/inventree/InvenTree/pull/12391) adds facility for bulk deleting line items against orders +- [#12388](https://github.com/inventree/InvenTree/pull/12388) adds uniqueness requirements options for the Parameter and ParameterTemplate models. This allows users to specify whether a parameter value should be unique for a given model type, or globally unique across all models. +- [#12310](https://github.com/inventree/InvenTree/pull/12310) adds the ability to disassemble (or break apart) assembled stock items into their component parts, based on the Bill of Materials (BOM) associated with the stock item. This allows users to easily break down assembled items into their constituent parts, which can be useful for inventory management and tracking purposes. +- [#12117](https://github.com/inventree/InvenTree/pull/12117) adds a "preview" drawer to the InvenTree table component, allowing users to preview the details of a selected row without navigating away from the table view. This feature is optional and can be enabled or disabled via the `PREVIEW_DRAWER_ENABLED` system setting. +- [#12341](https://github.com/inventree/InvenTree/pull/12341) adds support for importing internal part prices. +- [#12295](https://github.com/inventree/InvenTree/pull/12295) adds "consumable" field to the Part model and API endpoints +- [#12250](https://github.com/inventree/InvenTree/pull/12250) adds "active" field to the ProjectCode model and API endpoints + +### Changed + +- [#12274](https://github.com/inventree/InvenTree/pull/12274) fixes a bug in rendering the "table field" component in frontend forms. Any plugins which make use of the "table field" component in their forms may be affected by this change, and will need to update their form definitions accordingly. + +### Removed + +## 1.4.0 - 2026-06-24 + +### Breaking Changes + +- [#12160](https://github.com/inventree/InvenTree/pull/12160) changes the way that remote URIs are loaded into the PDF report generator. Remote URIs (e.g. `http://` and `https://`) are now blocked by default, and can be enabled via the `REPORT_FETCH_URLS` system setting. This change was made to improve the security of the report generation process, as allowing remote URL fetching can potentially expose internal network services to SSRF attacks. Additionally, file URIs (e.g. `file://`) are now always blocked, and assets must be embedded as `data:` URIs before reaching the PDF generator. +- [#12107](https://github.com/inventree/InvenTree/pull/12107) makes a breaking change to the `SalesOrderStatusGroups` enum, fixing a bug where the "shipped" status was not included in the "active" group. This change may affect any external client applications which make use of the `SalesOrderStatusGroups` enum, as the "shipped" status will now be included in the "active" group instead of the "complete" group. If you are using this enum in an external client application, you will need to update your application to account for this change. +- [#9604](https://github.com/inventree/InvenTree/pull/9604) refactors user API endpoint to be less ambiguous +- [#11893](https://github.com/inventree/InvenTree/pull/11893) bumps Node environment to version 24 LTS - this is only relevant if you build the frontend assets yourself +- [#11951](https://github.com/inventree/InvenTree/pull/11951) adds API throtteling by default to make DoS attacks more difficult. This can be disabled by setting the `INVENTREE_THROTTLE_ANON` and `INVENTREE_THROTTLE_USER` settings to `None` (either via environment variable or config file). The default throttling rates are 20 requests per minute for anonymous users, and 20 requests per second for authenticated users. + +### Added + +- [#12208](https://github.com/inventree/InvenTree/pull/12208) adds custom locale support for rendering currencies, dates and numbers within reports. This allows users to specify a custom locale for report rendering, which can be used to control the formatting of dates, numbers and currency values in the generated reports. +- [#12204](https://github.com/inventree/InvenTree/pull/12204) adds new filtering options to PartCategoryTree and StockLocationTree API endpoints, allowing tree data to be fetched dynamically +- [#12165](https://github.com/inventree/InvenTree/pull/12165) adds support for parameters against the PartCategory model +- [#12103](https://github.com/inventree/InvenTree/pull/12103) adds column-based filtering to table views in the user interface. This extends the existing table filtering functionality by allowing users to apply filters directly to individual columns. +- [#12093](https://github.com/inventree/InvenTree/pull/12093) adds "read_only" attribute to PluginSetting API endpoint, which indicates whether a particular plugin setting is read-only (i.e. cannot be modified via the API) +- [#12079](https://github.com/inventree/InvenTree/pull/12079) adds the ability to save filter groups for table and calendar views in the user interface. This allows users to save and reuse commonly used filter configurations, improving the usability and efficiency of the interface. +- [#12077](https://github.com/inventree/InvenTree/pull/12077) adds "tags" fields to multiple new model types and a /api/tag/ endpoint for fetching tags. Also adds the ability to filter various model types by tags. +- [#12019](https://github.com/inventree/InvenTree/pull/12019) adds a "location" field to the StockCount API endpoint, allowing users to specify a location when performing a stock count. This field is optional, and if not provided, the stock count will be performed without changing the location of the stock item. If a location is provided, the stock item(s) will be moved to the specified location as part of the stock count operation. +- [#12011](https://github.com/inventree/InvenTree/pull/12011) adds a "creation_date" field to the StockItem API endpoint, allowing users to track when each stock item was created. This field is read-only and is automatically set to the current date and time when a new stock item is created. +- [#12000](https://github.com/inventree/InvenTree/pull/12000) adds support for auto-allocation of stock items against sales orders. This includes both backend and frontend changes, allowing users to trigger auto-allocation via the API or through the UI. The auto-allocation process will attempt to allocate available stock items to the sales order line items, based on the specified stock sorting and allocation rules. - [#11920](https://github.com/inventree/InvenTree/pull/11920) adds support for renaming attachments after they have been uploaded. This includes both backend and frontend changes, allowing users to rename attachments via the API or through the UI. - [#11914](https://github.com/inventree/InvenTree/pull/11914) adds a "maximum_stock" field to the Part model, allowing users to specify a maximum preferred stock level for each part. This is used in conjunction with the existing "minimum_stock" field to allow users to define a preferred stock range for each part. The "high_stock" filter has also been added to the Part API endpoint, allowing users to filter parts which are above their maximum stock level. - [#11631](https://github.com/inventree/InvenTree/pull/11631) adds "raw_amount" field to the BomItem model, allowing BOM quantities to account for the units of measure of the underlying part. @@ -39,12 +91,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- [#12197](https://github.com/inventree/InvenTree/pull/12197) requires staff permissions to restart machines via the API. +- [#12142](https://github.com/inventree/InvenTree/pull/12142) prevents users from printing reports or labels against models for which they do not have adequate permissions. This change improves the security of the system by ensuring that users cannot access or print reports or labels for models they do not have permission to view. - [#11990](https://github.com/inventree/InvenTree/pull/11990) build output operations performed via the API now offload the work to a background task, and now return a task ID which can be used to monitor the progress of the task. This allows for better performance and responsiveness when performing build output operations, as the work is performed asynchronously in the background. - [#11825](https://github.com/inventree/InvenTree/pull/11825) adds a new "bom" ruleset and associated permissions for BOM management, separate from the "part" ruleset which remains focused on part management. This allows for more granular control over user permissions, allowing users to have different levels of access to part management and BOM management functionality. - [#11816](https://github.com/inventree/InvenTree/pull/11816) makes the `issued_by` field on the `Build` API read only, and instead sets the `issued_by` field to the current user when a build is created. This change was made to ensure that the `issued_by` field accurately reflects the user who created the build, and to prevent users from setting this field to an arbitrary value when creating or updating a build. ### Removed +- [#12071](https://github.com/inventree/InvenTree/pull/12071) removes the "review_needed" field on the StockItem model. Note that this field was never exposed to the API or any business logic, and is essentially a no-op field which is not used for anything. This field was removed to simplify the StockItem model and reduce confusion around its purpose. - [#11962](https://github.com/inventree/InvenTree/pull/11962) removes the "remote_image" field from the Part API endpoint, which (previously) allowed the user to specify a remote URL for an image to be downloaded and associated with the part. This field was removed due to security concerns around downloading images from arbitrary URLs. If you were using this field in an external client application, you will need to update your application to use the new "download_image_from_url" API endpoint instead. ## 1.3.0 - 2026-04-11 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..90afc6d2bc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +See [CONTRIBUTING.md](CONTRIBUTING.md) for codebase guidance. +Security reports must follow the security policy in [SECURITY.md](docs/docs/SECURITY.md) and provide how they interact with the [threat model](docs/docs/concepts/threat_model.md). + +Do not open a pull request without manual review by a human. Do not file AI generated issues under any circumstances. +Using AI generated content in issue/PR discussions might lead to code of conduct violations and/or bans. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c589902e9b..e9115615dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,15 +1,28 @@ -### Contributing to InvenTree +# Contributing to InvenTree Hi there, thank you for your interest in contributing! Please read our contribution guidelines, before submitting your first pull request to the InvenTree codebase. -### Project File Structure +## About InvenTree + +InvenTree is an open-source inventory management system designed for makers, engineers, and small manufacturers. + +The codebase is split into two independently deployable layers: + +**Backend — Django (Python)** +A REST API built with Django and Django REST Framework. It owns all business logic, the database schema, background task processing (Django-Q2), plugin execution, and report generation. The backend can be used standalone via the API without the frontend. + +**Frontend — React (TypeScript)** +A single-page application built with React 19, Mantine 9, and Vite. It communicates exclusively through the backend REST API. It has its own build pipeline, test suite (Playwright), and i18n system (Lingui). The frontend lives entirely in `src/frontend/` and has no Django awareness. + +When making changes, be clear about which layer you are working in — they have separate toolchains, test runners, and linting rules. + +## Project File Structure The InvenTree project is split into two main components: frontend and backend. This source is located in the `src` directory. All other files are used for project management, documentation, and testing. -```bash +``` InvenTree/ -├─ .devops/ # Files for Azure DevOps ├─ .github/ # Files for GitHub │ ├─ actions/ # Reused actions │ ├─ ISSUE_TEMPLATE/ # Templates for issues and pull requests @@ -39,11 +52,209 @@ InvenTree/ │ │ ├─ tsconfig.json # Settings for frontend compilation ├─ .pkgr.yml # Build definition for Debian/Ubuntu packages ├─ .pre-commit-config.yaml # Code formatter/linter configuration +├─ biome.json # JS/TS linting and formatting config ├─ CONTRIBUTING.md # Contribution guidelines and overview ├─ Procfile # Process definition for Debian/Ubuntu packages +├─ pyproject.toml # Python tooling config (Ruff, pytest, coverage, djLint, ty) ├─ README.md # General project information and overview ├─ SECURITY.md # Project security policy ├─ tasks.py # Action definitions for development, testing and deployment ``` +### Backend app domains + +The following Django apps are defined in `src/backend/InvenTree/`: + +| Directory | Domain | +|-----------|--------| +| `build/` | Build (manufacturing/assembly) orders | +| `common/` | Shared models, settings, utilities | +| `company/` | Suppliers, customers, manufacturers | +| `data_exporter/` | Data export functionality | +| `generic/` | Shared enums, events, and state machine utilities | +| `importer/` | Data import functionality | +| `InvenTree/` | Core configuration (settings, URLs, middleware) | +| `machine/` | Support for external machines and devices | +| `order/` | Purchase orders and sales orders | +| `part/` | Parts catalogue and categories | +| `stock/` | Stock items and locations | +| `report/` | Report templates and generation | +| `plugin/` | Plugin system | +| `users/` | User accounts and permissions | +| `web/` | Serves the React frontend static build to Django | + +### Frontend layout + +``` +src/frontend/src/ + components/ # Reusable React components + pages/ # Page-level route components + tables/ # Data table components + forms/ # Form components + hooks/ # Custom React hooks + states/ # Zustand global state + locales/ # i18n translation catalogues (Lingui) +``` + +## Development Setup + +The project uses [Invoke](https://www.pyinvoketasks.com/) (`tasks.py`) as the task runner. + +```bash +# One-time setup: creates venv at dev/venv/, installs deps, sets up pre-commit hooks +invoke dev.setup-dev + +# Apply database migrations (and detect/create new migration files if required) +invoke migrate --detect + +# Create an admin account (required to log in) +invoke superuser + +# Terminal 1 — Django dev server (port 8000) +invoke dev.server + +# Terminal 2 — Vite dev server with HMR (port 5173) +invoke dev.frontend-server + +# Terminal 3 (optional) — Background task worker +invoke worker +``` + +A VS Code Dev Container configuration is available at `.devcontainer/` and includes PostgreSQL 15 and Redis 7 sidecar services. + +To see all available tasks, run `invoke --list`. + +## Running Backend Tests + +Always pass `--keepdb` to backend test commands. It reuses the existing test database instead of rebuilding it from scratch on every run, which is significantly faster. + +```bash +# All backend tests +invoke dev.test --keepdb + +# Specific test module +invoke dev.test --keepdb --runtest=company.test_api + +# With coverage +invoke dev.test --keepdb --coverage + +# Migration tests only (skip --keepdb here — migrations must run against a fresh DB) +invoke dev.test --migrations +``` + +## Running Frontend Tests + +Frontend tests use [Playwright](https://playwright.dev/) and target Chromium and Firefox. The test runner automatically starts the Vite dev server (port 5173), the Django backend (port 8000), and the background worker — no manual server startup is needed. + +```bash +# Open Playwright's interactive UI (recommended for local development) +invoke dev.frontend-test + +# Run tests in headless mode from the frontend directory +cd src/frontend && npx playwright test + +# Run a specific test file +cd src/frontend && npx playwright test tests/pui_login.spec.ts + +# Run tests in a specific browser only +cd src/frontend && npx playwright test --project=chromium +``` + +Test files live in `src/frontend/tests/` and follow the `pui_*.spec.ts` naming convention. + +Locally, tests run with a single worker (required for Vite HMR compatibility). In CI they run with multiple workers against a production build for speed. + +## Code Style and Linting + +All formatting and linting runs automatically on commit via pre-commit hooks. Never skip them. + +### Python (Backend) + +Tool: **Ruff** (replaces Black, isort, flake8, and others). + +```bash +ruff check src/backend/ # Lint +ruff format src/backend/ # Format +``` + +- Google-style docstrings enforced +- Enabled rule sets: A, B, C, D, F, I, N, SIM, PIE, PLE, PLW, RUF, UP, W +- Type checking: `ty` (configured in `pyproject.toml`) + +### Django Templates + +Tool: **djLint** + +```bash +djlint src/backend/ --check +``` + +### JavaScript / TypeScript (Frontend) + +Tool: **Biome** (replaces ESLint + Prettier). + +```bash +cd src/frontend +yarn biome check . # Lint + format check +yarn biome format . # Format only +``` + +- Single quotes, space indentation +- `noUnusedImports` is an error + +## Making Changes + +### Backend + +- Each Django app has its own `models.py`, `serializers.py`, `views.py`, `urls.py`, and `filters.py`. +- API endpoints use Django REST Framework; document them with drf-spectacular decorators. +- After changing models, create a migration: `invoke dev.makemigrations`. +- Tests live in `test_*.py` files within each app directory. +- Background tasks go through Django-Q2; define them in the app's `tasks.py`. + +### Frontend + +- Pages register themselves in `src/frontend/src/router.tsx`. +- Server state fetching uses TanStack Query (React Query); avoid raw `useEffect` for data fetching. +- Global UI state uses Zustand stores in `states/`. +- UI components come from Mantine 9.x; use the Mantine component library before writing custom CSS. +- Add i18n strings with Lingui (`t` macro / `Trans` component); run `invoke int.frontend-trans` to extract from source and compile. (`invoke dev.translate` is for the full translation pipeline and is not intended for local use.) +- Playwright tests live in `src/frontend/tests/`. + +### Dependencies + +**Python:** Add packages to `src/backend/requirements.in` (or `requirements-dev.in` for dev-only tools). The pre-commit hook runs `pip-compile` automatically on commit to regenerate `requirements.txt`. Never edit `requirements.txt` directly. + +**Frontend:** Add packages with `yarn add ` from `src/frontend/`. + +### Migrations + +- Never edit existing migration files; always generate new ones. +- Keep migrations reversible where possible. +- Migration tests run in CI under the tag `migration_test`. + +## CI / CD + +GitHub Actions workflows live in `.github/workflows/`. Key workflows: + +| Workflow | Purpose | +|----------|---------| +| `qc_checks.yaml` | Lint, type-check, backend tests, API schema | +| `frontend.yaml` | Playwright E2E tests, frontend build | +| `docker.yaml` | Docker image builds | +| `translations.yaml` | Crowdin i18n sync | + +CI uses path-based filtering — only affected jobs run per PR. Coverage tracked via Codecov; quality analysis via SonarCloud. + +## Key Conventions + +- **REST API versioning:** Endpoint changes must not break the published API schema. Run `invoke dev.schema` and check the diff before opening a PR. +- **Plugin safety:** The plugin system (`plugin/`) is a public extension point; avoid breaking its interfaces. +- **No hardcoded secrets:** gitleaks runs in pre-commit and CI — any credential-shaped string will block merges. +- **Database portability:** Code must work on PostgreSQL, MySQL/MariaDB, and SQLite. Avoid database-specific SQL or ORM features. +- **Frontend translations:** Every user-visible string must be wrapped in a Lingui `t` macro or `` component. +- **Test tagging:** Tag slow or special tests (`@tag('migration_test')`, `@tag('performance_test')`) so CI can filter them selectively. + +--- + Refer to our [contribution guidelines](https://docs.inventree.org/en/latest/develop/contributing/) for more information! diff --git a/README.md b/README.md index 7803cf8ec5..26afd2f362 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ [![Documentation Status](https://readthedocs.org/projects/inventree/badge/?version=latest)](https://inventree.readthedocs.io/en/latest/?badge=latest) ![Docker Build](https://github.com/inventree/inventree/actions/workflows/docker.yaml/badge.svg) [![Netlify Status](https://api.netlify.com/api/v1/badges/9bbb2101-0a4d-41e7-ad56-b63fb6053094/deploy-status)](https://app.netlify.com/sites/inventree/deploys) -[![Performance Testing](https://dev.azure.com/InvenTree/InvenTree%20test%20statistics/_apis/build/status%2Fmatmair.InvenTree?branchName=testing)](https://dev.azure.com/InvenTree/InvenTree%20test%20statistics/_build/latest?definitionId=3&branchName=testing) [![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/7179/badge)](https://bestpractices.coreinfrastructure.org/projects/7179) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/inventree/InvenTree/badge)](https://securityscorecards.dev/viewer/?uri=github.com/inventree/InvenTree) @@ -202,6 +201,7 @@ Find a full list of used third-party libraries in the license information dialog Deploys by Netlify Translation by Crowdin
CodSpeed Badge + Flakiness Badge

diff --git a/codecov.yml b/codecov.yml index b49179c3ed..35e93ceb04 100644 --- a/codecov.yml +++ b/codecov.yml @@ -24,7 +24,7 @@ flag_management: carryforward: true statuses: - type: project - target: 40% + target: 38% - name: web carryforward: true statuses: @@ -43,8 +43,10 @@ component_management: name: Backend Apps paths: - src/backend/InvenTree/build/** + - src/backend/InvenTree/common/** - src/backend/InvenTree/company/** - src/backend/InvenTree/data_exporter/** + - src/backend/InvenTree/generic/** - src/backend/InvenTree/importer/** - src/backend/InvenTree/machine/** - src/backend/InvenTree/order/** @@ -70,7 +72,8 @@ component_management: - component_id: web name: Frontend paths: - - src/frontend/** + - src/frontend/lib/** + - src/frontend/src/** statuses: - type: project target: 68% # 90% diff --git a/contrib/container/.env b/contrib/container/.env index 33ffc7e5ee..58bfbf4e97 100644 --- a/contrib/container/.env +++ b/contrib/container/.env @@ -9,11 +9,19 @@ COMPOSE_PROJECT_NAME=inventree INVENTREE_TAG=stable # InvenTree server URL - update this to match your server URL -INVENTREE_SITE_URL="http://inventree.localhost" -#INVENTREE_SITE_URL="http://192.168.1.2" # You can specify a local IP address here +# Local: http://localhost or http://inventree.localhost (requires hosts entry) +# LAN: http://192.168.133.37 +INVENTREE_SITE_URL="http://localhost" +#INVENTREE_SITE_URL="http://inventree.localhost" #INVENTREE_SITE_URL="https://inventree.my-domain.com" # Or a public domain name (which you control) + +# Port that the InvenTree server listens on *inside* the container - do not change unless you know what you are doing INVENTREE_WEB_PORT=8000 +# Ports that the proxy (Caddy) publishes on the *host* - change these to serve InvenTree on a non-standard port +#INVENTREE_HTTP_PORT=80 +#INVENTREE_HTTPS_PORT=443 + # InvenTree proxy forwarding settings INVENTREE_USE_X_FORWARDED_HOST=True INVENTREE_USE_X_FORWARDED_PORT=True @@ -34,10 +42,10 @@ INVENTREE_PLUGINS_ENABLED=True INVENTREE_AUTO_UPDATE=True # InvenTree superuser account details -# Un-comment (and complete) these lines to auto-create an admin account -#INVENTREE_ADMIN_USER= -#INVENTREE_ADMIN_PASSWORD= -#INVENTREE_ADMIN_EMAIL= +# Demo dataset includes its own users — see docs/demo.md +#INVENTREE_ADMIN_USER=admin +#INVENTREE_ADMIN_PASSWORD=admin +#INVENTREE_ADMIN_EMAIL=admin@localhost # Database configuration options # DO NOT CHANGE THESE SETTINGS (unless you really know what you are doing) diff --git a/contrib/container/Dockerfile b/contrib/container/Dockerfile index 2a8693f11d..5864a68627 100644 --- a/contrib/container/Dockerfile +++ b/contrib/container/Dockerfile @@ -9,8 +9,8 @@ # - Runs InvenTree web server under django development server # - Monitors source files for any changes, and live-reloads server -# Base image last bumped 2026-03-20 -FROM python:3.14-slim-trixie@sha256:fb83750094b46fd6b8adaa80f66e2302ecbe45d513f6cece637a841e1025b4ca AS inventree_base +# Base image last bumped 2026-06-16 +FROM python:3.14.7-slim-trixie@sha256:ce40764625a4ff50df3548277632e7f96c4e77fe75fa848aae9885476e7df5a4 AS inventree_base # Build arguments for this image ARG commit_tag="" @@ -18,6 +18,7 @@ ARG commit_hash="" ARG commit_date="" ARG data_dir="data" +ARG NODE_VERSION=24 ENV PYTHONUNBUFFERED=1 ENV PIP_DISABLE_PIP_VERSION_CHECK=1 @@ -118,15 +119,11 @@ RUN pip install --user --require-hashes -r base_requirements.txt --no-cache-dir rm -rf /root/.cache/pip # Install frontend build dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - nodejs npm \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -RUN npm install -g n yarn --ignore-scripts && \ - yarn config set network-timeout 600000 -g -RUN bash -c "n lts" -RUN cd "${INVENTREE_HOME}" && invoke int.frontend-compile --extract +# pinned to v0.40.5 +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/1889911f0841e669de0be5bd02c737a3f1fd20fa/install.sh | bash && \ + bash -c "export NVM_DIR="$HOME/.nvm" && source $HOME/.nvm/nvm.sh && \ + nvm install $NODE_VERSION && corepack enable yarn && yarn config set network-timeout 600000 -g" +RUN bash -c "source $HOME/.nvm/nvm.sh && cd '${INVENTREE_HOME}' && invoke int.frontend-compile --extract" # InvenTree production image: # - Copies required files from local directory @@ -149,6 +146,13 @@ ENV PATH=/root/.local/bin:$PATH COPY --from=builder_stage ${INVENTREE_BACKEND_DIR}/InvenTree/web/static/web ${INVENTREE_BACKEND_DIR}/InvenTree/web/static/web COPY --from=builder_stage /root/.local /root/.local +# Compile Django backend translations during image build +RUN bash -c "cd '${INVENTREE_HOME}' && invoke int.backend-compilemessages" + +# Generate license information for installed python packages +RUN pip-licenses --format=json --with-license-file --no-license-path > "${INVENTREE_BACKEND_DIR}/InvenTree/InvenTree/licenses.txt" \ + && test -s "${INVENTREE_BACKEND_DIR}/InvenTree/InvenTree/licenses.txt" + # Launch the production server CMD ["sh", "-c", "exec gunicorn -c ./gunicorn.conf.py InvenTree.wsgi -b ${INVENTREE_WEB_ADDR}:${INVENTREE_WEB_PORT} --chdir ${INVENTREE_BACKEND_DIR}/InvenTree"] diff --git a/contrib/container/docker-compose.yml b/contrib/container/docker-compose.yml index 9b8abc5b05..ce8b958a09 100644 --- a/contrib/container/docker-compose.yml +++ b/contrib/container/docker-compose.yml @@ -60,6 +60,9 @@ services: inventree-cache: image: redis:7-alpine container_name: inventree-cache + # Disable disk persistence to avoid permission errors on Windows bind mounts. + # The /data volume is retained for layout consistency (#11100); cache data is ephemeral. + command: redis-server --save "" --appendonly no env_file: - .env expose: diff --git a/contrib/container/gunicorn.conf.py b/contrib/container/gunicorn.conf.py index 682f75b50d..9f95c0e53a 100644 --- a/contrib/container/gunicorn.conf.py +++ b/contrib/container/gunicorn.conf.py @@ -19,7 +19,7 @@ threads = 4 # Worker timeout (default = 90 seconds) -timeout = os.environ.get('INVENTREE_GUNICORN_TIMEOUT', '90') +timeout = int(os.environ.get('INVENTREE_GUNICORN_TIMEOUT', '90')) # Number of worker processes workers = os.environ.get('INVENTREE_GUNICORN_WORKERS', None) @@ -43,7 +43,13 @@ preload_app = True def post_fork(server, worker): - """Post-fork hook to set up logging for each worker.""" + """Post-fork hook called after each worker process is forked.""" + from django.db import connections + + # Close any DB connections inherited from the master process — PostgreSQL + # connections are not fork-safe, so each worker must open its own. + connections.close_all() + from django.conf import settings if not settings.TRACING_ENABLED: diff --git a/contrib/container/requirements.in b/contrib/container/requirements.in index 932b942c3d..1e29f27b0d 100644 --- a/contrib/container/requirements.in +++ b/contrib/container/requirements.in @@ -1,18 +1,18 @@ # Base python requirements for docker containers # Basic package requirements -invoke>=2.2.0 # Invoke build tool -pyyaml>=6.0.1 -setuptools>=69.0.0 -wheel>=0.41.0 +invoke # Invoke build tool +pyyaml +setuptools +wheel # Database links psycopg[binary, pool] -mysqlclient>=2.2.0 -mariadb>=1.1.8 +mysqlclient +mariadb # gunicorn web server -gunicorn>=22.0.0 +gunicorn # LDAP required packages django-auth-ldap # Django integration for ldap auth diff --git a/contrib/container/requirements.txt b/contrib/container/requirements.txt index 6e0559a9c2..eaf8d51a87 100644 --- a/contrib/container/requirements.txt +++ b/contrib/container/requirements.txt @@ -1,14 +1,14 @@ # This file was autogenerated by uv via the following command: # uv pip compile contrib/container/requirements.in -o contrib/container/requirements.txt --python-version=3.14 -c src/backend/requirements.txt -asgiref==3.11.1 \ - --hash=sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce \ - --hash=sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133 +asgiref==3.12.1 \ + --hash=sha256:59dcb51c272ad209d59bed5708a64a333083e86017d7fcdd67498eeab7784340 \ + --hash=sha256:fe386d1c2bff7259ea95929266d12a8cf9a8b5a1c2598402967d8792e7a7c094 # via # -c src/backend/requirements.txt # django -django==5.2.14 \ - --hash=sha256:58a63ba841662e5c686b57ba1fec52ddd68c0b93bd96ac3029d55728f00bf8a2 \ - --hash=sha256:6f712143bd3064310d1f50fac859c3e9a274bdcfc9595339853be7779297fc76 +django==5.2.16 \ + --hash=sha256:04f354bf9d807a86ad1a8392fe3808d362358a8eafc322848e0e43e59b24371d \ + --hash=sha256:59ea02020c3136fce14bef0bbece21a10a4febef5eed1c51c22ae468efa22200 # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in @@ -17,9 +17,9 @@ django-auth-ldap==5.3.0 \ --hash=sha256:743d8107b146240b46f7e97207dc06cb11facc0cd70dce490b7ca09dd5643d19 \ --hash=sha256:aa880415983149b072f876d976ef8ec755a438090e176817998263a6ed9e1038 # via -r contrib/container/requirements.in -gunicorn==25.3.0 \ - --hash=sha256:cacea387dab08cd6776501621c295a904fe8e3b7aae9a1a3cbb26f4e7ed54660 \ - --hash=sha256:f74e1b2f9f76f6cd1ca01198968bd2dd65830edc24b6e8e4d78de8320e2fe889 +gunicorn==26.0.0 \ + --hash=sha256:40233d26a5f0d1872916188c276e21641155111c2853f0c2cd55260aec0d24fc \ + --hash=sha256:ca9346f85e3a4aeeb64d491045c16b9a35647abd37ea15efe53080eb8b090baf # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in @@ -53,82 +53,82 @@ mysqlclient==2.2.8 \ --hash=sha256:9bed7c8d3b629bdc09e17fb628d5b3b0a5fd1f12b09432b464b9126c727bedc0 \ --hash=sha256:a81f5e12f8d05439709cb02fba97f9f76d1a6c528164f2260d8798fec969e300 # via -r contrib/container/requirements.in -packaging==26.2 \ - --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ - --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 +packaging==26.3 \ + --hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \ + --hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c # via # -c src/backend/requirements.txt # gunicorn # mariadb # wheel -psycopg[binary, pool]==3.3.3 \ - --hash=sha256:5e9a47458b3c1583326513b2556a2a9473a1001a56c9efe9e587245b43148dd9 \ - --hash=sha256:f96525a72bcfade6584ab17e89de415ff360748c766f0106959144dcbb38c698 +psycopg[binary, pool]==3.3.4 \ + --hash=sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a \ + --hash=sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc # via -r contrib/container/requirements.in -psycopg-binary==3.3.3 \ - --hash=sha256:05f32239aec25c5fb15f7948cffdc2dc0dac098e48b80a140e4ba32b572a2e7d \ - --hash=sha256:07c7211f9327d522c9c47560cae00a4ecf6687f4e02d779d035dd3177b41cb12 \ - --hash=sha256:0dde92cfde09293fb63b3f547919ba7d73bd2654573c03502b3263dd0218e44e \ - --hash=sha256:111c59897a452196116db12e7f608da472fbff000693a21040e35fc978b23430 \ - --hash=sha256:162e5675efb4704192411eaf8e00d07f7960b679cd3306e7efb120bb8d9456cc \ - --hash=sha256:165f22ab5a9513a3d7425ffb7fcc7955ed8ccaeef6d37e369d6cc1dff1582383 \ - --hash=sha256:17bb6600e2455993946385249a3c3d0af52cd70c1c1cdbf712e9d696d0b0bf1b \ - --hash=sha256:19f93235ece6dbfc4036b5e4f6d8b13f0b8f2b3eeb8b0bd2936d406991bcdd40 \ - --hash=sha256:1bef235a50a80f6aba05147002bc354559657cb6386dbd04d8e1c97d1d7cbe84 \ - --hash=sha256:258d1ea53464d29768bf25930f43291949f4c7becc706f6e220c515a63a24edd \ - --hash=sha256:263a24f39f26e19ed7fc982d7859a36f17841b05bebad3eb47bb9cd2dd785351 \ - --hash=sha256:329ff393441e75f10b673ae99ab45276887993d49e65f141da20d915c05aafd8 \ - --hash=sha256:42961609ac07c232a427da7c87a468d3c82fee6762c220f38e37cfdacb2b178d \ - --hash=sha256:47f06fcbe8542b4d96d7392c476a74ada521c5aebdb41c3c0155f6595fc14c8d \ - --hash=sha256:48e500cf1c0984dacf1f28ea482c3cdbb4c2288d51c336c04bc64198ab21fc51 \ - --hash=sha256:497852c5eaf1f0c2d88ab74a64a8097c099deac0c71de1cbcf18659a8a04a4b2 \ - --hash=sha256:4d4606c84d04b80f9138d72f1e28c6c02dc5ae0c7b8f3f8aaf89c681ce1cd1b1 \ - --hash=sha256:5152d50798c2fa5bd9b68ec68eb68a1b71b95126c1d70adaa1a08cd5eefdc23d \ - --hash=sha256:533efe6dc3a7cba5e2a84e38970786bb966306863e45f3db152007e9f48638a6 \ - --hash=sha256:56c767007ca959ca32f796b42379fc7e1ae2ed085d29f20b05b3fc394f3715cc \ - --hash=sha256:5958dbf28b77ce2033482f6cb9ef04d43f5d8f4b7636e6963d5626f000efb23e \ - --hash=sha256:59aa31fe11a0e1d1bcc2ce37ed35fe2ac84cd65bb9036d049b1a1c39064d0f14 \ - --hash=sha256:642050398583d61c9856210568eb09a8e4f2fe8224bf3be21b67a370e677eead \ - --hash=sha256:6698dbab5bcef8fdb570fc9d35fd9ac52041771bfcfe6fd0fc5f5c4e36f1e99d \ - --hash=sha256:73eaaf4bb04709f545606c1db2f65f4000e8a04cdbf3e00d165a23004692093e \ - --hash=sha256:74eae563166ebf74e8d950ff359be037b85723d99ca83f57d9b244a871d6c13b \ - --hash=sha256:78c9ce98caaf82ac8484d269791c1b403d7598633e0e4e2fa1097baae244e2f1 \ - --hash=sha256:7c84f9d214f2d1de2fafebc17fa68ac3f6561a59e291553dfc45ad299f4898c1 \ - --hash=sha256:883d68d48ca9ff3cb3d10c5fdebea02c79b48eecacdddbf7cce6e7cdbdc216b8 \ - --hash=sha256:8e7e9eca9b363dbedeceeadd8be97149d2499081f3c52d141d7cd1f395a91f83 \ - --hash=sha256:90eecd93073922f085967f3ed3a98ba8c325cbbc8c1a204e300282abd2369e13 \ - --hash=sha256:97c839717bf8c8df3f6d983a20949c4fb22e2a34ee172e3e427ede363feda27b \ - --hash=sha256:9d6a1e56dd267848edb824dbeb08cf5bac649e02ee0b03ba883ba3f4f0bd54f2 \ - --hash=sha256:9f7d0cf072c6fbac3795b08c98ef9ea013f11db609659dcfc6b1f6cc31f9e181 \ - --hash=sha256:a39f34c9b18e8f6794cca17bfbcd64572ca2482318db644268049f8c738f35a6 \ - --hash=sha256:a4aab31bd6d1057f287c96c0effca3a25584eb9cc702f282ecb96ded7814e830 \ - --hash=sha256:a6af77b6626ce92b5817bf294b4d45ec1a6161dba80fc2d82cdffdd6814fd023 \ - --hash=sha256:a89bb9ee11177b2995d87186b1d9fa892d8ea725e85eab28c6525e4cc14ee048 \ - --hash=sha256:ae07a3114313dd91fce686cab2f4c44af094398519af0e0f854bc707e1aeedf1 \ - --hash=sha256:b27d3a23c79fa59557d2cc63a7e8bb4c7e022c018558eda36f9d7c4e6b99a6e0 \ - --hash=sha256:b3385b58b2fe408a13d084c14b8dcf468cd36cbbe774408250facc128f9fa75c \ - --hash=sha256:b62cf8784eb6d35beaee1056d54caf94ec6ecf2b7552395e305518ab61eb8fd2 \ - --hash=sha256:cab7bc3d288d37a80aa8c0820033250c95e40b1c2b5c57cf59827b19c2a8b69d \ - --hash=sha256:cb85b1d5702877c16f28d7b92ba030c1f49ebcc9b87d03d8c10bf45a2f1c7508 \ - --hash=sha256:d257c58d7b36a621dcce1d01476ad8b60f12d80eb1406aee4cf796f88b2ae482 \ - --hash=sha256:d593612758d0041cb13cb0003f7f8d3fabb7ad9319e651e78afae49b1cf5860e \ - --hash=sha256:da2f331a01af232259a21573a01338530c6016dcfad74626c01330535bcd8628 \ - --hash=sha256:dac7ee2f88b4d7bb12837989ca354c38d400eeb21bce3b73dac02622f0a3c8d6 \ - --hash=sha256:e77957d2ba17cada11be09a5066d93026cdb61ada7c8893101d7fe1c6e1f3925 \ - --hash=sha256:e7800e6c6b5dc4b0ca7cc7370f770f53ac83886b76afda0848065a674231e856 \ - --hash=sha256:e7b607f0e14f2a4cf7e78a05ebd13df6144acfba87cb90842e70d3f125d9f53f \ - --hash=sha256:eb072949b8ebf4082ae24289a2b0fd724da9adc8f22743409d6fd718ddb379df \ - --hash=sha256:eb36a08859b9432d94ea6b26ec41a2f98f83f14868c91321d0c1e11f672eeae7 \ - --hash=sha256:f24e8e17035200a465c178e9ea945527ad0738118694184c450f1192a452ff25 \ - --hash=sha256:fab6b5e37715885c69f5d091f6ff229be71e235f272ebaa35158d5a46fd548a0 +psycopg-binary==3.3.4 \ + --hash=sha256:018fbed325936da502feb546642c982dcc4b9ffdea32dfef78dbf3b7f7ad4070 \ + --hash=sha256:0579252a1202cd73e4da137a1426e2dae993ae44e757605344282af3a082848c \ + --hash=sha256:136f199a407b5348b9b857c504aff60c77622a28482e7195839ce1b51238c4cc \ + --hash=sha256:13a7f380824c35896dcac7fe0f61440f7ca49d6dc73f3c13a9a4471e6a3b302e \ + --hash=sha256:17a21953a9e5ff3a16dab692625a3676e2f101db5e40072f39dbee2250194d68 \ + --hash=sha256:1dc1f79fd16bb1f3f4421417a514607539f17804d95c7ed617265369d1981cae \ + --hash=sha256:1fbaa292a3c8bb61b45df1ad3da1908ccee7cb889db9425e3557d9e34e2a4829 \ + --hash=sha256:22cdbf5f91ef7bb91fe0c5757e1962d3127a8010256eefd9c61fcaf441802097 \ + --hash=sha256:26df2717e59c0473e4465a97dfb1b7afebaa479277870fd5784d1436470db47c \ + --hash=sha256:276904e3452d6a23d474ef9a21eee19f20eed3d53ddd2576af033827e0ba0992 \ + --hash=sha256:28b7398fdd19db3232c884fb24550bdfe951221f510e195e233299e4c9b78f97 \ + --hash=sha256:2c09aad7051326e7603c14e50636db9c01f78272dc54b3accff03d46370461e6 \ + --hash=sha256:32a6fbf8481e3a370d0d72b860d35948a693cb01281da217f7b2f307636e591a \ + --hash=sha256:41f2ec0fea529832982bcb6c9415de3c86264ebe562b77a467c0fbcd7efbba8d \ + --hash=sha256:46893c26858be12cc49ca4226ed6a60b4bfccadd946b3bebb783a60b38788228 \ + --hash=sha256:47c656a8a7ba6eb0cff1801a4caaa9c8bdc12d03080e273aff1c8ac39971a77e \ + --hash=sha256:494ca54901be8cf9eb7e02c25b731f2317c378efa44f43e8f9bd0e1184ae7be4 \ + --hash=sha256:514404ed543efd620c85602b747df2a23cf1241b4067199e1a66f2d2757aaa41 \ + --hash=sha256:574ea21a9651958f1535c5a1c649c7409e9168bcbffa29a3f2f961f58b322949 \ + --hash=sha256:580ae30a5f95ccd90008ec697d3ed6a4a2047a516407ad904283fa42086936e9 \ + --hash=sha256:5ab28a2a7649df3b72e6b674b4c190e448e8e77cf496a65bd846472048de2089 \ + --hash=sha256:5c4ab71be17bdca30cb34c34c4e1496e2f5d6f20c199c12bad226070b22ef9bf \ + --hash=sha256:612a627d733f695b1de1f9b4bd511c15f999a5d8b915d444bbd7dd71cf3370da \ + --hash=sha256:6402a9d8146cf4b3974ded3fd28a971e83dc6a0333eb7822524a3aa20b546578 \ + --hash=sha256:6b9016b1714da4dd5ecaaa75b82098aa5a0b87854ce9b092e21c27c4ae23e014 \ + --hash=sha256:71e55ccbdfae79a2ed9c6369c3008a3025817ff9d7e27b32a2d84e2a4267e66e \ + --hash=sha256:7465bfe6087d2d5b42d4c53b9b11ca9f218e477317a4a162a10e3c19e984ba8e \ + --hash=sha256:75a9067e236f9b9ae3535b66fe99bddb33d39c0de10112e49b9ab11eee53dc31 \ + --hash=sha256:773d573e11f437ce0bdb95b7c18dc58390494f96d43f8b45b9760436114f7652 \ + --hash=sha256:77df19583501ea288eaf15ac0fe7ad01e6d8091a91d5c41df5c718f307d8e31b \ + --hash=sha256:7f7668f30b9dd5163197e5cbf4e0efd54e00f0a859cc566ce56cfc31f4054839 \ + --hash=sha256:8c0056529e68dbe9184cd4019a1f3d8f3a4ead2f6fc7a5afcf27d3314edd1277 \ + --hash=sha256:94596f9e7633ee3f6440711d43bb70aa31cc0a46a900ab8b4201a366ace5c9e7 \ + --hash=sha256:ab8cca8ef8fb1ccf5b048ae5bd78ba55b9e4b5d472e3ce5ca39ff4d2a9c249e4 \ + --hash=sha256:ad3bc94054876155549fdaedf4a46d1ec69d39a5bcee377148afe498e84c4b8e \ + --hash=sha256:b56b603ebcea8aa10b46228b8410ba7f13e7c2ee54389d4d9be0927fd8ce2a70 \ + --hash=sha256:b6f5a29e9c775b9f12a1a717aa7a2c80f9e1db6f27ba44a5b59c80ac61d2ffcf \ + --hash=sha256:b7bfff1ca23732b488cbca3076fc11bc98d520ee122514fdb17a8e20d3338f5a \ + --hash=sha256:bdef84570ebbce1d42b4e7ea952d21c414c5f118ad02fee00c5625f35e134429 \ + --hash=sha256:c37e024c07308cd06cf3ec51bfd0e7f6157585a4d84d1bce4a7f5f7913719bf8 \ + --hash=sha256:c677c4ad433cb7150c8cd304a0769ae3bcfbe5ea0676eb53faa7b1443b16d0d3 \ + --hash=sha256:cf7f73a4a792bc5db58a4b385d8a1467e8d468f7548702fb0ed1e9b7501b1c13 \ + --hash=sha256:cffc3408d77a27973f33e5d909b624cce683db5fc25964b02fe0aae7886c1007 \ + --hash=sha256:d7b4d40c153fa352ab3cca530f3a0baedf7621b2ebcbd7f084009522c21788fc \ + --hash=sha256:dbfdb9b6cc79f31104a7b162a2b921b765fcc62af6c00540a167a8de47e4ed38 \ + --hash=sha256:df1d567fc430f6df15c9fcf67d87685fc49bdb325adc0db5af1adfb2f44eb5c9 \ + --hash=sha256:e2631da29253a98bd496e6c4813b24e09a4fe3fb2a9e88513305d6f8747cce95 \ + --hash=sha256:e7510c37550f91a187e3660a8cc50d4b760f8c3b8b2f89ebc5698cd2c7f2c85d \ + --hash=sha256:eb05ee1c2b817d27c537333224c9e83c7afb86fe7296ba970990068baf819b16 \ + --hash=sha256:eb4eed2079c01a4850bf467deacfab56d356d4225040170af03dc9958321242d \ + --hash=sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260 \ + --hash=sha256:f80e3f2b5331dbbf0901bcb658056c03eeb2c1ef31d774afb0d61598b242e744 \ + --hash=sha256:f9b1c2533af01cd7648378599f82b0b8ae32f293296e6eec5753a625bc97ef28 \ + --hash=sha256:fa1cbc10768a796c96d3243656016bf4e337c81c71097270bb7b0ad6210d9765 \ + --hash=sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7 # via psycopg -psycopg-pool==3.3.0 \ - --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ - --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 +psycopg-pool==3.3.1 \ + --hash=sha256:2af5b432941c4c9ad5c87b3fa410aec910ec8f7c122855897983a06c45f2e4b5 \ + --hash=sha256:b10b10b7a175d5cc1592147dc5b7eec8a9e0834eb3ed2c4a92c858e2f51eb63c # via psycopg -pyasn1==0.6.3 \ - --hash=sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf \ - --hash=sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde +pyasn1==0.6.4 \ + --hash=sha256:9c447d8431c947fe4c8febc4ed9e760bc29011a5b01e5c74b67025bd9fb8ce81 \ + --hash=sha256:deda9277cfd454080ec40b207fb6df82206a3a2688735233cdcd8d3d565f088b # via # pyasn1-modules # python-ldap @@ -136,8 +136,8 @@ pyasn1-modules==0.4.2 \ --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 # via python-ldap -python-ldap==3.4.5 \ - --hash=sha256:b2f6ef1c37fe2c6a5a85212efe71311ee21847766a7d45fcb711f3b270a5f79a +python-ldap==3.4.7 \ + --hash=sha256:bacd9fb680d20263d8570ade1cf234d90d281149a8beb4f079dd8f33f7613dc8 # via # -r contrib/container/requirements.in # django-auth-ldap @@ -218,44 +218,44 @@ pyyaml==6.0.3 \ # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in -setuptools==82.0.1 \ - --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ - --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb +setuptools==83.0.0 \ + --hash=sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef \ + --hash=sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3 # via # -c src/backend/requirements.txt # -r contrib/container/requirements.in -sqlparse==0.5.5 \ - --hash=sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba \ - --hash=sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e +sqlparse==0.6.0 \ + --hash=sha256:113c35c75365ab9cc9c7231d68c6428fb11c085fc8e9eb1ad659b7ddbf6cd2b9 \ + --hash=sha256:b861c0288ce2fa56209a9a6412d2e066ac664b3873b89c26c9d8415e8e32996f # via # -c src/backend/requirements.txt # django -typing-extensions==4.15.0 \ - --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ - --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 +typing-extensions==4.16.0 \ + --hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \ + --hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5 # via # -c src/backend/requirements.txt # psycopg-pool -uv==0.11.7 \ - --hash=sha256:0df59ab0c6a4b14a763e8445e1c303af9abeb53cdfa4428daf9ff9642c0a3cce \ - --hash=sha256:162fa961a9a081dcea6e889c79f738a5ae56507047e4672964972e33c301bea9 \ - --hash=sha256:23d457d6731ebdb83f1bffebe4894edab2ef43c1ec5488433c74300db4958924 \ - --hash=sha256:46d971489b00bdb27e0aa715e4a5cd4ef2c28ea5b6ef78f2b67bf861eb44b405 \ - --hash=sha256:4e4d5e31bea86e1b6e0f5a0f95e14e80018e6f6c0129256d2915a4b3d793644d \ - --hash=sha256:553e67cc766d013ce24353fecd4ea5533d2aedcfd35f9fac430e07b1d1f23ed4 \ - --hash=sha256:5674dfb5944513f4b3735b05c2deba6b1b01151f46729d533d413a9a905f8c5d \ - --hash=sha256:5985a15a92bd9a170fc1947abb1fbc3e9828c5a430ad85b5bed8356c20b67a71 \ - --hash=sha256:6158b7e39464f1aa1e040daa0186cae4749a78b5cd80ac769f32ca711b8976b1 \ - --hash=sha256:750ee5b96959b807cf442b73dd8b55111862d63f258f896787ea5f06b68aaca9 \ - --hash=sha256:7d6a17507b8139b8803f445a03fd097f732ce8356b1b7b13cdb4dd8ef7f4b2e0 \ - --hash=sha256:8b2fe1ec6775dad10183e3fdce430a5b37b7857d49763c884f3a67eaa8ca6f8a \ - --hash=sha256:ceae53b202ea92bc954759bc7c7570cdcd5c3512fce15701198c19fd2dfb8605 \ - --hash=sha256:dd48823ca4b505124389f49ae50626ba9f57212b9047738efc95126ed5f3844d \ - --hash=sha256:eb91f52ee67e10d5290f2c2897e2171357f1a10966de38d83eefa93d96843b0c \ - --hash=sha256:f394331f0507e80ee732cb3df737589de53bed999dd02a6d24682f08c2f8ac4f \ - --hash=sha256:f422d39530516b1dfb28bb6e90c32bb7dacd50f6a383cd6e40c1a859419fbc8c \ - --hash=sha256:f97e9f4e4d44fb5c4dfaa05e858ef3414a96416a2e4af270ecd88a3e5fb049a9 \ - --hash=sha256:fab0bb43fbbc0ee5b5fee212078d2300c371b725faff7cf72eeaafa0bff0606b +uv==0.11.29 \ + --hash=sha256:0222a51972e42bc1c132761ea027b9086d710ff5fa5199af658955bd03bee4d8 \ + --hash=sha256:157ed0bcfef5aba9b53ff4b322e009b3261d83fbf5d9423e367a33c0416c85ac \ + --hash=sha256:257c6df4393116114f296f7a02f51db9a2117f68c3ae93bbe218fa79e6521df3 \ + --hash=sha256:2b49e175bfbcd8ac1e09e06f0b9d544b9e671d2cdecf753aa3fbff4d61d19317 \ + --hash=sha256:2dc8012a693b6bb9ec17dcb2c2345cf273ccad06ae2ab4a8c7a0833955812c75 \ + --hash=sha256:606e2bc7880d70448ff4359faa43a7c71743283010262fc142e1ca9fcb6937cf \ + --hash=sha256:60e792b00f4cd6c5eadd814161cd046fa8418d83621d85d3e65aae28dc5b53ff \ + --hash=sha256:66b250d102f0e49f3d2306353aaabb43f39da5ccfa4e84fe10ba8a25de85316c \ + --hash=sha256:7711c46452b44332352d344b5818ad8faf04596efaf837d8114aa9984e4a9610 \ + --hash=sha256:7d618b4a2ae2b367d20710858838344604d5b9e8c0863343d5f793142408ea11 \ + --hash=sha256:865f09f5de0c1913bf9ed424bcc5c1a15780d01debd4d62b8a22c8f3e9bdb420 \ + --hash=sha256:91b5d1407ac8757e1757268e9d983e9e7b72eeb826808f9e2404344a6de1d3fb \ + --hash=sha256:a4ca34dc3b247740e511ca7c718181d5300e7899bbef755db45bb6c993610a64 \ + --hash=sha256:aa166ce529cfbce6b3afaabdc4cdbfdf9e3e3d82413c709d679ff374eb76d5e9 \ + --hash=sha256:abc641b24be42dc5d62f63ecb3500c07a0fb3c596e407963708f59114f0816ad \ + --hash=sha256:db119a3ec9d7ce42e98de3d014427d74fd92f1f7c40fc9dfe62b14601a9e83da \ + --hash=sha256:e245e6f95f154ae56793bfc7742ec27334a546469bba4d09c03624470ab451d2 \ + --hash=sha256:eec03a8b63d55915694db3af4e91324b39ced49e2aeac7af37851c7eb3f470ea \ + --hash=sha256:f7e4c709397468264764f571003fd278cbd384321f5c497370c28352bdb8b6a9 # via -r contrib/container/requirements.in wheel==0.47.0 \ --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ diff --git a/contrib/dev_reqs/requirements.in b/contrib/dev_reqs/requirements.in index c148de0a40..115b23c47f 100644 --- a/contrib/dev_reqs/requirements.in +++ b/contrib/dev_reqs/requirements.in @@ -1,4 +1,4 @@ # Packages needed for CI/packages -requests==2.33.1 +requests==2.34.2 pyyaml==6.0.3 -jc==1.25.6 +jc diff --git a/contrib/dev_reqs/requirements.txt b/contrib/dev_reqs/requirements.txt index 0591b6d8a6..cf3d1a6d56 100644 --- a/contrib/dev_reqs/requirements.txt +++ b/contrib/dev_reqs/requirements.txt @@ -1,153 +1,117 @@ # This file was autogenerated by uv via the following command: # uv pip compile contrib/dev_reqs/requirements.in -o contrib/dev_reqs/requirements.txt -c src/backend/requirements.txt -certifi==2026.4.22 \ - --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ - --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 +certifi==2026.7.22 \ + --hash=sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775 \ + --hash=sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55 # via # -c src/backend/requirements.txt # requests -charset-normalizer==3.4.7 \ - --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ - --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ - --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ - --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ - --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ - --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ - --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ - --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ - --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ - --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ - --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ - --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ - --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ - --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ - --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ - --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ - --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ - --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ - --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ - --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ - --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ - --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ - --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ - --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ - --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ - --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ - --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ - --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ - --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ - --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ - --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ - --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ - --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ - --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ - --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ - --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ - --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ - --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ - --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ - --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ - --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ - --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ - --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ - --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ - --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ - --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ - --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ - --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ - --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ - --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ - --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ - --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ - --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ - --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ - --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ - --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ - --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ - --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ - --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ - --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ - --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ - --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ - --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ - --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ - --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ - --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ - --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ - --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ - --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ - --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ - --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ - --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ - --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ - --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ - --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ - --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ - --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ - --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ - --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ - --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ - --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ - --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ - --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ - --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ - --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ - --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ - --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ - --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ - --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ - --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ - --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ - --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ - --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ - --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ - --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ - --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ - --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ - --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ - --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ - --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ - --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ - --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ - --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ - --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ - --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ - --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ - --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ - --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ - --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ - --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ - --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ - --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ - --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ - --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ - --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ - --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ - --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ - --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ - --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ - --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ - --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ - --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ - --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ - --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ - --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ - --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ - --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ - --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ - --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 +charset-normalizer==3.4.9 \ + --hash=sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380 \ + --hash=sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62 \ + --hash=sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c \ + --hash=sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226 \ + --hash=sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5 \ + --hash=sha256:0fa1aec2d32bcc03c8fa0f6f1712caad1adc38509f31142112e5c9daf5b9c833 \ + --hash=sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b \ + --hash=sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99 \ + --hash=sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501 \ + --hash=sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec \ + --hash=sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698 \ + --hash=sha256:231ddcbb35e2ff8973e1365db41fe0572662893b99a05deb183b68ad4c0c8bd4 \ + --hash=sha256:253a4a220747e8b5faf57ec320c4f5efb0cef05f647420bf267143ec15dba10a \ + --hash=sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3 \ + --hash=sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2 \ + --hash=sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a \ + --hash=sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e \ + --hash=sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4 \ + --hash=sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419 \ + --hash=sha256:3c09a49d6cde137258beb3d551994a2927fd35ad5cf96aed573f61bbd67c5f84 \ + --hash=sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da \ + --hash=sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519 \ + --hash=sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe \ + --hash=sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381 \ + --hash=sha256:43b9e366a31fdd1c87d0eb08f579b4a82b723ea54338f040d6b4e518a026ea29 \ + --hash=sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614 \ + --hash=sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0 \ + --hash=sha256:476743fe6dfe14a2da12e3ac79125dc84a3b2cf8094369a47a1529b0cd8549fe \ + --hash=sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29 \ + --hash=sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0 \ + --hash=sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917 \ + --hash=sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9 \ + --hash=sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32 \ + --hash=sha256:58150c9f9b9a552505912d182ccdf26f6396fb6094816ceebcbb20eecabaed94 \ + --hash=sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63 \ + --hash=sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd \ + --hash=sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198 \ + --hash=sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde \ + --hash=sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012 \ + --hash=sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1 \ + --hash=sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15 \ + --hash=sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b \ + --hash=sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993 \ + --hash=sha256:68ce9f4d6b26d5ccbf7fd4459bf75f74a0a146677ebba80597df60cbdb20e6f4 \ + --hash=sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5 \ + --hash=sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8 \ + --hash=sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35 \ + --hash=sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642 \ + --hash=sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2 \ + --hash=sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d \ + --hash=sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9 \ + --hash=sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c \ + --hash=sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33 \ + --hash=sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db \ + --hash=sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf \ + --hash=sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9 \ + --hash=sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee \ + --hash=sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84 \ + --hash=sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44 \ + --hash=sha256:920079c3f7456fa213e0829ed2073aaa727fd39d889ead5b4f35d0de5460d04f \ + --hash=sha256:93d59d504b230e83c7a843251681959a0b6a9cd76f6e146ce1b8a80eb8739af9 \ + --hash=sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9 \ + --hash=sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177 \ + --hash=sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8 \ + --hash=sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b \ + --hash=sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39 \ + --hash=sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41 \ + --hash=sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0 \ + --hash=sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616 \ + --hash=sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d \ + --hash=sha256:ad41ba96094304aa090f5a30cb6e4fb3b3f1c264c523394b4c39bbacc4dc92ba \ + --hash=sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2 \ + --hash=sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b \ + --hash=sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9 \ + --hash=sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b \ + --hash=sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209 \ + --hash=sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48 \ + --hash=sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046 \ + --hash=sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632 \ + --hash=sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a \ + --hash=sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2 \ + --hash=sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1 \ + --hash=sha256:ddf4af30b417d9fe16481e9b81c27ab2a7cde1ff7ba3e85653b02db7d145dc7b \ + --hash=sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990 \ + --hash=sha256:df7276909358e5635ae203673ab7e509ddd224225a8d6b0790bf13eb2bde1cc5 \ + --hash=sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b \ + --hash=sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9 \ + --hash=sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534 \ + --hash=sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81 \ + --hash=sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a \ + --hash=sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d \ + --hash=sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf \ + --hash=sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115 # via # -c src/backend/requirements.txt # requests -idna==3.15 \ - --hash=sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8 \ - --hash=sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # -c src/backend/requirements.txt # requests -jc==1.25.6 \ - --hash=sha256:27f58befc7ae0a4c63322926c5f1ec892e3eac4a065eff3b07cfe420a6924a07 \ - --hash=sha256:7367b59e6e0da8babeede1e5b0da083f3c5aa6b6e585b4aed28dd7c4b2d76162 +jc==1.25.7 \ + --hash=sha256:5ed6a0da915c931c04693cab806d5c31d9ef14ca998c6c32308460d37cb30baf \ + --hash=sha256:63481e34d92715781e1b094eca7d76d122a14489463d45b7f3e8180f44ea3a10 # via -r contrib/dev_reqs/requirements.in pygments==2.20.0 \ --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ @@ -230,9 +194,9 @@ pyyaml==6.0.3 \ # via # -c src/backend/requirements.txt # -r contrib/dev_reqs/requirements.in -requests==2.33.1 \ - --hash=sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517 \ - --hash=sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # -c src/backend/requirements.txt # -r contrib/dev_reqs/requirements.in diff --git a/contrib/packager.io/functions.sh b/contrib/packager.io/functions.sh index c4703d6eba..2705a369e8 100755 --- a/contrib/packager.io/functions.sh +++ b/contrib/packager.io/functions.sh @@ -79,7 +79,7 @@ function detect_python() { echo "${On_Red}" echo "# POI07| Python ${SETUP_PYTHON} not found - aborting!" echo "# POI07| Please ensure python can be executed with the command '$SETUP_PYTHON' by the current user '$USER'." - echo "# POI07| If you are using a different python version, please set the environment variable SETUP_PYTHON to the correct command - eg. 'python3.11'." + echo "# POI07| If you are using a different python version, please set the environment variable SETUP_PYTHON to the correct command - eg. 'python3.12'." echo "${Color_Off}" exit 1 fi diff --git a/contrib/packager.io/postinstall.sh b/contrib/packager.io/postinstall.sh index a3ae0b0802..5660900b65 100755 --- a/contrib/packager.io/postinstall.sh +++ b/contrib/packager.io/postinstall.sh @@ -26,7 +26,7 @@ export DATA_DIR=${APP_HOME}/data export SETUP_NGINX_FILE=${SETUP_NGINX_FILE:-/etc/nginx/sites-enabled/inventree.conf} export SETUP_ADMIN_PASSWORD_FILE=${CONF_DIR}/admin_password.txt export SETUP_NO_CALLS=${SETUP_NO_CALLS:-false} -export SETUP_PYTHON=${SETUP_PYTHON:-python3.11} +export SETUP_PYTHON=${SETUP_PYTHON:-python3.12} export SETUP_ADMIN_NOCREATION=${SETUP_ADMIN_NOCREATION:-false} # SETUP_DEBUG can be set to get debug info # SETUP_EXTRA_PIP can be set to install extra pip packages diff --git a/docs/docs/api/index.md b/docs/docs/api/index.md index 256eddd9cf..fa05c6bc2d 100644 --- a/docs/docs/api/index.md +++ b/docs/docs/api/index.md @@ -48,7 +48,7 @@ Users can authenticate against the API using basic authentication - specifically Each user is assigned an authentication token which can be used to access the API. This token is persistent for that user (unless invalidated by an administrator) and can be used across multiple sessions. !!! info "Token Administration" - User tokens can be created and/or invalidated via the user settings, [Admin Center](../settings/admin.md#admin-center) or admin interface. + User tokens can be created and/or invalidated via the user settings, [Admin Center](../settings/admin.md#admin-center), or the [Database Admin interface](../settings/db_admin.md). #### Requesting a Token diff --git a/docs/docs/app/barcode.md b/docs/docs/app/barcode.md index 2645287f76..21eebb315f 100644 --- a/docs/docs/app/barcode.md +++ b/docs/docs/app/barcode.md @@ -67,6 +67,8 @@ Transfer the currently selected stock location into another location. Scanning a Receive incoming purchase order items into the selected location. Scanning a *new* barcode which is associated with an item in an incoming purchase order will receive the item into the selected location. +*Note: Both purchase order number and supplier SKU's are required to be found on the barcode for this function to find the associated line item. Missing one will lead to an error.* + #### Scan Items Into Location the *Scan Items Into Location* action allows you to scan items into the selected location. Scanning a valid barcode associated with a stock item (already in the database) will result in that item being transferred to the selected location. @@ -105,6 +107,8 @@ From the [Purchase Order detail page](./po.md#purchase-order-detail) page, the f Receive incoming purchase order items against the selected purchase order. Scanning a *new* barcode which is associated with an item in an incoming purchase order will receive the item into stock. +*Note: supplier SKU's are required to be found on the barcode for this function to find the associated line item.* + ### Sales Order Actions The following barcode actions are available for [Sales Orders](./so.md): diff --git a/docs/docs/assets/images/concepts/ui_navigation_tree.png b/docs/docs/assets/images/concepts/ui_navigation_tree.png index 5d274452ab8141e4bac90050a0e3631cc067519f..e124cd51bfa729103ee9ae47db7ca374c39ef765 100644 GIT binary patch literal 41520 zcmdqJ2UJr{^e<{dzYhfbL_nIT2na~;T|s&;p@b&ViS*uWfP#QVdX)|dA+!((RS=LG zffRZu(t8QL+{EvH%ergbSJqqqx9)pcCu?%foHJ);&&=Mx{hK}csIRL=P037o>Cz=? z4fW@Smo8mRC4IO4x=y-c>@gTaN-p~tswrJ6A7EW3om_Kzrt|F5rOE`VQ(Fqs`QM)E z=02A$(X^Alm%BVl>@Qu)?a+As%s9|`Z89Lx7%8#6=DUU%(2k?L~kl9XDC8P&hPSgvW4f4t`Z zi_{>}$KsaIWpY}3|HTz@`s!KhHF7%g_VwT7w1VO?9XWkLb%l$Zwle(hUx3%MD+`r& zU3*LU2@sdzB8YzOTUMHA(!pz7^3Ab7eYvvho{_b6HiCuRqHnA|Bsn1}o@7aRDW%wi z*PE1Ey1;hm*xBKnTFE6!k(4-I@_kRGeW#p+aw5);jH0wOfVHpEtb><1LBfB^$duW< z>~p-g9Jv`y!v-lUd%|RA|H;6_Bsq$Pjk$vV&pn~Co5-KnDJYf?x97kG?a{PQ%_QD% zqFOww0Tu$F8edpgIL2Nj-`Z2WdrydsMs4N<+5P5vecxq+%wQ`TAb>6b`mcIpt3dKBi(-|Xm7j4wQImC_&kjpTjo-OKt1nD zV8@p*UX&*(!f}e7a&WG}IG9e)kD!R_)h|0@A~zH6$*-6?@l#P!?m+nxn#Y5Ul@$hl zQO^zEIh$orNe~EhOAb*&MfHv3Z`Lv>qP?My$5V_wam)%$eJ4Ojl%62AO((icCtT8` zkZp*C@XE;Fz4_7dIQ5CRgBJ?HM5@*c3f^ zmKO1y0_k>Ppkv)=guHM{a%Z<`gLEs15=k|DdcQrI+Q8GZBA%@mONW*#CbEQAN^JX_ z9(u{|PH1UbHJN}DF~sXu45o?Sd&YujQ{9mbTW4Vhlf~21FQi#%NCyC7tU)Wc_0%>j zM$PE}a?Naum$Du2p%(xHoFl2ahgq>rHIdfg z8%zMmowEF{_~mY=96>KGQAt5PvQVLhcy%yp$`f{-5P~Fdd~jHAywNw)9=%%CD^ShA z=yNomvU+j8c~RCe--e-&Mg+AuaawkZ(qSvT9Kz%(%4_BRf${4-2c2J~7ArS(* z*d|@ET<~VA9WecQ$}da&I28_%hp|tZyTC2s-3PVvM_QzMUBfh*(>00p(1|3F6+ z)s)@~Srg_rt9VM!n}}AdQyfp7W4!+mA|<|^;OA>@?`doP&XqpVw^VB`7>he&gD@tq zV(2pGpPSz-zxfVSzt&J0my*f+e_uZqS4J!flxO3G=PB5`(W>F~_sn!O12aDhc}+rq?+(3lEO|o(KVm z%ZI!5=Uve-N_JY_B}O9@I82$;9D>N~vk zqHtnZ+cqgH{OpR$A%1=;AiMeN4KbsxqTFydP0{(ToBbAFONk9WiC!Z2t~@hpo8mZ~Ye#5PV7T;O&i-en&W25da~ zCb2ev%T}J+q-uV?O|9%VKJVviv(++18XF#c8hti(~_j-UoaaShaR z%yUo+c)80Q=|-h(omd`J$^>j#{owBu6^kKOjiK_Dr!7GF_tF-F=FW~w zX&;r?_TOp}1LZecXXLI;(0NnH`mGoK6MR~9SG|7U2%#>m;iNu&%(5!!K4ip^jUTk@y2Hv^RvfJeIZ({Z6<@_^frBSA3qm#; z+sD=$r9Ce1LgCGZuC5T8dvZ&r3K8d_VJGWIaDi@?OsUV}Ksb@4e1{!UtcpPJCLH`! ziCM@kfx%sV!RV!2brSOM1`Tv+(BgF1{`KdeO#qg7h?oHfJji{sx%sQdca^v1JS-hk zR+1>oLeWScFq8ah^5R*rZ7T1ne-8Ue!8i*;)K67(`94d&N9*Zs0Ss8N>}i|D_cQlm za@05l3$rvcNzZ%Dqp?tP)e$!sN}XEwjBhADkTOQMtvCr&W5TJ^B4}cp6pIcOJml0m z(6zR?TONDIs<%7hBjBZ|o|%Wxsca4x?&7&zj)$w27M$2pQ&A)If)Cd7Z!?c= zekchW|=PF0L{{HzT9RAjmM}rW4;#PS~y0n5?EjPlK zTlr15UT(3od2IEvOjLrV-#i7zcac?8%16VuI-;S~BzQ5-#l|@yk?yxv5Ui&@+{4y& zrA%Ul;I!L3w{o@t?`S3q{VZt5fAdp*vDe^wJ zAeQf(?TtNKf656A0sN9|wblsh8mT!*o$x3(z!_XTt(i`FGI>4#MEgDVpTgN)*H_9h zhwi)LAWfH7W7y$lZz3bkzGu>{5aBtYZH1KMcc{B|9fz}D5l`{7GO2ddZxvXFw5la} zW%0)i%hIa;*3H)Gh}??37Xw~IHl*2T{gFybex#<18cBAUwEY?4gR$r{EWB)$8gISj zS-Sg=(8cMZ;_5D15y_BKNm5MOSFhi!V6eG$Hf9XS2*%0Fu=PlR;l+yMaK*;#qLk+D zCk%(Ra!e%ktP0h!Lc66>Y&2D&Y86I}Epl9eQXxm3dD<Nd?_G|I!jf@M_v_y71?|IOx`GL6_ezCMhKh@ln_2~%Na^qX9 zF+FUvu)3nB7*Z=z-qp^9`mo;H-OlE_q0~eiyGS+e!R& zaowggV;sx>ik1YRcf0Q9Cnh+ZB=H}4rTMQ59EWTu@eEtoN1Se}S$TEPN9Hv6F6Z&V z8;9Wi+jCt>=_^4Sf&v1%^n47HdE6RW$xjBIa>7gwgGQ?yT=C^uHW^e8NF!eUY&5*z z+-Y*IYRMb*mNhuv^!@p-k%(lpylu2oES<;rGgA}3o5>WwGq>uhUCMZe#8937m$4K& z=GleCip1-zb3ymKh+B@?D2E$Oenl1TD>*DHB3g9_S26E60{`c)8_oq6PsX4W8BNII zp2vBv6k*#>`&{G$mZ38?rh$Z@_|1BiT8Iq`G?^piM1EKLwDYn2FCJ1O64^!fes@_= zDK@+n7#wpFOnIbpZkwQ&^@VTgwoU`LNs3C4`-waYHJFj1Ie?`6{m@qHri#G>3{Ap{ zFwZ`>)o9lR<&Fra)eC}Tw&c{swc?5KqAi9|2EBoUYjPfwa~eA0hbUE*tR}Rh!ugEM zCO3y^g%OK2s=PvB<;&X(ce$>*i?Pn&m4(!{V-11_o{l{*xkA7>TbftiI` zDGbdmpWAq?^1P6kp^%6&n1o-LlW44CT-ENUb2&E>e0B|rs;bbKW-7}Gm_L56rQuy- z(;$?Cz9$bf;g^Y0?ir9R%?Sv0JV`zU3Z2YTI&2EsZ{=6KNJVf_dp7ruOHv{uQVXEx*2`?eM2VZ6|R#(toQP{3prnymD zZ(yWMvPB0UvmTA$X+NQ*D4ZDMHDA>mtbMJQL&Dc*C(^7P3|n7}%@#s*s=ZGSoQOx$ zyHlpqJ2>h#OsNWguT+6~Z@}`K0MnAmVVhfGB=344|E*{J;SKboDdht~eg-Pw%Oe$B zDXda3&Ja-{#Maj{bRjQ1`!=#~wsf8~ljMb(TKOeehY}8Nb|J z35G?)wk--58s+?04kMI~WkRfrn~OM24k;%bd#BoD;A#ne62IpfoRC1@p?fee3ww`-*~ zKRFs0MY9I`Wjl%5kXn`)cY1ni6xDlW{(=1%vrw^Kj`d;q(y!c}o*uBUYUf=C2L~6@ z>E&_Ys9$E)4#p`hnN)1xIkU$!<0<8x^TLfq+Bm*m`rlhrX-3H>?xr)sA?vm+Tel24 z%n#*F#r9gP4!&ZeuUs3teaI?WHpCfxcto0Y z=kh2rTuhCY-Z+hCGC<@pW46jZ2dmg!sJvG&N3@Jca5bA0GCpy9q(K9K{f+>wytO$! z@ZuM5TwYUhBq8=G`j=EvVnN$9Bz;tE$^d)8Cv7Y%W=7qvRToxY<8{Y`!rh3!AaA1% z^`=Pfm$lD1{Ka+rZUmFLlWYbx$@~p(!|@kJcLmt*`kH>6se1Yx24voCtA;RHD@W6? z<0`nb2jBE*gQ`XBK&_T7;bAi;2KlNyVq!I0KF-c1s&UMK!=Qd<0+#O#X5EC^I;&?b zE-M?)C?1##aQVr7BJLEXYwOu7<8NqWdJh-7dlvEf9{_L3Geq7uLj*V?@Gy`#^YRVC zhYo$^3B`lm4*0=QWFJp&_1>)MRK+|s?NvcRphK-qgKPNr2eO+5?xA+E+=;>z(%5V}c(Mk20S<%h4)D2SY4xK42 zB(fi@MAnZt<;Zn4Rx5uud1!dCkDwy-HeC8eyf`$k4xh3y+xI#Chx(kL%74fS9jTMp z=;pbZL=`SwV#|IyYs#)}=5V2p5?TMi@JbFFfjK9HtQVeB?Z_#DzS{iEY+Fy zKtjlc#{@qjl;IM1$}F?6B`m|djv_L8@$4HPWO*9|dQ8G1eoQS^B(D}3!Q3kx8%UY{ z{>F0e3G*?war^9Y+>xWl-*!)qPpvPmuiRb#yCzNzMlAipMfCUf9`IYL{QN z+lb6(E_LZAxv^|)o-5;%S#cu{wAYjbpEUABJ0<=w*O}flCzx=tdp6LvDAE+JtC)B1 z0%))n%wk7Eg@At6+0m+kbGzNMbZsUK@MFLHg}Ud~(%)7WNcI};-jfiMpT+OchZ(AM zd;N2!^jM7;=HtkNtl~+`$!yYHqZ+n>x6~)t&A7azY)+mtb}LSg*3fnjoBr0thzmcR zJq$lTr3Fc?w^}dD`nz77Uv&*L=L2DR930q&AXrdhAmW1X(V-j1)JOO_i&kgI$?~C) z-3v`&4xcduA0uE8t{HlMB>yqHAZd~_M}P{7ty(wvru8#|lM+QLnh{C|Hde~rcnq)Y zr#A|WN%Vf(ja1MzOs^zu@n{NpA_*A&YgII<8Q;F! z>=u?%L>M1}Cq0t?Razbuz!M&J>S4nld@(IYpYN?2TM;JN3&Y*caxN!I%7y!?6@Uf&y6M+0KIOuDAHE}YG*Rz` zB7rM+t;_+G*=oLl*+}hAG=m{$E3Tcb$Cr`9UnK3rWu<`fFQE{P{`)PP&PH&Oh@tmh zjQ^v@0@~Y};I-%we5GyW|CCDdL;)E{$r+UmR$g!*D(zvFE1AQzu5upBr!4C~$Hr*B zVt{l9bS}-E0F$LMj-M8zfQJ!o7!CnT9T0saAi6!bmIy70IQa_^zw^HSd)DeQLQ&jw z_(NXAU1uP)%6gSCe;i(7)FXW-2o^y#iI>(yD9fYYGDv;>Jcr63 zks(d{)&&du@me>Fy5rRhkLFU@&Bkh>OC;WSB`aWR@G7m`eT|re1pH8;*4Z&*#i|tP z36i72y;XxZ_imVs+}v!~RG_$Vqj$#h=Zt5GVWDPZu0EK=S{ofs^_0(%@4hs^Zs8=f zyR+jQ8ri5zd1T0VTH%YZV&e|4`IY5wEho-=w4*qE$ToX4@WBs_~V} zTP8L;+D9hqe_-yuVf3BxUVlnnOn{00S#x+z5G1|h&#FU<&Hw(Z3IC55L}r9K?}BF1 zGzkdP5L(t6hJPvkFFADYx1nmd0kHz)b|S9AWmmh<#K zeJO{=?o%a0_D6b9xWV{{BW~8G$`0>-*68?dpZzDM`Rv9c4e@qRiDTRfstiDdg&B>H zkr&4*>0lCW@eKdOG*FUDoeOu+PmW%;cRF}Jde1}nHC%EM4y z-C=z!D|a)(%u)Vk=$h7<^|0cZb+3E?6S>=-rtvaf_BqIIinOgf(6Pc+gv*1zD#fv= zE+@O=wWjpbD+5{(ALVryobge{VMoL(VIl`0or{_!aY^DgggCiMryEJJuj^l7T{R3> zO;UIv?rb1G;W*~!%T*%`;DY(7=31Gcr+f_OB^? z91XdY*WUjK9kBmQe1vdjaD(w0XdCH`hfOv6%hZME*E-4?!!#O$EdwHD5FYu8HRNvs zo`~mKi88^KS&^Tg4uD%;>${qkZK2Dt`rHhvY0RBh^vI-k~~pnj<|Ut{uT zN$?7(&AYdYxjVDuf{v-iND$=2nChGm&Yc*70h(0JrM0+rzulzF!Ji)Pb{vQAK4U{l z$a(3rB%gh&&p{t33`^UHF2XULWnaVlV;GjCOZ)iw!~>@A=?VdnwTCs^p^FFU(&&@W zrA80&gJ?II-@~1A1tQ3Tm0ox=_NGSzI((u?`vOj0mVE7FC~(Db9XJCnm}Clp0XWCz z-7Jceow$Z|4G_?75~+09?&^kC@T2S{Agyf#NAo6w=m8D3bR7~fDDZn%Ql)KVv#$KN z(45+gWC48oCrfE4)*v>O%hjL-!pkcE4Xao-lx&$3W$kzY!lYeziUx@pM@>VD)gD&Xs8x17!QPNC+){XC93a zDRL==4rIqsVxdsY{qS`ePkq_iV!rjy2F`&cmTycBr0cb`nh6kP+d)*h9iRBelA`n( zaqKq(H|c|QOuT%wuZV~y;+^8@Ie)CAciSJCHkA>^oi zM22eCKPRSq&F`VMSVi#xdCP+eT-AFBO{!Elhn45*R#std7Kkz%2YYU zGK8OHHET}7+LQn8x3lnfMt^*PO>ilIgqv1_)A4Yw;wr!U`6WiaP!rebotCu+GXQ|b z&__BPi>ptPDWdeY9fYs0qF2N1%n$BOpSR@Cf5(ei@jI_UKc=Qi?>i>~^Z22eVYWBT zNg{c2w@ORJ1sd+RDM5KFl|wX!*3iv3oZB*vE3(#IYxvV>POmy@XQ!5u3g+teGUM|H zXOeL8+@0A9)4y{kCDoeP2$&U5a>tCVNvHDXTb`kQM8Nx&bHZWEikqg*1(~l1#Sis( z11b((<0zS3qzd^sBGi?o2%c{Zqzki>tDe@wYTAyoIeWNoqB4 z5APxOc6e`(&YmYpi|2a?lB#F|u5mmQ)J&7sy9fonwLaN=q?04A2f|%EB!Q{-{$3=W z2tpd~VlHDh9Tqdcd&8Yz;JmR~qh0;wALlpe`zozxJ=JAOzcEwO4?o(1dew0&+_P*k zXknG0OdySu01e|5==c)tHa|vW$nW}iuGDW&^`2hp3g8oRWh|xUxn5|3hl4(rF9#N$ zpLSWh(%}t>t11xh!WV$@J7vejhgga7KRKw}UG}|2MHH3tLdd3`qQ?W#k*fQ;{l9K$ zbS2iKQT`w=iW3kHbbFTlu}=*A6j-$aSpX-7>C0X%llc=^!KhhJnM$#uf-^v_$}aCW z%M*W|1uTC#*&JFA3xTW>vy73tZW>^|0&k|szIQ;P9Yn(6Sk8GlDd!C8Z?EAEF!;Xk zIG5N4z&>D`Kmjw#Y$9H^B*Q0ddHTLyaHQR+3H^Fu!d2)~YCfqi-S@!FvJy6ur%Z09 zXKrGwo92Lten$*RjcBt-xD9?UQy!~ui3N6w8Ii8yikzlX{oO~(s9W4gOEv)@{Q22f zr5&>N0;K|#*Z|a)7O1)j7|q?NKH5QjtUQUZfgq-NED}bSmYfsz=H3q%-0+*Kj zD1o>gIdvv*gucbWJ=`0ski?`6_*#=}A}ScVFRgqhGr*FYH=41Qf261YXna-Wxcm}d zsZty>B=ALwKl=zAHZEGDD66NIz&bRro{@w)`k>Tgk(B6vQ_red$yMB>eP!p`sz-|R z;PGS+^q)eRq(ZxK6W5Jdzp+$v1M1aCh|+5ba+3uF9MWcb=5H>fc}5!J*pNg+qN}Y; zs-HS(E;zV(M?rYX-9*J9OnLX`m#3Sr_KXBPJ*kSboH5W;Z!}zYJ+`jZx-$rADhFAa zV&CaL205kUUL69)X|we`Va|SFKziM2OgC;@%ON7P1e)~`+ zVfJEZG(VLV^2XcssGk5p60dN{pX>~iAdr`Cf2{N3oA$eQWsy!VJJM}1618cF!$w(f zRz44VXxX&pcjm+5DV!_0Ay1i{>ImBZqO?q)xno`IIfMD1jHCa2>{ffN?<;p4;xF?1 z^am3C{ACwkn?qH_3)g!d@4oqC`3I){1)#>H%b+AT*3MKP-Kgb;eb>!5?{H)Wm=qLa zNXk=D!BsJgcP9TEGSn(fc=%^hy#9|EqlW+V7^BGlkT+;d0Q3*JUf)ZsW6H$%#noox*Ny^kes3z_&?{ zz4kFJzgqN2ylj4Gtt(b(VW|H^F#B^*J7}!hNv{?EV+z-~NZ6;%#;4Y|EdBBV=>%bb z9ELs)x@*JHNC5H=T77(@C#)6IaZlur_Yg3f_gCsed-7m@S|2cYP5aDU*)e-)G2ZZC zM2I4U@h?i6SipgSPg1s%+iFru`KC2f$@@-~Fy6X0`tdWBe)JPyX-$7BKe&M3ZtRYL z0_KO)e0sNh3`2FdxtwMe$2)mK1Sn=Rh3BlnR7@zhvh6JugD|Cu+1xei(D{Z|yFDv$ zNkJ0a3qdZTD)$gB0d zRip2PCGX!bx5#vjjoA#i#<8b2Fo|MXG&uZNB@BA~8HgWCJ)eUX&rN-h zTG(-}?sflF)PjHp7<%MKVhKoxrYph@RbJvDS_C*2e2$zrAdJZ{avj!Coks3 zHMf#(`4!%csgJ-k0}E5sq<6qa(=$r78vhN}!ee$U1N593?tj+hyisHqgBtRQqsuRx z?B!aSl2|vMJ=SFUiiJL7k>8qe$1VrPPHa3!l=*6d7UT5~R8w36yBW!Yw$8Ip#kn`T zy=ZQDS39dE)OqD}UU_$?3kuT_DAUkTHSC5j*;fxC&wA|X_?b9$cKF3JRFUGk-BNZ@ z=_;cN^z|+a>jgp_(mLaV8KJx;>BTQIRlULP>P z;rTpbJQ}L5&a<;^+Qw+4He~Z|Xcr?Et-X68VpqkO_GP{O(<3^ZNAfn5U&^L<_?kJI z|HQ|~sbEpYk2RpRIPZnrU}r>~lji{8rU>FueqC`tu*JWgYke4f7Qw{{bOGmIjpL|D zLi>w`O=*gsrwHH+;?|ur!Cu6Sc~he;(Z8vvXgw7|`WD~4{A45&!{QPeu|po}L7s#C zFWkp7U>P>&sx4~@Pc$^0Z*O8OmzY!`x!iU{2O%xuH&KXLjHDP`p2i zc^_*Aob4KP@YwJvoIa(X^G)+m$V-v<-8;I?4wNW_=e-R*e*7GEFAPA7+~b#J8?UKt z^X$(NR)>Xl=?f`zET$Ugntv+`G?$!Yeen$o*Vb3oI2y0L z6Sdenu$2i%0o}3;Nnr$7&?zOGoJ~O50vjeK?E(vJzflr^zb0O8Wnt?V<(!MiN=Q|t ze*9p||5vM`L}HDWq9ASR7)fQlrdr7RJC)I@PR?{{wDwdw;EsUm+yzQ??%>$ptQg~W z1Rg83bLxFHEA3M9p6{w$$}*b`Ov{4jDa`cq>`NBS9{hRJV>t*X`{f?nLNyIG(L63sj13d={ix(n0)DHd)I z>>Sw1R0ft3dUIUu_8+(%1%7^+X@0!jy(+#W3TpSM-fvH+d0^uzd#ZfaU}FK;ZMrr- zTr<3wkIj9@X@z|YTEP^0aiYD+ri4+6WZjlee0+C%33sA;_jMw;Nz8uvMoDj$;W^{5 z_*_j9j=AK7dJw$t+QTBcmJ?Tvs!RY|f*IoRb^SO^cpvTF`Dti(Qh|abkZ;|ye33P; z6WLhUO)H+5SQu$@1L(fE#&1*q3~Y=H-)4Cu>NtQ!{x%d zmya}dxtrz~8GINNAwO&j_39S{LxGa!Xl|#@HE8FmZnI`p#_)#<0?-9|wIHm6q7f0@|= zR-q@U>@{el7I9o`y|);{`&dgce(9UOY28a%qRHk|7G{DTQfKQkj}*{1r1kUHJlbV9 zHr~};nG}DPrIvmE#Cmm+(OC)Y$rA=~huQ#aE3+EsV!?bh?^I6%pU=p1JAdDOgI7j$ zFlG8Iv@v2tWsJ+W%=}i?UFcX$0FuoOrUR+A$Ky<#wQk1;h|A&S2oThN{j%m4%ua4` z(j6{`h;ZaebWn4((W_KQz+uYXPi53VusXXWO_Qm4zDx-UX|t(YNeP{L26z8yst+v| z^RaYFGH@howt;LvJMEDdhTt#8$9yh^1}90~Tw_3!`;z^kGF2Ha<{Uqyn!>Ukh->E` zUUpn-6Z;Bs^Z3-QW8vIM^FcCB>0Kj%(O!wABjd6iW4f4Dw0sVChOS@Z`dg)bzl#wQ zGf9#Oi;?K&J42b-XJB}`i!6GXxqd9mBfsenKW;`c9l1eY zC{*}nGTkEl#Qf!Tj98Z68GeZ`wCB_D_I;gGOyKLjlWD$jjO>4X7(4}<6MI0M?SGBL zXIP4MKcbN8O6nd|1#6_+Yx}QQ6zTQq(>?MaF!SpmMVZM_>z?7#pM*P^W&U7wDWm!0 zfBm7>j(7jx-Hz}-!}R}y9Tg6?-n7!J@rE|?To$rq8MJo5CMf!>($xHh%(V2-8gt7w z?$;uDNf>&Xudxc@H9E3`^rb@$rPm@R_zLFH!J4sclg0*D;+IP4PC-Bl!=N z=V8p;&eOk1D7{-=F81$9;jZEE0X9xSp~RH)ENiCJZ=JT^Bi-J%GxOO_^BoJw|N4sy zO7e8nzRmy(S^4i_&A)ul7T(is)&WqiUg-_pWd?Xk8PC@;ab~lVWbryyk0eu4JufB# z0Jc9T8W+`DKbzkYkld7h7}P!=vC**dkSYbtbpY7&YZvo!h~l*gZkljMqJH3iRU&-E z^FsJ0CHRMj9_VS=G%ESc9fSHNsAWu=;!t&yE4OX5xQCKmW=~=tX~dC%`=sWFy}cOi ztx$i`&sUbdHJ_NyumuKc)ERZ!vRLDf?nn~&702rGXGm$YW&BuOF68WLG+e}Q-26~{YsQ+g%7jdF);T9Nye=L7E3GAs6pu^K zfqigfR5)+X7q%={SWw_RHDuLudaA3!tHs`OT2y-?hR*cQD3917nRf*Kr%H5URlFbM7*%m*0l{CPKj6d9ne7*J5a zpT5VgH$tpF(}~N;5mZ58;qMS+SFyFD%<{T+(ruB5(XhkWzf*iR9@kzJwg;aqxm^q% z2nHA>I`9hqj#6AL0)kCK;S`aDv3vMjc0R2y%zN8P@;-nMHaXu)+>Z}F4BKS;?~4jL zt2Ey^=nK_ZW^qW`s?)9N7fKb+^p>Nd|H(j4gZs59m{d4Z!b zQfY~j9y=zU9B=x(!!`tPci_rlo_Hd&$E2GBmOH&c%Wxu0b0f4|GGzc?CRoMkhxzt^ zlRw7TDqwOFpgRwmamuma{oF?m=L3UY4Q|Tkd_SwE3Ql*Hksp#7KN{V4T2&B3z`Ks$ISb! zlIIG`2N^UF<(ioKu4>=)5x!Dfp(|h#X!_`}fC)9{{3ZeV(kGRg&ex%}nc}-|ibASX zOG)4$G*}eiO$=8LpjabYt?8F08&``$9Ys#8vHD=l0VHZZWMRkGL3h{^Rl{$?A@;9k6Xcg2QllPUDQbMMn-gGFUMR@DOiIJIqqQ`SPs93qz?R6S zT&4tTXlHnWaS=~g!lsi3w(U2##%&oqTm8|gEWJ(c#xU5BCOHMAI{v8MRW;N6@y(UO z=o_k%8^XES4L%uZvSH276xCBM z2EA(njZNjHxGe@!)%Jdm_Q}-VE4b`sxSyG@H=^c~XtnZIiQGN`|7(3zrFbJ|hPlMr zMhG8NjVBl6;ivP#kf<84+MsxII7dDq^VsF=^oq_BlR%*!){O||E%SPd+TVbc|NR95 zY-#9(%WV+OligzyYgQ4UJ88cFO|s&qEpKm*9S8BJ{xX`;#AC)+psr?RGQQ z-Cqlrm@;wRFWZ>sF}0EJ_~2-)X-zb&N=yw4p$DiKb?>lOf(O-!W+ClrQHL zu6RCYA>KPG4WE=&Myeg&+v+oJS#|gG(*$cZv7@wpllMJMBYSN>3FDMnC4#&mb#KTyTufp}w=>%c56-g~7qu|U@h4eppGS{?6UZo$aoaxA}to;HzG$b)57ih3J zh*r8^(;g8Czc%;iZt@X~LZ z*54&F@t%~|v>UX^yd~+#MbQdW;gVl|xmUKjtoC`U(zRgrEgM9C*F>kc#w3}8LNP#z z9Axvf^$Ar2*Qt@{PFdlb`ToOVuC=OUazC|p6qCRhDcGTM-Y*ve0ciE;4z^55XSpD6 z#zly$j0&V!;vj?u97ke0$oC~78U;iBF;-85j5n@0k^&@Z8wFDL*Rdu?=@-Zp-LQt$ zJOkz?A)E4oM^OlDz-h*2Vwn|%o*9%=W>Yxu*4;@G z(w{S3G_zpnF_#ClH+1nfeoNpmvyGz@^W0$o8NqLc2}2rQw!e*S&foRy*P*=y-lcKv zz|5@Nv#_xJK1C6u$uta^(fREug|VwjOi?h+M|CmmQ~e=OZ63FeEgSQdER^9eGn4cz z8-^5{vzp&+;ty_04O)Ek3fln>?aSA`N)L4zH3Bu~;lQLOu}U0=2rTbz-| zmv=45S~0Ew)bc9Wz)Vq;4}Z5>Wc0a~>R`8Hp-qE%kxlBSJC5KfUD0|4z-Vk#`rTr* za3f74Vfejb z`Eu4Bj~kO*pQuT?*vT)htw{F59UZ)DzSw6D+@}-u{bJLyhTatW0{$YC?sX%Sx9`!{ zJ4@-TfrPz1>#zG9X9*78!+pi?a>P}f>W1XTVF^Ke*oXoy$^K94OJd+&vnW?C&TjQV zuF*{`E!(5|l#Q_66q@dZVKG8ZfiTw}=JgW>cWC3fDef7WRLb~x5W zvXXt7x=Vkh`d40$dwXkn?bXy4m2T%N=1H6sC!M7C*Wz#QU)Q_&T5xnfr#bEvv<&{8 zz8q$i{CTg5iIs;#CH)!U&ZdF(_XFO6J2yMKXz`?Z{>{~egLfQS^<2g9>4`jkjjC5y9lM*EjC<8Z&ZD=juhwf1J?a(w zf`20^!%}RYnMDwK^CzBUkrw$gIq92q@Q6=Nne{<~p8pqXHl)(gz(DW|br;DlN7sc3 zdT^d!*VQa~dzi^*nSfW^JQi9E!5({-#E%Ob;5z|1U|GgZgS^^^q1H>vrQr^5nKg&D z8)uR5|21RTi<&I^3zQ34?Rg&s-a)wa`hyBPc*AC;pG~H)E~Q^f4)Bb0JU;+Xv;VTN zqGKizAVOFs!!h+kdMVLBH`6g1jj=po zw??XEGi&j(2RwdpwdxQ*z{^s!AA=FHnc1xOQRzz+X-=2n>#$v(fmC7rK>!pw$$zjk zD7@*iKPxtmd6l~w^62qUaTZ|m_;QO1J)aDxhWU-Fif_yw0YGxxB|nB`zTfP>dlv@5 zjxQ&N+{30GID))@@vgOX*7CPCSzMU9Eg+2W^3q>Rt9!*E*@LS&eZwnZ4IRoKZcO zsd>o0b3c+tGw87K6GpA5Xwtta+tOG6i+tA#lz&u&y9yD3HsQ}o$*YtHS;%HGIjQLV zA{%po`&S&(C=KD!H+ZXF^nz93t`jk#(z1$0T^1H3cZkfmQUX#)wFVpRtlC8E4cz?0 z%hncZX`03DO~B5!INW}wjL}@^Uu@t_u%Sjf`(o>RN6sy-l)IVVk~4R%;aA!dBp%zi ziJ!JdKyAid!{3C507v6%>d?gVvM1es8B?j-CFO3cv!)rz&0U+-Iqf&J&V$M|iG2c+ zaezz&*~Cks|4Ma$wd+qZE{<0HjvpLGXbBL*mjsf61IiwizLD|!kXZ9fRFT&fP6uUa zD6KXcYTM>?Pw*~JhELp2@@xQg_SGMc0-d2O*nXe4%n?0wmI7$~Rmh>fsF;sCsWPd6 zUZPKP!I%NW1J;`XHz$F6t=P4!!i#>v{X1m^a{Uou;9B*V#^wefkQ}%9diT?7^M&-K z?Jr^ThLDB6QBD;aOnZ~==E6vulaw0g@>KnD2g6vmxx6*fpWVEsPV3it@XYpI=_H6j z*2(HS--~a&+?dp;oDqoZoP;LSvL1x&mlJoX#B!bL5)}YQEF4nN`S;3L0}{pc z9O8Pm!Q8S_r?)DK{~vhKkgj1K32m(GsaEjs2Ubq&FOWDi===L@N>fzPlnLoI%zPx@ zgSe6Y?I(nY4Lj8&HM8(uu#ARn4{k94Z)*068|_C0CH0!yy=BICfCm5d*KnGAyyi+_ zaa708QvP6K&q|Eu5`^qx0GhsRoNv%F?=ME-I2b-Q8?^(`gKlw+XTbpgC1XEvR7iYP z=FE!p42Qf~Xpl8&fK4}YyvSx`6WeQ+>c(0q-^en*{h=yQ^YAmXX8h`JD!a5(i zQq6Oc~EgiFADEo|C)ISNyo%LJJ`MrN|*i2frtX z=YhLOa_R+XP&nQ7I`KW*+P~C+hkjc_P>G#=E$ngK=Wc3RaB7+uSopHQW~i#F+KSIE zn*+a1+}gR)&o-*VZ^d0>H|msr-Y-bGy7x(eAZ2mpYEHWZO+MDKf$2qC3BXPahl?YM z976a?!cQ+XA-o$LC&C?D$oo#7nv?%j2C=1NPVxc}ac++MWN>!L@>=Tm|7`sKZ>%xw zQ~uC*%jJ>3mtWBYd!q$W1^%M{{s+tS6RAf4$bA4+@5;zC_pToIr--LPfMlkP%&QB+j%1ha(sZ7|pK~s%V{$RA9r;g0C!}xu`Intb z&s+bMO631__8Q%W=d10N-?59!tWmG;+J#}s#cnk`Z9?d29;s**Qrc$u9bABcod~pjPAhINH6kV`cCL&qy+D-C zZ@vF%G4A2Jpz?_8N{&i8rW=XqwMhH35hKrj8swULOoYrzR*r<7(%DE4G1YBP^m0V!tS z=P73`Q6%4luy~d#%KZrW%4ok>%on<{bpRQ^WwEIgGvX^p`iGXB`1-Z~b%-hRuo7p3 z2^M)Zw7=`PdH(ykG=EL9&tB7-murajKBWBOl9ArCfpgem){niEv$dYaANXci5HS(V zkRC;-W97R=^4=?UFR_9YtEo@=?r1q(LnYRa%X4dmB8te+@B)X}im@4y73cN-=zuB& z;Rd0fHwjuCwkJDQ%zAHS_|()k_ME~*RX$%uRo!pw@e}}M{CkHl`bx`GaW7Y~2LL&x zY2%8C?r5eWCs%pF^!rI;dC}8zd;)(iB1g zTL)Hlj1#MOMt6;vnq{?Qck+)YU+g&QedzN-kB%2p#@rnGh(Qev$`0Adimz(;TzbcO zwZkD_dbh|=>pPK4<9ttz7pcx;ZzWn^s-)_0?mrW`m{FtxbLHVssz|_9D|dN+uaE1z zS3kmW%vo_AuH&YKHGwJs_kaDO*Rs83!b0LUX}pShkZ1|7$%i|(=JkCTkf(mo8+q^R zZTq*^(kROg+Pa*KzG95L_XK{=#OO4XjyhhyIF~Bba6@@{GgfJg8dMT+tWUMohPs}3 z+&Xrw8xJ>-B(@r7S2G9tUH|NF6SG2M0s7q^#FsjZsp@Z4Tp_68_pb0-)hn`rECT`- zuH>twmCJ?DZ|tYAm6oZ#2jlkDbx6rK^uJ%+!g#&E8|awwBv(-EY##_ID$9Qv%Dj!YVykNN~N_)-z_NJGb?xf(gRn(-wNBS8Zv3^5z$e3^u-KeUH{a; zQ_|JBTu^lY%#cuE={zL_+DMSxoxK{(F*axzGTD)h*(!3fIXJUMeet2QP0nO|3|=tR zHyL~SYM=sjM;*;;B!V4)D-X(x+|>kEN;j2|2u3<_hRh7!{g5*of2G7z6& zqeKInFc6!ANyN5Ol9?ZX5x}ptb><>`owePz$o*~v8x887*0x+ z((x#DoWTYV5u?o;KA$y3oPyiN){mEo-^>rY_(FeFA7>!KD}6M=i&k4pRBOsgt=N$6 zEh{^l$Cd>2PXoQgqn{(^EVs-}?&_kC>LbrYPv63BAkdfqP1Eeb4Gb`-N36GPrfkOF zxG)7TLOJB&fkO28*8x*iYFQJ4@G;F< zvl`o&YSlbqJZEMVp?km9M^^JTgu24YCjP*n*Sff;GUwi>B0*bp!B0(WZK8srU|p24 zC5WGSo$PiDM-EK$gjyHwtKo2k`;_xE=kA*v=Nt7gK}ss1_w-_L;;BFTJzu^8tRIjS zJ}K&&Q>E^XLe(b8PK&12_Y4gpcO!5}F+H;+zLcUpm$FfbH?pSvS7y%v_uRECm5Rv_<~;Vt=Hf?&m^~m+uI;mcZ)VO1>}dPf1P*lz2p++uHbq7_UrS3mFp>$j9E3&@8oX zu-ZHJJ$0L2HDS4Vl62qBZu!TsG+N+7N)=O|Z$l!FBwHTZi#fqValAM~r%LyQRg)s8 zA3_lm57`Y-4N*)mm&QCh<-NY1W=Y$bWks9=F(nQu8jPF?mV?%ysxK@#uR7v?6c?zK zw+OBz|4^HK`A&00x$v;Qpvr!Y#7gou5cY0aRdb(=rgmTl4R;vJUS#m^xM@_g$<);D zLauCm7IZg`SDS0t8qSa{&15iQ7@IO9B4UYW3Iyj+k}1U# z%l56Lqg#?54$cc5wNiD{CmyH+&>k>pcQV-5>NSk zVPz{7}tE zmg$&Mo9X^h6bU_k-Rdj`^|AybPV)ZBTIl8;QlOMQct^GhL(F=maIMH|fEJ0Fpz{6b zJoAxC>Qf3Z3Cbe39Or?)Q6){#ZP~DK>59s;c=M7gZ5u)mFPP?5l%~Nod*_8y1CsCK zfcEBV#`i$7=;k!8N3vQsJaUg@Dp+O;c=5PsS&OSQ11xQjDsFyu*ZxO)+XcdD^}AH$ zSqYcjO6vBgqgNXKo`ikri;NXAI_ElMf@{$j@#T`MnY^X-fK?t%a{5P+{uMI9LDdyH zBWrFg?58P>ax2K4L4l>FM}1;z;$<(S<;AwatcKgpDlzfLa^7vZNdKhbny|b|_L2}0 zd>Ko^ow5NYP2~*kdQMMCsR-uc9~9PetGgCz>5L<@tI@|z7<8RE@fMLfn0NV z=m_M*Crjdq1Wq5DGxT@yf5EBq)!@m|=fAxvPb8WHl8QkY8xy3B(C>RDn*Qq-jCINM zyPoJRt?qvbC{?-dX(shOI7#nToLJXye9PaFlmtK~_*n71-)q5%-kRQP@{{HFCoeyE zmuWzP7!>r0|ELaf`mIlW8E|vXhIMt@uI?5B720~U^MQH5$#IL!B*bPxL^vZ=C z${;!szTuxE`>Msn?6+&FeLua;_=V9PkeHOII+nY-h(q<$z>+NyQ&E$7pLTnw*1eu< z*RL5FrPUbcM73DfOb1sU&zR^v1Uh8CPBCzao_^ehYWbz^B~FhSQFV=U9`Wft2q2hw zn=(dNzC;!6D;acO$4c)R@0A?4c8_I@kB!hsBI8M>!ozUhc(y~D4z2keik{}{`2Zk6 z9{+iWljQCGRgw)|pWn&xEcdLgApWlhn5PjZN4ZG@P$S|Ir5F9nl>qZe3Hnak>R8rq zDqB5Q*cm;h`>t(_pmMzz>)Uiui%33bz7E{A!KOhKcYSrL$`r0_yixmwcin`B+=bi) zWk@+?p|*W(u=^1jNn^XZr;>)yIkIwv>oQwVoop1n#YxY^>i#x#spSbq?D6NU3AFdD z(Z9+D6;B?Jr7nnGhy=I}WapR#?sU}!}|6e5k2F+^>otFYjJ1Yl=|J5tA^UFmX zdDI3RKH`0HZKw2>sS)e_UeCjZZQc^AV98H70rgVEMbo{Bm%w8AaH)9Sz|X~(DF;0D zaIgix#0j{GYD)wqCI0$$*E^PMwa6eWiAMdPE*FO6em<{1w-`{-GtWG7?T2~*ByuMQ zWX|I~X1OOBhr|~)H_H~TU!@VVw4k=Y6Ukjq^{}I?MdR`!JO63>c&MdiyBDUrK;J3j z(^6*L7Jc|rpY}YB=li@NuPWseN)^3}P-h0Ydtkbgk-6!L#!|k~o z&(u}Qk+XIDof;}@3ccNOw2J{#L2lRED8>Zr)7>!L5i zWMu!)4MhAGEwmZ#y~W$hryS})9D(o7`}W=~%lW00iMcTqD-ro2Yg=Meq}Q1T;Vd^L zoto{6e*1b=Vlekc!g|Kho|YKsxfs0feW;A~Gr0T10ZAp^z)IWcVFz>l%F#Gz(VjPJ zkFzX#ft}Ye4JOPgF!)Sdn*KtW0MMpSC%ErI!~K>AUNRkWf1dMSzIu`*@#XUyX)Q-Y zRAyGRb;VsE5xqRuaxsedO#ZGLyX%yOT1A^fKzqlA=%Q?ZgY>E0$eVU;=Z7k7!UhOA z4w@!^J$R?A{p87$g+B2NqQq_2GZ~oj(FnxNX3^z?&)I29-Jh2a-d5LanBI6`f9LE$ za=_L8>fR(fJ~PBMPrQ`0hT35Ea++4pBaz^|*@#Z#pioh6@M zG1(YvBe<97*8Jssd?$K!?#VA*5e3=`aTznhG6|QxI1lqxq;;1)D;`5x6 z5b95{Xx%cg?t3P;<0)t`Qn6}?>P9mFr_OdKdFNomYx%=tGC}b1Oy_x$*`k_oG*!mGTfcn!!DL| zve@0+-rK@Z{qwigz+|sHx2y)^q-kbcA|b6;vaxrnMjhIwt>4?RQ8vIBnw*}haXoE5 zdD^m9u*6m1c9TT*UrM%QoGyl28p^f?J>NrOdp97i-SD(08Q0-Mf}mP9Y7H99*_bFW24Sp z7KxLb|YOdH$T3OxXLdeN3ed;MXy{ZO8&7-iSySB=P5B!P&Fg|(fD6$5;UtV z1f`!ESYkzz*Tf_|Hv#nlszq$>iVr^LuYH-e777(}FkMy%87g^qhu1Zg60ae9y7|eB zBuK>DOQX4yxY-rymgG8AkND05Q1-$!T2#ESM!~hJ1{S(xvQdsp+ZN&I|hBEOb|04zkq!#rakfTtLIVKe7$B3ymyk2j0o_UgTo0{5p_K&-)HG zm92+*{cZ+YGWBu?s$;WfsxhA@-c-KqO7^%w)NZaqt4caeilqfFxRb5(Z zW}jw3apzsroB+b{>Sb%p`-ckVp6~Z|W;KUPZ8G354paly(-N0vOKav+BZ};u;^M_S zd6-+P_I5%PT@`dNONPnW#ezgvCzYc_E%i6FdKyhe=_OIiNzuueDqf=^cX;rL$aN-){ z2jCgh>JD_fW$T&UkT~07Z%`At>w94gV~0quKl3$1?c>}hzO>w-bEDPf)oF0HpU6K= zAP-5sw9X43b}ahp@`K-+x}}>v^m!fOZgh2@F2d;hdbZ!ZFnZxWH7n({*{3~w=Ys-j zkL2h>4~R4R8Ipp z_(k%he6QsBhb!p#r&eahz@h}~Bafq_x7-HSg}y)@UcdClUZ&! zh9=!D)c64VVMbQ?kIQ~t;L~yTU=H6*<(5%_+~xaN10L(g)e$0-sKna@5Cc(OM=5AG z7bx5VcWvKd147{4YlxMs_H9`+l`UdoEP_&ZFtsiSqjGzo3kkvwx}W=PNc8Up;Ct5p z0}q%OH31meJ$K0{YfA6*vD`R0D(ug`v&GI{Y=*g{VYXWuV|32+$&>eYAn)%U4^@Jb z#gvZ^XX-ny2a{(2L@3WNDp$Zz1)&Ayf+0lf>Tkw)4AL9;HsNR!L zW~ceoPB}V)&FR3~zVrW0@W&*$n!Z#B-Hao8kM1+|#_HgD2SiFy?!QZGQHiCm{ePub z269&n@3(SDZnpoS;0LCJz4lkrU@){wbGOO|?_o@jqTL1eYMPg>Y=tyywDQ$p(Y@N~ z=>uCVz-R`!+~QHHO+M>M1$xGE5k}03WG{3G7&YXo<|bcN?C0&3G70SBWKF z0+xpFSJ{O?_*GgDB7os#b-+V_0J=GJ6Et#jR=?qqCUYMt)nDUy^BR+uQ`sk*zC5YQ zAjFP5x|8!ic%ueDG4jTQMFqn}nR{QIm%zFSE$;*+y#0K?0R;U|d(DCkd5I5RwrE(e z@cmDq9Y8r10m*XAVi~=0`hgu zVY))DHy!8Pfp_p`3?EyYM(_TM#HOx*%2%gT((z!gVA6=v(ER(mTdx$x?S7tJW!T|X zVD~2-Bg_JMO~>b&hQV}df8w=M=IgBE!w-469TQh6CP?7SjJrEo{*wT9^L-nU7B z=ScK`ZKFj0VE}$tbK9=`$@(tyc9B&O3lO+=%6~KxJwsbCN3#5_-P^UV0IRYduYVrQH*aYo^ z2ds{My5c>ukAO#)d*S~-5bn|Q-W#@B|9er~$Tf?E6O~Ql$Fo5x&KtmhPb3QcQ8Z9( zh!;C0%qVifa`5NHlgimLs_mKf)JD64hqhU9f?o4Xqmu&Mj*g_Ttpd}>?eYmfm%VK) zy1qYtHSIKNBIZGs96iP977I){@n+Uf)=RfY+OJ{%fMbgz=Q_L7&+pwG1AyGsHu;)H zohu^_pC~}>)VH^a-L{QuJq;9d)1^)1uG};%^rRu5$0zp^_0RW9EkF)%?>wOA zrFG{y0NoUiLGR?}b~?1zK0*fqu|JxeXVuCGtz|1XU+M$F1K0v#_IGVae5aRt-aaBF z`-tRCa$Jpc0dbslehQF)P07t(zNUyov|bKnqjJ@lC^b8pzl1U(U91@DKW;-VoC+v~ zD%)Z!IErLdu7fiKw)!aG+a)H)2Ux-Rg*#)vkYPAw`@zgofIqqA_bBVs4&&O4{sxb| zh*|L?UAN@BTXAAyVhq;d+xJ$hyV|fZ*N$;amyWamY$ct^NO)8Tq zcpCRzKH|y2oZu+FsD?`wR)e@$HkbloVo4nB}UWP|uL=+*xoIHy+l8_qcjKGmPK z!nLHx_LW!$9Bgr2ZKm7yJTkjwlU#C3)jLpADP%_XdGAQ(C0mSBo$xeuVcAbU5?LVLHh2YHVYuGP5ppTZ>h8h|gJ(VFe(e}DKj<>%1w32$G zJ)BcI_t@{?qs$(JT~oS$@7{ffB!h8~0TXt6?nPi7tv9P9-1{q-p7JH${(lJ35Us-t z9_2H)K;FjaXUM*x{zfHpM(lR4pYB9($lE_U%l}sqn!}&jGl?eJSaoxrZ)79uElHVa z7(ts(jWmOks(tQlI9StXqwt?v=31i)rb@*nO6$fksC$kmt5-_pq3}Bg7xh-Ye0cax zO>@LUsEV&1ASZ9f|0kzWv$w~rOy81gEYk(?g44fxDb(qMGXmf?N>~Hj#^9F^)B(EU z*aPB2o)Y!yGeD=5T;xVPesdTGPpR;oQ6T%My$(MscL5t$rz7B<2;a;i;&ro$Vn?`5 zHh;do3n_P%ncEIBr(_F-j+-p=8Db{w{?1-w1$5WBa&j>vFZ!7IMQEqUTcRfBSBtWB zne-O|G#sZZXSxlkGl5C_-O2<(17D??zA0dkz}Yf5d;3>X40Si-wOE4+;(jn711`z}0+a!5a_SvvJ8p>p28zDpzr^pCM|wu`m6LdZPBWe)u7`^?YaXTQ2-Q;S!|>HDQ=8@fYpv&xdaQOa=`IPvJ%NloGNab8LUPvxNq9q}#n! z=GN+S>v7P4w3l9fR+goLAKo`#&LwAL`D@f-M4nqELe1ZMR2N8FOe31>#Cu8bse+y&xvw*E8 zGha){qD2+1`OEaOFujw57ypBAaA5fr8(I%uQ`3~S3#p?|5?JK9)Q5%6dluyjIW9tV z%5H-=fi=8;q5-d}(oPvQ`#&!8J97mg(HO4c+aI5KTk>kckeLv~0Xn_?O@l^`+vW-N z=0tEQ2I`6aHo~3vjeZ?r*gHv$I69i}4A{%?){u+K4+1eT7(W>;mHb&E$~IgH&;_#S zAslZ0+gA&SoBoUc6AtyuvpCzI$UBWa{21%K0*&;N5W#~1KY8HGQSbF`x2Szyd67%u zqradp@>q%Gck2`I@)Ge|;2IHSuN(Bl0?sk4M1FS&cW1o^WYq&%h(ln*F z`0cWpr@@RHfk+0xO4#sG|`-(X!9X1LcH#2h<0|q3*fFJQ~3iKmzSRVK1FgR?IFl~ zXDW5F?e|>B%m@5f=oeS5T^X3=E!oJC_!NOMfQbFng$N29M4F|$m(v02OB|qEEy4SB z_iG;OR9?{1Tl{2$`Q!1$@c&T9w-lG=huEoqAIiu34^ZZS5Pj9F^S<(k)kh`%Ciov2WG8?{yXti;NicO zS8_R_LCAVz__WZT_W%LTW9n(S;?uX`)0Z`7f(ZC7=Dr%)l;@U71^jE6x{#&71ew_s zh8WUPrTRJYk6hV`$CoZZ>y^7wm`t0cn16JrXpfPv*I&*!E$G`NrrmNN=Ivjz1Z$IW z|CQ;dRoYi(Y&8tI$_tW9H1UfD26`g16i@(bjDT#76nKh%l6X@d9YH%HvF z)L)Yp(hje|{Q$O>!h)buNwYMtM0M+zZ4+WBacj&49o49z%Rh%KSv4?1J8Q^g7E0o; zlQlU4Yt~HeLpUyvs=F6D2#&Apvx|pdCt`F6?)%{kT-$3X9K# z`t60PyT?AOz>SQt8jYLuFL|(E_0ofojD->Pzcr1^?B5t&{B^&@&?q;~&|U!aKh!b# zWlsh*WT7ZBvaO<7yD~YUKRUCWd$fs>nD_vfWJiu%O-<&G-?x6+$efDacxk5nTo^Q+ z3;_vD+b;pe22!Ak^hZPUNRG#u7<~N-7J2fU;u-eBINa+ICkvVP3gw%Z6J8()T zM|b7BL|5%SViQ5~5k( zs2F`DfC0m&H6*Nx*9K4?0WFs=HDiy013R-kv`UL$1w!!e0lPxMs#Bh?Y`J(Fd4eS$ zFGk|SO9!qTA+Fgg(BZ?pZ!xgDnmSe*s^LU?*oE<2RC9(D_|*a{UB$c`h(uXr4K*ar z?Yx5wSRPr*nVBHu*v}nMZ8|(-`+xO=^0-ekL2u_CwP^r$W7<(X1LFn0L8B%y*Oh=% zBY6j;uFDHHZm0_h+xuWm6K?A!i51Bgh74INbh^cV30Nz+%pzI+SWiSj<{=p1P$Jw9 z>ZSHA###zHk|gc{7AuJ1*p!7EK)kQ9~rvFFYWq~RqocD1OwAHQQBr*IS1D0K$||L71a9IVqz4% zHukUNxeDAxFP&jl_!Z}PJC6xW27#we(<`eladbKs)9-xZL}rOcaO8b@`19ZY z7YvN(fAD|CnbL-=)E7p+lD@`q9SeG)4e?;2VMhG|2b0#{MxOw;0Pbh?Mf*l{)&B_w z%cYazx@S$b=w3rej_dcsI~LAIRJ@eb`H{b1Xe!t>^-VWB`J%2-{UuM7>ad2FuYShM zRlmpHfFiuI!Td@J-F`vXgI~(%+m$2ryR-MAqZpI(m9=MOg+{^tFalr^`0E{A7yIR{ z!g$X@@hwxoGFc{=I{S7Ron3WezTcwdq_}&DRZCL^q>flA>N$RoyZJ5T$&yuOKV1h zZ&2W$RK@_uEZu|u%#;T^e$Zn)RI|vW#~5bqQYxZOxUTbFDlBWzkZnY|{B?&e^*uvWE9nO2IY2*T1$eXWFp^Idwr zM`D1Jme;$7YTSF$>+l5|g@dHpSHxWx{Pr_9nR*$8i^r5{QUpbCdsG^>LSO8-51!l9 zITFH;ZI_j>@n90cjC`oH+*A`rzEB{sG+!mYT_{Pcae^4iS~c;f3|OVlx*5>Om81G- z7lif7IGQ;aWe>VOgHOKc1G+w|Aec{7Zd#bHO7rg8wrE|f28f*Pic`mbkXDJF-&m}* zAXhv_-$^fhovo1fk$xD`vaTtE7M%>h@OzR*$wd60+15EM@TJ^$qa-%qeDgF7Z2IOO=iSLZJY*I!rC zr1Pw)WcCCK5pHL>9J`u+)$wbKC5Fc>P>j(b2JdEEJtRmt;l_WEM(v~*cF z%216kRFU@jfMX(2e?_P}VcO?V$T#aan;{b@gV`Wx_a97?29jd=o%@})GK|pGy8KxO zZ8wwcW;;q{-4i&ZM9a&|ojH^WJlo@bWgWY_4t#z7PRs`a1)J**h(?1(Qf+lMEXHNM zT~>_SwIjthT!qqFUwTV%z?8w}=ANAm+#|;+(3fDG*Xzt2PREIN+RZPk*Sy?Kz3FcyQh&Hxv~YM>uNlU} zp=*B>$Zt3IfoZjnCd9R*pm-n7K)9XZX4}grG1(9J8M%P-bYm(= zGQT)_FkAy)WUh$4m{A{f1UM!s%u#K(7(<$bI6$&>uEg}ly@H=j&zUie;=S}oMfyzc~e_wNKHoVldY(V5d+VKSx3f8@m&SagDCE8`3h7F!Q zWw~|;EVa!>2T54$%t8sg3X8}twXQ#_)KU%6L0-r)FW+nn8Xmg`N-BwL64|I;tPeBw z40JIv#%Fs!ODcd+eoR3E_pVKkoAz=2kntNHn?u`@XBLd%5I@=nBoYY;^xldpx(C8a zkR!3wO{I}tJ#T-{a*cE(>)!4@Sz+RtP=;tNlGhlHd_K{LC70s%X7)BsFy&!;K5b2h z>xQc{#ReH@LG^0cP7JT3=ghq#Ytr54J+PqME1^OP;0XxLUGB zOK`9^?L9b2!bE&?qwR1GqGpIJC`tDs#RhU>21#Sn6p>)q$rG=E@M!A{%NO1IE~(>0 zrr*VH^~$ZKv|ePln#e2=71}Dvu&jIT#Ft}YQ9-E z0k3Jf1)LPPZn1J?N%lP!Pk{8`3ddJ)R>G$${M&dVO)XP;$kWRW7OjUd{Zp=dc^@h5 z6n}@>(h+%+yqWXCDPICvQ z=7>VI5B#*-MKPmQk1u>p=qgICyH88-te*d6N^K)}ak)~aKFDX=?H?RVB&@OD2Xz#j zmr(>w10Uqm=Y(ey^V&8xYje}Y&5BDST2SH=j$8K?2Sxr$1Rts%#=}?1?@M)NLJAm zch6Dha6b0Up7q7EgxuS~x-K;$+1AI(2GS?>VllV5bb{SBT2He2;JnQ!-;>K4VFu~4 zR=o=1{0>$*%v!j~pUP7FGV2q=fvHJ#w}tX!G)Cf6q_$w^J=X(ukk(`NhMUTnvD;%9_>!fwe{{&0^e*t~v}cUNuBW~eTll&F zl3JOQ<3d_bBKS>$#4{426#QS%kinxvnSGr5s#caYJf8e$ahkNRj*I8l`MsslKz2yr z^X~nM^FCDSPO9GuiY;!~G)OKM262IK=n|;0vq$L_UoScZY0~nnXc;H75?H-`AE}6> zFeS+U8jg^0Ul6BAhwOa3@9&~nXF6Tuz1Vs9lWVir@|e6&U9dc}JRdB7-hCaI60fCm zfR!_0(ZMn?nMVXhNuOzw_Vua5XXys}SQ@ZrkOo79nB9(iPN`wKz57Dob*AHlY_ow9 zSDKaL_M90dfYv_lH1t^;1b^cgB=0-xZHmvq93oogxYSyi$J4;yYg-XRE*HVzFnS!%gHYY?)cDu zG|y5agVIWWwNNqrI2PJd1=^n3+kQzKl*~+sJ@og4m?c2@EmNn7zHZYUjl2DQ9wFvJ z10hH8nKk45wEZY&9e9%2*y6}eoqW)@ul=iqw-Ez0y)b_NU+%))q4j$~Xvc#v^U;7^ zmYR}!Gds;}`g@u}-Ai7VmQvIUcJfjg54>nt_}oU)@8>+^=lo}Edsu~iiE((gmo`~% z7JAKh3bAM7BUH&$e34bA3gYTo4(5+prw)Lz@_Ppgb6peTfe%Vkl&rOp-frUaSyxJd z{nQu{R5qO(9f>T_ZjNzX`ieuMP^k2W+i{RbLdGK&mXwZ7>xpoVty-;dMc=Ia&*2w- z1c*44%kHeJVmmq6TP=cN1}kzr&{K0}+Aa$DY`(o+O|4fvZ2^lzmF7D4;xj&3;o_aG ztx$Zx!Jy^V=XJ7|sWIx+@EEeB%U7pN?V?Mu0kmS-3Kk%;#WZUbeB3*1tTO)Ug5N>I zS`-ck`QH7;SOtRp=!hv-93tXB&C^$2pQ(^jHS}Gt6i1_xv8szP6&G2DSf7B9VQ=1* z#$P$EZGvH`oK^K1!3_N=rRr{N#caMiF@LRINX+ljuBNr5q( zzWVqTr^Qp)8N<1$Ywk?gc0+e$z^0`+%AsclvORcfn&e-+d*?wZB#^u)Vr3K^7-)Kk zJ7eU|<*QHr#^sKu)UUCo0@_V$n6{+CwkH2Eg%kkEuGoEw1*p&7U@Rv zpg;*V;|Y^M=5e59Q_W?buBn@yQn@KrxK$@#v-Cx)$wwQ$K&gq%vUWQ29GGmn^6z?J zF0YEnfgzi^LZ>b|5AK7udb#QpQo1;;5*)2vbw?6G(#M8vFteI=;Il$b{*geNsFNpQ zkCTp%eu)sKmB2YE_1-)nwlfz8<#e*s1XrxHSo6=0xdXNNmdAh6#eAwj!w5hNcmDa$ zIeKH~!(VhV-qqW5QPf>!8z5f2_rU#6;9rEJXy@(P}?K+P-i`Tf9F%T1Z_tHHqS@knR{V zsTA%L+;y8aUG2Q_jxv)O=|PHJlh%Tqx;RM=e0R2}Zi7%}`O3Q}Dm(6&{Dk&n+@`Ob z(r@XSb!=7hfYA!$3p~|B!O7TDq+*NR^61HiDk90iyw27C{tCT*;il?-CTj2+ zM;8Iq-Rhf|OQ=l>Rsm?N4Q5gig5-`yh;+ZJ&rJS2Tko%MQTDDo2!85f_enBwxAO{P^-FDd)v=6t zmvt&@0t7Toqx8}kfT=fuK0G?@0Ke1`h7KhF~KK;1!4xNWI_Y$Ul^(GyxX#yt0YI>GFLXHb|V$AstGe9X8~ zOQVpkaBAAGj&u*3*oX+l9BMoO^2!>d4AnN+0&PZ%wHkd?W6#IR3Juo6Xd~`lTjb-l zDV-=oF(lNQD$SWdx-OqK=$|}Qv#`r-e>hYTkw}$x__5DS*qudx(iw+sO;q6DII~Ie zj#o_lWOG-633Vmj&&G++sL|am{BT!h>kN>JZ0u?~X%oo>s4I59?>%@>ztkKnpR)9+ zC0O0D!ZO>vE!A#+DN{1fZC?=*LI^z^ed{TZAp+IS` z7IJ|nPf4*0upOz|uDicl{y-WCz8+<_`vp7cwSV5()pdY%G3M#9b;ZDkgK;me)NiA6 z$;p$9H36dwG9OWr<&IH(muMkrD8WtLz4)G@nc#)LZz>Sh%J$8+V25~AnPAcw}73&l8H#j!JbHE7{75? zP%*WOgONqM9BzcFL63O;v;r&m`Xv>lV7QF7+Puuj2^(bd^{kD)!AiCSq|_=2+c%qx zm&>oxFhE(5YTPvCf&+2SvxtgKb!)$B{=t4e%54gzviD0ywugapAm3oA1ZJaI-C2yH zWF3I+$|>7xAL}+%#!am=r;K<}kaa}UR$m?jVo+#O%9g%jg5TPuu>%pM!|z3F8yl9F zq&GP&RwPZMtp{8yj6uk%oB+4+ZD4D~ddeNUX=`IYsyG^Hj_=8ruydsvOO6}x3K_?a zR@*iMFjZ(K#TJQFH8kW^Hx?4o#sY<+5}X$v@GRRehq+hS)SmgW1&l7=P1Q_;}F@RO4dL>#54^cOtdR6ZKh{P_CnLKv`VFTMt{Vs4Ywu7ioN$ zH7+8jeK6F20aU&0?xsZxs{S`>l&M?!Qz49lDdrp|c!@V$rCTyrY<2sCK+ z)6Z%ZI^P>eimog0SuX3Jq9yWj^DTevfXg4n`hSAWKHutVBwx!}9Pw~jLF>3Fpw%Dp zgF2ek3B^1d=p*mhbm4(x85Z)Z`d=XNW5XDY?eEN-!~@D$%b=}>$H+G>t&eggCr`|4 z+XDjypSfAR2>CvLQ(-geFr`s*dqM=3eO4H{>F@3SW7_i>d_W0sw0gds&eZ+G%-3=C zY&Z``smCHYSP@&Ffp9;vF!AAWZdNEiyU9Qp#Pm?sBSG6Q+73;9_x|p_NOM>mE*6{W~lUusNvW}+rrCS z(!pTRn70E8(vz#X?|d1%H!nIBhn&}1acM?T?PpsTErWHFYi*}laC;tvs*G_@Etz|Z zx)Y=Nz{VN;?|qZQ^osOyn);D2V`WA>0IM!bc0~^qgW=(uQyoiU2b%?+_>>NK*}-#6 zi6?c}D|x1o52SKtvxQK1B>sR2G_`rG5ztaq@KGj3;b&w^lLKg32j)n1hea| zt?69!!;&p-9^wJD)wdo{DvHuLS4E>{>(9x<1?~1j2?#><4f@ zshJs3W=Z1EqdPL37n_5jopzL7&of#=i2im~$U}A!e;UguKNzH`85U{xLg9(19L+LS2TgG+zAJ7J!C6*QnDyF>o~?<4j^Z6c>GjJ*G~s<7y+{-CH?1B(_DRqANURJSOP6xsC{)G--^byL0->c z@a0agO!BF3|S1mrT@YwbEuD=oULTHQ}U|Zl|y=ql_a}H z_2d9tNAg;2MdbxK=+wj#E}1LfB=NlwVvkp#mJ237m5Ys(&IDqo8j8LG#dE0MCdv-cJ&*twTa~Uh4RL!f*)7)ONt<{m71AV8qZF!oa z;!OUZp`H11ZrVOgxk55o@y^d515 z;?7sLNu4cw3gg9=QmR}ErXRMYPVE^K@Z*Nh@lpD{ay%K3kx#;+RRn2Qn)bzWM@5PL zM=*>|>qtYx+M1jt2CNFqFoU*rc_KmF7fgqfn+eL{!qkj+5zw3hhtrStKqTXOlXH~! z747L2#w>k&C9xCRqRbS?FqKVV#s+t5On|@o@XM%=FY6=%HHaBS-y^E*o(;?W#OJC*h!RdbU8w3 zR?MG%Uk#S0u+i2cHrV@7aU+mET=Z2Gs}C%Do-KN>%}a+3i>bk6XHhaeB=yMC-Me91 z-=f8W7Fvju4M=-TB(WEuAj@`f=E{u;6Bu(KHV4l@Br5i_8K0mA3)0zum4tAcV;L5L zW_riC{q}uvCZ<3?dy-S#*NCL(blEIi*pW>y5Y&I zI`(N~_$Ol{K~i=Mr;}l3%gwgEHcNb+yQWg}IQMOc^}hRu5S^fRYPFws@5aj&g{w8* zZw#YeKd9MHcrE;EFRQ(*kcs(!Ul$(6v)uRn-1qnUS-#Kn-0;?QR%Tvi2n52a ztD^~pK=#uh5QamCn7}76z9@OH+2;ejt_~^dKD7Y;IN*Hk<~0c9LoCbQ9Y*l?;rlw4 zJ`f1oXZrWPcCP{l2;`2FuI4q9hjuIDh+rFxEsjPS*gu+^;NGSCuBzG!eI=}@Q+8Hl zS>3(wlCIL{$K1kZ<8NPmD}#^r##K1xwHcb)-bl7|(P-Gac-hvU>FhzRxk#pCwZgX+ z?30E%F4~_yFeE$Yo^<)anU3e`y`HXkQmm31zDbr>zs5n=#}3_Y|89Ov7LI=*feY!T zq{=3GjMhLPE~k~?D{(@WiCDD*5N-Dj(6jd=7s?qSF&xx=pd%Vb|C=|GuG@&Yx6ZzV zCeq@FdwGJRWrd_Z#xAH7-$b%g+4wF?#e-%+5??uv)~tBhNKz;iMc?^XD9gC2kX?UP zcJ|$reUOh13`%e_ku(TIPG50@hLu5B#%+G#H27BIF;rrIU=8)fX64*a10gm23bi~g_n?}8sb}ygH&t3HpQK^nzPJakB1S50F2shSXy+l4 zicZvhnIDAHc3`>_yVGJ#q|fN3Ccz@*^u8dq%~aH=*JSKW64cw zb}!vwA7^G{T)@eMbYp2hs=%2b5a}FYR+_o3UxLs=F^u9?T?)k;E7bH;f4NT%2C3N` zPD_*s!bGmply+#F>Flb-sO=^5y~yL16nFF_QW@^5B1g@x`SNlJ-Rxa9;_riAstz3| z>BiMiR|CzxAf@=`akU(^ZfCZo~rRxLbV2VP(TUmWp}BqeQT*D z%l@ua-UJk})#7c{yGkpAH|fW1cEg)119yovqn>Ya7uAwRyr{2@@1C_JV>2vsP}@I> zH+fK4Wkow0p@_nEDpWV9`MzEKz1n9o>wYDRv=UL2?4DnUGSL8=(TI^Jr^wGgf1*}m zfY=N)PzoEYA@ZvgX~gb5Z%*DhOFOOG%OcY)z7w7Ca|3O#5UH+0{Vefm^Mi)sdjyJf z?Y7-c-phqMlNqC*+qaDws`{sCS&;(0FZq>xi38^5qZ6wU^79ixgaHk9mDz;`uJiz^ zX-9>F?&8BHBwu|q#z%Sg_I2W9nw>-jwl3(yvC{cyhWjTez9q0GwUYyavDCuQT~hPB z!q%tgO7gad8nUp^6^X$1jcgCrK73g&x{^}ufstMrtJYV76WuCr&EID^0(lHy?(JTw zE!cv6I{sks8QUq<(wI?kgi}M6&!|%=k;HJMI+rDMJkkC&K^BcFO3Mgs-D#~MPLrC< z2$Y`)0wHfmBwvp537+OzWIK6%0#in!CRhGLYMHi-IkjVsA&v&N$C%IasJ<^7L7gED zAO>)>`&QM)!}Yr_n&S2 zk@T^9{sfqcp=W2}`^S86Rv}aPk<3o7$gnOuO2SSkvmKXma(z$V8!SnK~lB zRk7ud?>fCzF9k=+&o-~GF4#vZW3MIfuK%*99^=C8;Me0La76-Y+1a>xG5)pq+U?j~ zG(xAnix#jtSgk}6P`zy1^tDbewGrc^({8}u_qlAN>_BC{!GLXTBucWNb$4?kSlW*O z$D>bLxE@#8Q(J9e=ybRkxHardiCk3PU9P16HTCEq2z@`C)h6&KAr^7e>j6hsf8byV zomjOHLUT6nakcekIda!zy*7dJLBe-xRsUV+w5e|5#Df|4%_LMvsQ@Ky$(OWJp5Wk0 z4mbC^y{T2GJVRs8N1fG&wl9rt4iP+i>~~Wm%{?IR;V?&xfW8`EgPTArDj<{6q!xP1 z7)QHVA?eZN7}LDoCLMx}_UhXrmB2p{cL;8ipSv@DWT>g;bo`Qtb9AMQ5Prfa*J7!Q z?3b6yskeQI!5QRL>&kWgCJE9Do| zn!4&_r!xYSRH=^z5WPF@{@{EAoCgt_FqQ4IWTJstw^Ya+O9GLh41P~HgAy)4A+E-{ zwj0E&8SC@zN;pHd5F*{?85^rSp_;IuhsDiXtFcS0=1qAcY_|i(c!Dyr33ayihycyW z;5kcV=#FvVlC>gb+$^%tHO;(XaA0!V1HWv<{p8lkC|QXRz3W@Ci(f{hs@LPCn$fe% zMj@7jvV>FB89$9M>irA$!lgb5wfBbaYhPD+!baGs_3#Y+St+7jjQQw;Iqs3Hk|opN zhRu)V@15pcszO>Z`QFm(ng4xzhP`1P}(=3mhY$d zU`XYa)e!E8WWE+VEv9+My{sKe{#1?*ZM3bUeYnM6UR%Tf(H&8E*sKUy6}pjxQX;0g z6;Ni&tlFl!C*-h*%1fcWb#GRYv<+{$6NoL`q~VH$ZUcVZoX?6p+F`!=Wi3fqm(aLV z9o1Mlj%jxmkR1`Bu3;C~V0%+3MJo*iF<7kW!daEA>bHxHyI#wO&35&A@hg~sQ0jLt zDqXE@1Z$KE6(q?8)*XZx(9&cr;v5&=2$qaPo9b}Hz|lPaLgg;lj16}5 za`n>Ok8a%dn_64*-BZf6`&3eTEHx%{i9HRqg@6-o-Z}{Bnj7{(FL=FFL1LP>^uUsR zNx?cwG1w~S`_8T&{^9xY!L+d2N{Zi`;wT65P@m#xv*qX*QaHsEvx3)qv-P9C)T+5R zE5&O$zB{oft7ax~R0YFv#9yxxhaF>28{7;i46!ZUYnw!MM@W@nCUa9R*ETr)G*~F) ztQ>id^&g-{f6%S<8ZBYj!z^7K%^j6s$clh#Ga#iG4N*GhOyrx76*bH}=--D+iPyaO(Wh zSlXQbqkS!P3kV6CbQ#bR zQc=)?x1>z1+QwcjpI@Atif~sU2`>0{=_Fbix5*bc+^v3%N#{i9qE@_E5`rf zaZLC3??oXqd2=kDA!yex#t}Z7FP5IkS|qDn7&#A-|Hby+FE7u}E{)mli#3d`Rmldf z!5eQ}*Y%Js!^N9$cdpUN^rVi7Ku(d0<8+4X`_$vYd-CE$SF_&A9%}ST*{I#jNl1S` zJ7l8gg84JJMIzFDk!(Sp+rVDa(CCg1zBD-f)JmUBK%v5ZwJPxtK5Sm47CZj zn|6M;%sOp!I4)k%kR@d@7~e2L)2TzqNQt`276_1rfA2Sn8A1Z}ZexIL$P_=DU4E_e<*4>vI@s(JG`nKKFN61RiX%uvE<0ZT?XJiY| z0b}u`&FvpotcAWe(2&WYt!A5NWyIHC^Q5+;O^%0KkssAkm74M!i8yx36v^z#?6;(5 zBq?+|fYJs-=rfGk6~DyPcElmeRVf}#I1L=&G--Y28Pr4}eYKBkLDfDfvi9#Q;WvrV zpQ+QEa9oT$x{l%+12CD{yeZW;Sv&1~uRw}Wb#qm$KIFvgs6EUgUav`fh=vKWuE+%(`XlrVVPS6}Uhd68F~wHg2N zVP|Nb-`)on!d+RfC9j_`e7Tj^$16vu7@N?x_Pt7cpCWbhq^ri&Ym-;6dgBiS*I5pu z$u~!aREs%bTcL^77|U6J#qLHQqna1Fm%I5K-_fg%i}&vMj^2b7f(&fN>pgDjL4He8 zP}+`HGNZ}uP6ZO1cJ*Mk4anwESTS0-Q6i8nZz2;uHXke>_E`a4oo*Z4_-G49C{O*| z3y4g82PD(%n6bOJt=DiCjNNTFXfR;6qj!tsJI{ie9XBIPqeD?52!sHbC0C6c}`O}bo{ywf`cpRn zLcs!Wgi()MB+}qeEp#7z54N8fo93^p-ptLhP;;y;n1ui zp>N5vNQ&2vKH7TG>%uT|SV(m`f*PQ*_Jwm`c&|JdD^b5vGwM5FYQ9j1Ym{waSz(8? zsE?_g|EH^>e{itZ$426_Be_==5^ZlpH4DZxOb93F!^L4!exn|>x=><<=kFuhES~O2 z*@PKupp33PR(mflske=o&x)+FZ)dX&@k45A27cz7$P6MhnX{{GzRE9`&Q^m!Sgy^( zc-z{8CvAcNzs*P$-xjEoe)lRjKY_1Y$u>5pCwQF>oQ z*N&uc&AWv1!97kOmN*%8h626idGh3bh|DK&DCG7bu*pPT*ky;vJw<>IT8@Iv)h_!j zLCC4UAKW7zhPWt@Hc{pE?Wmw)1O0ou&j)5YC15jN`=w9H(!fz+r;~RMLaI_blY$3+ z>}`a@AV=E2t3g^$e24El&p#~)b~%6G-!`|o^bnBb7pv^x^AnH%51aFBN>s@C1V`AX z$*_EMXy4=kNQ?03$7w}G-{UbjjZz_5Om=Z7^M|-NCUJodTRfi-jMh(BE&qBtW0k!{ z^LKwvo;YD>ZOsQ7JEigCUpxM{|NqHN^DGOb#~a^3P^JII`_CQ&#Hu^EdD{F4=*6=N zdMAI6-hXl=fPDM$9*-kzSkP5R)3RV$BMg4_X+tXcfsypH4n?#>3C5WidlL4>D z5*4%ChIX$jqO20lc83l@AejkZe;Hk`=C9DjM-oE19g&F$Naj`bfYC(T5UvE~9VMxk z>K8>NlKUO`t-pLt+*AP?X+7|_x4n5E-wsCr{;Znu^2Q#6&=`o5FTR78RITnU6w0twQf-BDPGO>mQ zly-h5z8fy6JyJxa{79ntBo{YNj>_o#;08meW&L3q^~=xPikin={OX9fa<91rXQ#-e zlW@jab?7yTvJTB=EA4m#UtMM~)2al618$DmZSigiR}|VJchhk3qm@Sb)4oX;2fT9| zkG)wVS7h1PH1U=a56^OW#SO7^WR`5_9t*$(G`O|@dQ*0>;Kmo)W`KlHS%6x*U@^(k2>uwtOOTzi=Wb@UN|M?3s2F#+SJLPn zQ|$FH8+H7vh8TC3(x6FftS`omWFM3^{_vf&q<=rk%;Idwj=uB-W@MDN^iRJDJU{j% znT+v~vGWw-A%*&zoi9`uMH->qj})Ws3>#>^&3Zn96GV%}eUJ%!eE|&og5+q8c{>vs z3~FCXOBg)`aI*Wj`X7N<{fv4CA~J{&zK8w<=>MNKW}4fyB%hk*wbT`_GTF({XymIS zofVRkXF)8Ri)G)?j%r7~P&r5Hg3XinWtxt|CqqDDa=ES5 z4<>9%`G@$xDP~>hdKNu?Z&fhSSj2_o#?q2JM!U~)8cE~r*k76UGfRvotZlwl*W>oU za_$q^9IaW_yCNgRUG?kTjgRP2r0)>)(o*PJTtL&3*aI+09(M(hUQKhGaUeDuPprt zvRN9&N)NHjOc_DjHn%mgB*a)%d^)?>WzNKOQfn_wI=_dF$S96fW8^>e`dH9&Dmbpd z^7S+fs|4|C40L2dh!sz#a&>$>{)@cnd(ebeVg6ky>eZ{j`b7|d#FSFs)CWr6=Q*9* zZ}=r3bUIVJKcD|c1~>`ibIH&us)AUc^v}(gnCy_ti&DFXkr7;CNN)e~{vX=KEN~4K zTM(wP!u#WLe+STykMUj{UE17e#yRvBH zbEUNNW!meJ(3CQ*CaQ@LYp6qZOfsk9SCqzB&uEsB1*in7?h&vkZc z?2#PE2Plu~XE7Z$(R$%~za!tfqf{Pau~HS*;`_{cY;#=CHGh8|))ldeav@)eKO`zY z_78=JK3k0tC|X!9fE8VFrU91o+vEVVWw1r?tGF__5em2K7SkmfxLl64{Qt-k($p z?9zKmgb_%7Vy?59N|w%YsnIS4*IFB8MNjw*^hU=2fhf7h<9NR_#(#^gV`94y6H^z# z@#v{`vB;_lEKXf4rVgewSpH1!-HCEJ-F?E^#zpDEa=FjE-F!JUuuIZf7sczl`SfBE zCL;-Cb)|luSLfRK(A_d)%4kAE^N>Z}LePHDjD6FH*KJ$payQf6wxxv*CPZ&y(B$IG zHC^Y35!+99+ibfYw~LrCZ@ONme9X!#&gUJ$&5A8Nm$!I0hD>Kk&;3+~*FjK}iXJ2# z2v3mSiG>xhWT^Fw&$urb!E>&GD}-G;M2nV+?={T5_}QkXl|$?U9G`ir!=y7{jGc6Y zhV0OmvP|zi0~_u+f3gmsgv+E`tQaWaz6~y8!zk4XA*ut+JyspPAwC-&_Cz-B)1p%Uh-aevS zQw(TK&&VN~{^=@>5MCp~ltZ5-4Meiewx(!P7F{ig;s+XHtXg_{k>f0;l~H8#+U~;U zeqlZjlda10ADRv`dOtu*D}_6lbUcPPdt!O@2BcwRsM&xNUoj|h&= zPyorg8kSAE`2-dQUm6D7@sPIjAPn@hC1B%wnHwe zE>}v+UPz7B$Q@59_HgBnYpq`rjt7yhs?3y|O2ej>dMP{arYwE0o%|&xda}x)4f$f_ zDIE9O$XwAzEeLi3le>Qr?>cduuhJ1q5+MfN;DSq3BTmg_WBJ zOx~R!34+sHWw9`wMv!c2c5#~>GM5A(sXKY42BFj3y1fSj)0*{Vid7ck&YVQ7mLC$6 z<1!L!x<0H|c=JkW9GGQNmS!fX-b^VabB{(;)wdAy)@rAzyZR5mis(`Em@1+IJHsCr z3691SB0iFT_$ef;pT%DRmy|38BcN1X9ZwzNh6X@Zi9Xf)S}^E=#|W~$dBKKNao{~& zIZ;euUtek1IXSym>V?_M!Rq@!6dA2pxj<2WQlriAoK7QEE%EkUH5+=qrtIP;1dK9v zha7_MFofMRS+mi6>%_vwtjk#X@f_!lRe*7x{=$2uF=y`TPkL}in~*aT8zv4p%=t*o z39}2;xs3F9|JB-b8Wsl-8M2?D8}iT2D_~ua6|6fVQ>QWjdTQEv*TuD0T;Ja(SsM{( z(lO6d?j4y`V5Q9_CO21d_#0kV|G5$2L)No+KF?-j1F_Qkj{d6Y#{Yb%oo>lF(;!j` z6`EmP{BXhX4AgTd0IBY6SO;z>>7O%~%}~!2_!79$I}>!kn%G&yLR)8rsD31IhukN4 zGa+=bmJ|i?3C?oW-Q6X-bw5@d=XZux z`plr<>vQdbN<|>pSBy9c;MVGJ$X*;%^*ur5$H9 zD3^Oz^)&Lc%^|-MP*v_5LybIEp!S=5X z&SyH?Y|BCLqlGi^;~7zj00aFf$8Zn1yR+oJSh1_(>$BKl`8*cFE6IJoJL&nACGI&J zcW{NUw%fxswx~O*5J>URzwoD{fA|x}UtR0Jn>GP56 zJ&;o$o_|Z+^dUQNr)>nVe);MkpMpfQN#s8xtMIEYF2w0^&R{d_c`H5S3XX$(+u{f! zyBVW!P@lL~L{aq`7!tE!=<`OYQGbEAWmTWdOsZd`|KU!BTOT$K-~1}YSS-8p5*ld8 z>qnmD+=u;@DCurEj@?l5!28J9+zEy<`xdujCi?j4aOMad*}Xq?h?ZmxB8J~!6Xx*T zz{0BD&I@=}i7{_{-+hHFp13ESjK?|~@_%ZG#hlwO9&>8*>B`l+Re@!OZaS|cJgR*_ zTFLa|pvu(#mfAdU35Vk2@qP)LKwhylS3RqHfp|T)WBpUu+Vi;mAxcHj5fbW3WG>O0 z1yC2+q%r}TEEu@k`#;et4vU$77lrD%qs24)*cI9+eotP4WBLb-<#p&|yZ+CfOmXs7 zy*pk*Wzo&z@tcABWtZ(I`)pwoXLZA$oE4WVXo7jGj5GJISeVe|pF&g&I4+DnhE54m z7iNBzxSu~7A2jZHnb%zURnLU?OSZq1#;ea*r%2uw>QJ!7zdz|FkWQY}J}rE;Y-&~Q zPEWAw;I=jZM8YA)V}3~@9IA!ogeuyMM#+}FxQF3+qA=>@#MRN}ZXFT<&@imI^pd@O zg6;Fvr8UIclVFGw1t(WofXp2HSq5_H>t9>}3jBWS*LeH6-xD4Pu53W@?m0o1y@BZb z-?%uFj8317ceHH2ZeodO=awoiaO{X0gjIu8mLRzu)bEf}yw(Kna*5|tT9?!-!-*Ql zBtf7eu98Hd8?fE~To%&g0LS@AHv=Umf>w{2f9M!7&|ZaQ_C zzfgxZEl6vfp)y#m=q7P>ybv?0W<8(*=VTIM-JZoYenPv+rinnS0~x(z8;Lr?RlxnsK>c}e58MAaZRoAdFQ>5 z3#O#NjU>}csb)!DhTx`#bw#hD?g80FHY&b%q|ae6B!D~q)OX!ZF}&5;qiEgEw&Kx% zh}2)y`fKgmn!1aNuRE0vC{%>57zn;^7?S`fW)nRh9OkCmsG6SKS?3jZmS%e;VW2NF%o#}AD+7>A1 zEx$nQds&t0SQHdUbqOW;%sGpYBH z-OPU)uy3w!tmusZa5G9Dts*+^@^)#O=tc4|jSVGBDRI8$GWuHMIBFlIi=E;#tM4*Z ze`DZs(Nk>RTGCLDT`%WW#)o9isK|zmYMdhgTjQ+?#Rc3LhwMR-NtJ?!-9ATz@>;hXDwZXPGl-0zQ8Q77)&SFF4^Q}^(VrKgO@vvcu+ z#hOmKS@GJO`x3O-0+(=SH71T_8|vBPBP>v7#9gy(;KmB1f?@+vQ;N(=EfutMtOZ7C~c*yrJi zOn6Wb9hixvHG< zvQSkZP>>5trliB4cc~PrVd_-=S}zUDUyB-)dJO$qy|g)YoW_ClQS`m6A)M~IoXq69 zq$;LGwq?ku_$`2ISzE+QSK;J z#?s6P5ra5g*qT~gg3PzxchhZ*`!`zAnA@-2@G*T%8B z=gJVIMBMJjnAvm={UEqV+Fa9h7MimPTQ(Coz*-h3BL-sa#{+)?WvLinHJ7>5J~;~H zy&~(8BL$_UrHXaulbqTincNpPyk2;Z2jz_LfZ2cI(duLrV96>=M}agt15l>bvUec( zM~T2wniKJ6KmHT``u}zpuWd$P={MAp z&;-6vIno6n3;&Cko($Xe@}?7#{|yj}28r3sT|e!*VaH<>W-%$Ie$sx2O5m+PC`uccHdz%v8)JxOWo71iAp2B$@Z&h9=VYvi>T)>Vv#wFeOEzI^zJqLNM2Z4S+G_I;33<_$YN$MxR<0sLw|dyREw$*XNVVz? z{#u()dSB72BY|BBo#m5L9+zI5UivLr>@{~f8ZMNr?@A>x-Td0*&HyG!2*$;^KAvqC zh7!W9B%wJ)*|V7%x-hn$)wk0vP_KL>a2*-iQammM1uYu z@6S9Rshzt(hZ}rP_ONd2bm#t~DVsAXcqcH$6nH-o`Yo>*2c@T?FBp@^__!j#6kdPz zsGDX%Qya>ZQUN}hl^OtX&BgCOL{vTI&6NU{j4b{TKjOwCya2|)kr6I-!v?QQsq0=b z0x}$3PIZ(w8y|lZQN-db8}&_oNmVrq3UbMwjKD}%^Hs;NU-4s_|1PSw{F;^~Zll!% zo5MTDpKS0I0MJ;)3?@mmYl%(N#gCfSx=uhjTzy7fPxvS0wKEhkA&%5(j@?Rd{}4y71;pllYUN1SKkjxO14|qL{pVSgBH$QpgX-ESvG0)Vy)b<%Tge zX@s;$eIvu(9S!f&o1hsk9#3g)QYt5T;1B;wH`oi}@un3$^Nn|6HnB}u zP1drXQTitvcKBoTf9?3V-KSqps=LBtbW1*4&M_zPSLe}(`>Gm&`cPe6ZF+F;Up1Pq zqUGE!??1DF{l8z`_RjPLv3;+!3CL8Wp{b7E!$9eC1Jz9-!!fuhLl zH1jk6Fdn;=aaY_#r5woqVySp&p0@zqU2AMsRpT))*LDxtuh7Q#(oCoj_)KDSvk0t> ztM5)ZF9J>dcD3cd)fQ#_34Rl{L4ta&mpBYTno#g{t`@O{3K^S7)dHVPU(5urHpjO4 zAyn(QVzHf$+j$l4d#wmsc}8VI@I1FJy@qRZj$U*Elcbxe%Gu3sx`x^uh8;U@?9%dEuV`a}Q1NCDow>L*wgEGoy(Dd*3=)sc~F-tYXmhl>pdZfykz>JbCNf z{%WnpTOz_ay4<{ysXw$Sj%q$Xnj4;i(x~`&wgxy}47gclfR^eqM0W-)m)bS@*a>e1 z!XcokEk*CMKcR$d`+nxZDD&Kljh^8LXi%#=q~q@fR;~c;Pc~}ySG7I%m;ixyDtrB~ z7=M|vTFGlXKXU>Pwx}^C-_ep6UoP_}2!^uKw$iyjT%Z?qtu4w$$n_?{p33a^nXoq} z@}_NcS1%o<&-Tk*H7f}`N$?C_Vxb|m~QCu#ff+XA=X{ja5^|0{0%uT**&zd`{I z&%L2Pf7^xl*x5TqM~C!>f~A~q-@Y9>jq142B2+2URI-J!UGUOo$zGHHqLpr^IPa}u3Ei?-><6D6Qe(jSv9^S>8S~!oSB_e3Dxg7OgIe2O*#Ldi1CA;12L4Gk?}AeK)80i} zZe!ek=n(W7RUzBN)|O)DXN?oEz7BM?aB!p!||cS7!rL zONAund$Uh|tC*NKRV7tg7idZ8p{(5xTK)D5$DF#SY)B_Yf2j46Vp>krWhw3=8=t{C z{a;p?S26V&7?-9egt4C`8>e8`2?2ZM056B_oY_M=s$vy^ND2fwMzMJD&TbJd!>e>f zS)fnml1uc?AY{nj4!@Yfn}0wwIA*%G2~V@XXvg!;{a-lt*7H9I z@U?eLL9ncV*5+EY073VOLgziGwHSh%6* zL;O3+Uwo&ER$}a4ia&Fbd%XJEUvrDJ_b<>67eI+B$bJ3**Z#-u$|+O*3-3VrQF65C zjGZw5XtCyPe8UNF`DDInl$f&_;uet8$fMFibjRI>=~67jt{g;Jh01Mw+(}w|fX0QG z1RhDHCt*%3!D*Q1n;0IIHuBlt*^kZ~-kCq8jv2T@ZSWGOGDO9CYIAlnorBepZema@ zhgtnB0VJNVoqzVw!u>hYm>Yf?Go0eK^Z2U_A1;^|b}KtiQ_c)joF>_q5f6uA8M_{( zG9?v+p5v=_2+(_T(HlHIX^ouiAgzwYfY!D&9;M>A=p?PKwXSAZQdA)sn0@f{N2BG9 zrTNAheGW_$GP&txOpfv_bE)~4aPv-o9kBFsm0MtH=IZ1P`O0VYe!Dj5yfo%fu()8B zdFhOJFgW+|gVU(zhHfT64=R(0?GSehPe`nF3bA9>)#5onD&T#revCr}IDDY&Fncr) z_d|RU)nEt`2TpwHfs|d@U!;ZVk>oQ~<}tkMRe9PVww|FkcgX=%!!C=|$Y)*cXfQ3R ztS%}xc8Mg@Rm>)a_xJi~IDk{=10-)c{J^=_94?S_v1}ZE+@%*7VCGK<9QU8En4U2# z3o5@yJjo|PNS~?CTYXASVbv682`Q$e#icGej#8 zI2{TbHhAJga_euHGCz%s>L!UjwZ*6og?xZpgV7XL+9}vt88xS!2!$F`o1>R!bGqGG z)fO7#XwEjtzh4G$AW`4X-GIcV26=y#;rFAz#kY9BBZvQeobm+6jgYoaBHT@JgX8rZ zfe81r#)0139Ncy`IX$+NdcP*x!=^W}_`VtET)C`FKI6fi?|b%)V!yE-h}IT& z2A}$3@Z%#*LACyq+`aF-H{Rysf)3ucl9eHkzH6Y~!VwRVd1BupBxBW~ttu+wX3pCz zdQ544TszT{`TN6|ov4q(>k8h|yh7|@u>BLUyouTQ#Br2fqcJ28xzBX?$zr!T zSt0g@19S%e^7W0ChjgPn%1rwp&#Un_iTml=WcP(_a01A?%6p?Vl$iTmz@7!VxlA5c zksQ4s0@hq$q657wE+Or>e4(w;fb>mUsx9HQirEq12=4`Bmxz%@TyLkazmxT7lehMFdG~RVB#21U9(xi>8w$d5=5K4 zu!~Rmtqh&-=#oL`o7?U1B4n+OI;ydl{wbGvZ9>;E!LupH1+KDm*dY^o<{3Y`U+ZWE z>bMeD+@C7Xo`&R_S0?9G3pJ~kMRRnBhK6gp<_iGff8p=7b-elJfn~E*?!UKh^S^hv z7MFU7s_8G>_aX+=q!|gBBRp#tA%%gZAjgKVMEX2nB`LKZrq_P5fGWLLCE3$edaqBL zE9fT$&ZS)QSzDAexdOb+Zz0$3uu=DE|Bksar+kHftsPEK#&Gmm1Vn@cXAAie`|U(7 zo26x;e^--Wf)0b4o7di-)Bh2?Pox)rx(+4wy_dmUzlg8MNd9_}h%5V>NSkvwMvI@) znwXA_G{otrgNB%$|3nK14vjf{{<-_b*QA88?c>DDGj^-)xB(RxxwOMcbQNLp_Sszi zkmhjIhbFxP-cj;HtfKVnAT3?&x%A^PFxQ}p%j4nSYz6x@F^t!hu?=TE0do0H42Ur( z5W=bSm$jQ-G?^Co1}=CTl*#e@8eVBPcRL1@Lr~QRSG&{9i>?TA1axP8>_WkqoFS-} z91w|!7gt2e*<#Pb_zwU9)J)%{r2g7fA>$yg>gyYAUHV^1mhyYwK`Ofc6DSixbY+1r z)tx}o|E;q+F7AI|_dG0q12Zg|_raSLyn7?_!-w?^amP!bs!mR^y;tniDI>9-{0M!a zzFvAZ8s zi7XX81D3hX*e*~$e%8qZ?gJu_ZMiL-fD}pFlo{J~y}}dOa^KmifsP-K0G3B;TuSiW zUh{HKF==>dGrYCjQDM|(&|}!rNT>58-}eW~K;-h~l|1O@d@$YH@|ANC6wcq|<^E$R zdHKed4I2sNEUK1RCOFl^cFbj2= zEXkDJA&T3-6F?kI8MLrfs3#m4lSzk^c{K;7vH&Pui>OZdRqj~UUx)?m) zWM8Sf7wY7Zxzy{{{-y{2q2j#m^UJoOb~p3YD6YRNX@=GIHejwr=W}ZJOm6&4naq^{ z&+l$(Q%sbLX!k#}26n+S26GT3-tqT^8tZ7#QY zi8fxhesi&Tx|EFX&~4g#(iBDef-oVal)VzVDHx?6&vXw(lWZa~F)F3D ze#=4cW!8-Ea*|`^ui(VQ3vPQ<-9A8n-j6BSY+_jjGf z{iA)V&VDpnal_1|bQ(Wil6SS=Epc)ZPupi>5$QS6tUr2LUxbZ-c|?iy4ep%Gw`-TG zU790SXFO@W<+{}#1ymp)1!PS?AVCr~v6TW6B!R>vhN#FAq6CBxAcV|K zsM?vfr*%#{bLO1#{GB0i!i6 zS@6t!)%;&6&VWGmUu>Ou+t4Nui&Skq-ipRz(9@;~OUNpZo8q`?30NC%c1=yqcrE!_ zz^Pq9enhWVg)ENb^1|&PrhrpRt5E%|560LBAe9TQ3xhsGM3R(kaJBORC#@z`PjA*% zEzbROJ`M>OXq5@T|4sV(`alN!W^f)QKOM@GM+CpfHc9JumZk!-J5uay!a#MKCO@&d zds+90HP4eFx1*Kj2@K$5<(p8q5S@d+!5jEOrRcwNxS6}A2Pn-SleasOpCOFYr8yM0eMaiRe6%Rk6{ffmZiW_kn4TI*tGLkoHajMDRa!& z>Nw4`>ARhz^#3X4cDkMzurF|IOf3D)tj z16XcdY->}2aT+9DFnq;;c0JPwSC9~d^qEqD2?Hnbc%TC=av9nHb(Y;D4c^sK8cP*|Lbv_cvynO!C3(>sxY`7ZK72t6>{t% zbC%XWixieMtB<>nGgi;hh7?FHZ1#=|Fi$wk?ni>zJj zZ3`mryEF{0BC9FFN|s+4%~})jx+U?`Or0rX(Fc2bTk4uo&OK{hRSgp5=`wk1AC&?b z+C!iWQ!MQ`|(OA9;(>4a^`S{MQ)}BKCIV@a5 z_4Z3OjmX?*%gLp(cCc1V%AD<{t zOtc^00|p1f5<7f*t8tZsP{k0lSDx09X(m?QEyb0stoCk~>^|(AGak{6Ql!|h?Y`|T zL@AU)+dd-k)#G|tXGJT8lc5T3PDqhxSUjl|wl}21m&TfwH}3n?u5du*<29-7SIMjW zpacxJYY?V*oO`Sz_uEp%w6U5QTW-yX@Xv=J4I!lcoH0ZjFbROrccioMA!X2!wDufU zL!bfSJX<#K<&|v;hvCk7QQ%ujEu8gkq@Hl?owaG^ce1uSp2UG6%g|A0Hw#=u*8}g- zN4}rs_V4r^eH3#Z=03}_;W8s{@cT1WLoebp6-+w0tj~aYbepD6D6bGH2z@*-@ts>W zm{;wQ*)+fET_*gB9By_6{ABU*uBr0yKrICDc8|uCA3e)n&?qHyO_>31osU;chh`0O z!<}L+DG>FykkEqjXB1`aIqdaLl+~I#l5nA?S9aCOwsN=b3~nSEmm4w{w)qyoWKIn{{H=H9OjRNTD>>(mCxq4?ogvFlBY? z5cr=kmU&az1zxybc~;@M>?2J~BQp2--7Pt6W0!o$D7iRieaNO@Zf$!_vF=EXbsH{m zW8q(MW{icl5S^uu`*VUYdGYE9M+8*ed`$L;xv_KIVx`e?mI@~$X1m{W;BL0(EC7!1OO=Y~E?`sFVb8Zs%yV%&9`=@GWcQ2)d8;^Fxh-X}j!WGXY$zI;p0rg-pgR*b~1!?gu^YPVh*` zDPdXa-JC1e31f2)OsDZF2&m$#XLDz(^!40aj6x(G$ky^UdN^CLRpNi>OBYf-eLg(! zbpIao@wJK<*B2$KeSRQzZ*M;x8Jkg?NeV~!rQ@j8X$=fW#ZDQK;q{3Ra*P-bwur)BP50~~)w^Vj}&ll!h$u=)U z8}~}Klol{g!f{A*eq!2e##n(5r@l8at({7uyxNgQnZ&^F7N#sMA0Ss54-Or{U)t&P)epNXz$9!HXOo)B= zDl8p$0W9ji#fzDOz5dqG*xZE;fSj|T4HmYz?Jz70BU$#bIdqBGRf;fMR-hQB8jejc zUh8e^TkK~R-#TZV41n7CI-_K|sqK55qGFx1Pp8uHR(>AEKD)u~_e@Ea;+MT>NZ zG3+LqPebzL9x#E+H96 zq&bq1&NYGa@oDdv-v+?^eyuGJtn7cz{N53{H$m>LGHGo+*zEag9DFRf<;;7suCH4OQvXT62jEn1`fV@Pb$}NDHF@?c#RT(7 z_1|RPL{IyR|2=E4eSTM_zbrT_o{ diff --git a/docs/docs/assets/images/concepts/ui_preview_details_link.png b/docs/docs/assets/images/concepts/ui_preview_details_link.png new file mode 100644 index 0000000000000000000000000000000000000000..8b375591c2951b13c136afc17732fec8f5342638 GIT binary patch literal 76761 zcmcG$cUV(j^Dl~mfPx^R^dcfCA|0iJN|z=eARVOl5_(A#R4f$fEr3Xq8l?9~mm2Av z&?CJhloa4@{Fc}E{O)<~Ie*-Fo|WvDwb!0CGi&BEv-AF`rt;-WOqYm=h%T$DDCiIo zktq`qos%FZ1&*u_-$@3(&Vh849}|`Iv#bI;BzBK99uX0Ji=rS{UI6wlx~mw1h={0K z&)T_8x3AVjM5j5b3Xh)onQhGYzKk1bJl#F?&vmv;G)c3QZbAs%^ReUW*ZLms%dA!O&K5rAaP2g)Y zW2$=r4gWs1HTy*1{8x}gh^PN$?@DLG`jD$*58pdk^h{nC9UjS@@(3{aZx$Vt$goA$ zJ^SfE$tPtrUIxAnUJSq`1}d~z-kcXa?vWvM>^mF6KP0g70euFny8IW%6%I;e=p!Y` zsKSMwBg?!OC4HQY74_cdXsOcd)@WIQC?fj!+7>V3;;!lHy_opsa((JSNh^-dDhAZX zbL;xQj|OZ+%Qzpl4h%PBcD#HwxoJF61!fFx<$H$VX{k;at@3e9owCQsSNJIoSGPI1 zxU?SfUAJkE3o{Q8U?E^VJq)vK2pue`E|+d{YEtN-o`0MQUjG5SI;7+6+uoq; zf5iN+@4)XRVOd?;X`3!C&Vle0h2ucX_99J$!n;mdQPJwBLu<788(OE$p?CN{EI6OH zqm8?!$SCSe9!z>Ui^J94-j#zbiZ(*&7qXL6`;={J7M9ys%!fLYnLnuBajbP<>1+R? zexru?fQp0aH78(tj3#EM-e2tLf^}8aoC(aCOQ1_Kk*G+0c+DR5|>{ zGohE02_#ZJ6$|);!G$}P@b`!Md_58g|KSX<^`m5R-(58Sixv&X;&@$SI-hr6ML_#A zO18&}isp~gIYwtY@Tp9O@cSV=Odr_U+6pcwcr&lrySZ^LJ+iUkA_nebX3}5vmesk~ z<PPsTCnjHlWYdKxnS_&`I!Ig({;;ZR^xC^1kM|Gm0CL~q8kR*g z>dRpD?zK#j+qY3vTDnR*YiIEp(jG_(y(dH$K zD!Z0}^B+EZiHkR|Y`CJaf4`!-YR;cST0kMti2~SV5Ku5g-u=?9h)q3wQc1zKQeyou zy8M^Muvy`p)xpkrN3;~%RsCJ{lS=WWjQV`1LGRBQ0c@KY7M|A;(p9g!^Tpf&gY3RF zPVkv9UPC6e7m;oCnqIqe05)XjR^f}fCoT$E`v{n&?FE);zn-Ze+)DM=;wY3DyYK^- z!`iuAJ`?vLx~717S=ChGKr>=H$bo79$wob4K5A+&^~_dSQ%^bpQb31d;mWaz(|Z=J z(q`{CuBqGVbM-xg&2_!FxP*CV`vmdV*REJ={zeXRo{(i>?lHt7e?;VZqbFN=Pg3ty zwyDjRqU0k7TF zinIj!Ol9}!?1I<$%#0_Y@QXyu)g9vNx*vynDzr#@I*Pv$N*v^lyzdW{1co|{HTGAm zo1x5`PBp>wL?^hG2f1c=qy91xJG1haA~3`6<{8KoWSa&uFjWKw=CZ@CqmB3Ky;lVg zE-T@MC(VoojcpypE`;UUJ}7uZ?W_?FUR7deq>g&ZQ^k+Fu~6{x$JJ$dgQg#+(xu#a z$Oxo=8nvlVb!(ZsYA1XWi5%=EgZZUXgKt(!caq8NvWU1E{s?KWT%C%NtLK2|0tTG8 zCC@G>`m_TIT|Lla-JBRpci0&|eYK@RR{Tp=&n4PW;>{ z_V{4H4HBq$g;Je$pe+V<@NE1>pw{)EF8Ml&z{9LiYi7f&c#aU308u2yv`4cM3LzMavkdR(r5AeRi% zD(N=j01QYOgn<}Nm?e38nSbH9Z!>5sRqYT*uA}?wn2xq6(5@JvXfFLz?x5POm!Qjv z0=x26US^e>KJCFfC4td_*g{{^S7FX>t2+ci((w89Q^USAYPWs|Tnn|n$0i*1!=GIM z`)nZv#)l$R6sAaRY}@(jq3g-UmW$SV&n9o9WbY=UexYEcLx>9=tl$+9KqX!@pRAn{vI0Sd|mFe{~{3q zmB#A_QFE%(ICETtHp8iRcQV*f>3FtoxAUJfzrA-0LXkNm&02Rm*gj z-YYpc%sv`#f3L(@QDNMDmu!XI6Ydav>Y_heIV=6iZafUGHuY&va+u#Qi7X?4D>&E_X6b%>GBB8!kjQ4!&kHMW z^p--W8>(~uta)&l;&Ys|Emyn^@B0w%A`#_e)OViE-<@sU>dI7EL+kw?a9KC!^`47X z=);&(mM5|q{u$K($BWtQx6}?(%A{xR zJ2@~X9Q&;xQ7uTZEXRz#I`Bkr2x@eyy%rHYd4U=|r^XkaA_^Tn+x)oxp2n)@!^UR4 ztj`TN;t8QO?Axvz_0EeOi}Hp2F@GzY5bf9}&+B4AJgXSHM^1Zzx3JKB!|$BbO$t5p z?G48k26Cx;{cgsd@Ine1cmRL;IF>y@YN*Per;rIJG0F|TT1FLR8&`> z+!1RTTZcyLcfM>-BcPC5c!S%6ha5R45r&4S@)!jym092(mr)FUhIK&2ad6kvpc>~r zJHw(XXGc*0JfR`1xcTs5E@WnH%&_Mx6lJ-EI4Bx(y0ashisT1OLH)w;;cV8e^ovyH zjQ2l`s@%%c(h^72ELpMlm^UKguZ4*pV$Ss*+wlQX-Kx1 z;r`gXlO=$eU(rhN?0eJR>o1|?WW0kn2<-JB9GSwaWJabJj(QqyR51P&Xv4B^V8p7; z=HJt&*5JSO=5c0VTkT8m_Ht*9u4$(GKr&<0r?VvoSWW|wP?x}knaa(Ey6g)tRjt&L zJiRgq{DJCdsto0f%d%|J9_l>Qr$HrZLA1cy81kw(qG za_uzroo5oss=%8-WXu#5HQ8xsB*a<7{I3?fxDc?r@PYB+HdWn7t?K)t4|Xfvf)ghv zC0*g0cow06XZ=+&-|Unl>*nZbt-e=NA$leoRejv~QC2$X^exqM{-jpwSF+jO;S97@ zX}$B2iB5E-bx51!GO(_48Q3frv$dATZlk(9?1j&XMLXG+Sj~dmed-#a`{+HCqDf~% zvJ*qBp5!O4DBF0Y%PnCWizbj&>owGJf>yC<>07WN7kOUf^UelBOzJx7TY&mcu%ahP z|5~1%Fif`4dNU{fUdmXb*4(Cngv}F!U89*e=z436vQ%7;i%}VQKNSv&Zw3ubpBHmw?44{k!#`<8}UdSAd+@j@~IyWu|#m>5G=W)bfvukqqIV%bj)0yR9+NAo!vvJmASjzevQAT z5)v-qc9%0HVdptLnj8i$PUo4B8+zViWg28&0<1>p9|5dslTlnz`%C*KfRB93K+ooN zJy`O+W$4H8nw+$C__sslPb>8}!U9I6vbd5}S$>OlhJj~{nXq><>Gg9TUd@^?bWrGa zIji6%d6mJl&gT`*hstZ-41Ki**JL}CbM*$`!YtE*ZzGJY8mcOi{b3J?-k!u;g3&Y6 zm!2J-qF!U}$kklvp_L?aygudgW za^}#1obLn52g?F*Ihj0x?`hR(ae%|?Ab-y9WSNgi=I+g#WZBHJ!F-9q8!t`{mWBui z)Q3b*4Upf*n)XfC*4D7AQSi>B8FHnGSO5o^dn5f~Q^;q-{`OkCz01V84hpb#m!?cC z$K8&sN*gkoAtkFts)cV1^Pdu@4qs|3!Z*rNu{MMbw&r(Uenx68GI57J6$WWRuC9y^ zyOV=_xGTO&`d{MwkwO0r+LdVgM*Uc8Wut3ZR1fxr?yG6(yZzFw+d7l1k0t-jX9KnRXCr13+E5RO*WV} z4IN7v7>tp`>m{!X9ZWX}SK)Qf4xQsm<>c$4lsczPGzJmhe;bg`?)vgj49H zkO5`G$Ft~f^!ZF8DSP`)p6BByM@9s(Z6S|bPl7i#@GBb_@BD>q9!`#JhWZzFom;b3 zWgqt-bY3sohKo>r{P9Tk2R%JD2)N%rTr%jE z=onY)0Mi=t=c1dS2sGYTFvw_hH_Cditw|JS96ybGl5o$-dfWjOi>+K#>95&&-aS|y z82SyGiu?Y(H+fp`#w}Km*%qQgsG0h>#ilZr{ZmrPF^Ct1olYAAok2&D0rC$o)t<9) zt zO^yVnJQJwG=l7R|_-h>00{r*3n}2o1QMgX_Vl$9&<mKv2?~iKFzfb^ zrYFHU^AP@GCDaLw&3kQx61lZQTv-)nY%%K2i(lWZ-IJE1Z9ny1n=G%o3=# z_o1LxrjwmKrlz1N(*9b@`*OHo+x{MbQ$J#q3H)wtk@Zm3MyH(EOJj@=1rSH4LAmNr zH~jaZ#}n6~$H~it`RL-H)i5XQj$Hz}71@+go?&7d7Q_RCr`0Na+&*Xy0|1U6GoCk)7mAd`a8ILSN|*ln3vTw*CR}&i3hgxXew3{_O~ZBAh9}bJvR!e^rvQ`ne+8U95j)Q@KveF7*peSEy&ll_kApnxg0F8c@eDRy%*mV zt?@`DMJA*sw4ZJ9#EQ{0of#9wFyw8de{3Smu(^7tJvjfgOP%psq@p1w%-r~VR{htH z(~H}wGGEbFzS}|*HZyfv`Oy<^ybsFr4IIsSp=4Xuqr|?#>#u4>H5;I-6R&K2^`6

XzB{b02n~%eo~+#w`MBp>Jti%Fn-<3!_)P4{8XZGg;w7gh^!hVMBfE8DgzT+%vY+ zpDJ;@QhCoj)}QkG&JSqhD}nFqCp8gngnR4Lu_gEpCc4Hn=37>j)N*>Qd-sc_YWH|* z8&4ioN2cKBWHB&G5$C6I?c28JS7;;o2?IYkjzhJRJHF?-2t9DU%qI8pQCC&P5{GW5 z>YMCatq7K`k8lsQPJd-ILIw$-EZxat_vU(?%$DtZ4T#-G+U2o?5vkLsrwiAcK>-WV zZ?@g+==k%sGRE4zO>hF)fNf0kYT#~*T=nnJe8&7<&$?p3@SP-#{a~5|?#Jh)jde8& zIT+vrP?2Ob9o*$_nlrJL+ow!@;5MHphjSHtXiYu7=`Ol|lkHO29Ur0aZQA!ryN_w! zQf(n#3&mr2CmtEA$-IBf6`rh>x%c6|Tr%$<7rouV$tSNhm6U{rD(ZA!jfei7+VPD)lW1?tJ3iYl zxL>sG)wXj&Xqw3AlqHF0?ZK`Jm*vOQG&Vn3k#oNd8ja|Onu85z2T-?rR!7m@#J)aK zw`7vSB?Jr;z}jUSUVHLt6E>a#GZWOu4P&3EU|fwWzXeos(PaAsQ+b~%vFJyoFUfWZ zq0`N%=148Vgpi}O785Gp8F9&@IjqjmwPG$+^sR{IyS*hh92#gMUN1W#Gh^2<_jlS0 zyZ!bcq*q1CfX%2befOUJW*srVG%H7_j%qD0nu2ttl@FWUuxQD#{#d%lLm(%#^E?VxNin?T`Z1sgzaq1aiwr<@HtLg>Q zo1f0TA>P%@p&m&?hoqKBgcQn2-bAG|?jVYTes%jxpKNqMn`G`=TexqfR@;Q_0AVv( z0-tg9Zg4f9G})E5qk4$`HF>z%n@XaEbPQ5GcqH6~CUm)iPzW2FW%hTHK;PuHxSd7#g@q!pZILlc73|9t5jjIW}qtJJ?uj_cTm{N zlaZ=l{$VY5_{aCV1$Qlj6SZbNl`?{DJV^`$s4oMqT3k0*Lsdb-n~!Tr(}u_6GuWoC zSo4As!`&r0eCNF*Xb{@;N@wV;C%Z8J^bE~k^TF84pj0iDFApf zzC&4>Amt3w+;o%vpRZ;ZFPj{7ycXhWaNoYA35^qTEHg$#5oEE|<=LrqzhVb%5?dnJ zk9TgE1Uv=tzpB7N|^HPYJH>2<;= z0|z3jqT+S;3*{nP*3{9G?EHL2wRdG@I^2=W{cRqtJiNT^F94Ut7F~D$)|%KLOjIFb z@ap6A&d5=pDp5vKO09m5Qv4xk`wV3h0RnlO0|L02kTvnBbuF*FXKl1>XLadL!c1AD zKegSa-H1r9aRyJGq4(Z3B~iZlZ+YdjImL$GL24-sLR^eRUgST3DvbW zdeD^{B6d!>PzI*Z5+SuzAf;_?cv$^# zgw^(jP#4w57$=`i6Q2RVugf2-yLNCwG{-hgBf=TFG#?=B|0Z`VJN`jcz(?GAq`QU=Kz=+VIyudfaa!|?TLs7|K& zR`;~G)=6XhnXKELa*8|_u5a7Qb-DPKihTDy2o&0YmV-y5!NZZ;EIT@XWk1cX`ap! z{0b2yb7WHn9VnCHY+21*^3j_>kZyVb4!bE783>hC;fNkMj>fG z)TlGM29y)>qIQQrrk-Q?DUfn9`@AOmHYC^!Tmmq!aU!?RxCWbw%&9Dn$T-=lr(}N+ zx0+EC*CXpAgg~Ssv`*LIzEU?fabhDSx6I8yeo$i&-c$KP+@Uk%_^zE+;U*34fG2a> zDa&E;$pbgPsL?8h4hpLV!D7H)a(k|YUa7=H-1=p#|M=Eb4!S7aA?NoPDJTbL=hJ6U zY|fXlAIWgxLNC|;J8^e4B?E=;`HRlD?I$&q)$P}!Erj>qnldzs$K>m-iQto~BWWb? zj6Jnt>NagSf7X7nnY`03Xc`nE{Hy$}(9GQdLm+`?)?rJ%)m57^9ni$U;B>1e zVm)iN2$94T1b?7eopL@~u%YHfpw62PMMYJoVCoG;skyT*2*IEc*h* zC0h^LNR#2V(&}Xq!=C$SDw$}iH%CZcWXWA2e3BM?#s;BU>>1_i8J+DaI_z*iX=}pH zToR8FDFN`JLzHbFg zZ#jJszagh^S+0>+N<}zmVcK(ra3YwlDe&n13@tYue@4InV=~eQfSD%Zs2+=K;f+@~ z-*;-=>vG^NnrpNjs#=2PKP?4BX;U!0e*I2*y;LO$mk-E$+SS+8PYI40Lo`kAE+zsQ z&ZI*}ZfErf@lA8a4u!|;rK13`Wx8Wu>{-m?OfZURxuoFTW_-% zXX<4`$*x%rE_;_}iwQJjScZNGy%GDl$Bq3LwvAiNBpR2+2MX_6jNK0jw_ItR!7FU8 zY&MfGa}d{~q1Vn90G(!g5Sj|S7kX-e`Pw?X$>^TY+QtT*E+@m$gAFfg_`agGaaC6Gzvb?h;MiQP`3}&{`me_xBGPD>1 zaQ2se{#72tMO#21^or#3@k!e)_dj>?==VU(_@cx%LHGv@Z!%_wI*>>eqDb}=HJ;8W z>SbTm`Yox5)tDMN+++4gcJ`I6PGc+@^ys0e>$7*KIHR5Bvh^lYc8quAZE!3;bB+T3 ziH8%DC2+9(`eO4j9^!j{w{N{?qGHDL*f&&mQ8^3?gHVH`gM$6T-A;Y4G^GjUymK=( zZw7n;)mi=(W3gvMJ0nw0&$U@e-pieMmTp25jcS%b$>u7$Io^eLrP&CpSNcy0_|?PY zE$qORw^WoR0K78kAMDR8X2P~n|0x+#f{N0z%kB5W_4kHdg%e^mik{OFv)H8%hq)oh zpJd7IzMzFSK%|Hapa#vC*%2mL?8jgV0siT8;w9qn7(}o%xmO;t;Q=d)nFm--_VE45 zy@2{RZYKs$Q*t3T?+oR7!q*6`?A0DEZL;bTb#W8uHEjFog|W46ih`r*+d5oE6jK#^ z{gvj_1>@@CUtXJ^DvxD+A+%5%lm~fVsnTH3ZE-u{Jl1~Hj~h1bg0Yw%W87th`D)~R zWgFfbYPnvR>!u*{Sd5p)HoJ`qACAlkogiRQ^KGij0Id2R0uR0}o+OwXcZxj`2T)2M zFj(tpjxA0xwALe_vsM=ZvhHH|{ z$s6>m9ZCc^OTbS(aw!ix_==}-h1J;OC=nE{nKzwmE+vYsA8t~Qhgfa9{jR?Y&TSa^ zoM_H1T83iRp{I$S-PX;(pWnY6LHHF|?cO^;yO-+GzuSW(q}!!ublS=JUuK76II*U6 zHit-=2hFz=-KkifU1n+duHE@l!JNs5B**9D$B+4UKmM$9VRgB`E%MooroCP9^<%cn zQj_*i;)E^QUf*EwCcz6|Qc_f)V(qF;sb~7e+o*Xw>6p@^B;qI*s(l9f$-e^aEN=_g zEhhLVQSz-&pSo?6X4U$fkoFkfw&~6Tqr{|YeyLqvwW!d&p!5m6ThMFYvrVXrK7#x*zJnA2JL{XI>2#PLebu0k>2a;sCOoC5_e~keA0iMR}prg1OPfy!wZC2&M zD^jTvryYktyF9(uqh34PKke?%WtX0GaRrh3EfQ_p(CIHSyO_528M<-A`C+j6SHB6w z(9x@KK3ZZQK>r-iP`~?^!C~tX%fEEES!hV??(fS2;2+@JnRiW$!FyUk!n8SFhXE^V zClBD*C?No@ctRv#KGSWOVa9ZC)#6&Nx%eH{@bkSjp7uBfYPs5YhYXY6=_T?ZhrDN= z3)wg91otQ3s5km>7@SVUU~q-}Y$-#q zPduH^h~B2){N}GVkh0;X@KBGD9-zq$_Ow*5NvtM4acu%S~sdvlmow8U|@g<+NO9aHBUz_6tE3aPW<;6OcE_PQ6Y0ksQiuy_%UV{zTP-CR*k7N`jB0vCI>)NXxm>=+}=kEy$hkI$x)W4%G!R z@m=W@$w1|RbQFNbOK4Bn!zz7d@6GmtPjdpOKneGSo%eWdeUv_{6~q|T>v}qAT?(V* z47-l5pNh172&ix_!a;jkF-9g+(PmCF^tk+N1N4GAq9bBNEaGcPtmX<-%(M z4{4p-Vb7XRhs~4C2g4(Sv!#s8PA#u*`bEns^pNQc2w;0m_055_>o}0sOGf{=)^@J@ zHppR=rKVoZ#`~}VCuS>TXP66R_+B~#?G#PzUIPlWRH|f5^~a2Q8V{#qk+*K@{A{Ua zI-1l-T}|M0 zR+RG8YNJbI4PSs0^mkZfcJ8nM)vD3Xfx;~N!R#n#i#E+_w8hqd#mQtC*dr)_YH0Q@ zxe`5bBrMpKC6Pse%lmrdhj%~Ht9$_)Slf&$rO6U*wtwXV7_KvlmdUA(8@e7%j6lKI zx;|2aU(&M^9>S=V&S|EYw5vs_FXkxsOMVT}1}<&1+GK!uzxo(t{Ga9AKytQ~W7nfQA)$((2gF;SaGf#sCwEtuWyK{D;A@}s zjf|l1CxFxPY43m5H1{t>F;$K(Ko@5Nx4I00f^xFA#d+x;;NW1~!S7|m)A}rX9-aR4 z$3J8Kd*ruRggO7I-(LFuIT{#X%$KvzvOI^g66oK=a&7Ooxd(a(`oF36UV51q1I#Kw zgRK8IzXJ>uK>wG8Gu3Pmf)?>PKULqLakWv&w3cNt~ zU)E+DtVaC46?+N@s4qVdjUV}6+3>H-{&gFPTfcSczc}?jE=gh(v8^G*&&-?HmT$oR zDLwb;gf|`C)Z^n@oq~&_)g9H;Ksf95wcv|Re4|ENjfb-YZoqI5Im_%nBkZpaRg*Om zgfpW#K{!C9Fm3!mEux%cxDZz3FCGG=K+8QK)XM8Dc*=v~A@_|3SC^-Acs{BMd5?yfCCj+TzTC|>@Xm8;P! zti{eSr}0$;D{#$3a0gJ4Q~0?^OBFoisw)m;_J0#uQQDhp0Qao54C^gLTEi%T>hfhk znBVkf5776P~MwvfY|W& zCM@pf5>^^t3=Arr9JJ`C`#S`JWB-^hKuK)yw^)Kfis5-?j(x^Perq{&X5ex@I9}GO z?4(}6d75c@>>$a;*ySGl-}>y|ygc|4d^M7EPyWZ8k9_%Z7rc6@a+5Q6(Qs3vmGnCC z(`)+-&#(8n(f!SrznIf#&kjf-`Jnq?_D%kyrx)pizP|oq@9t-1p|}rbQmv&P8sLe= z?M0W9dTfP}E}cF7f9Qu2QezryP;^KTz!R)~vtpkbl|bf8a7iIE@si$3S{0ilr+ z(cK>TaAwn%!jGx3Gc27fdfoG_A9R?70?k}->v5K$U!a2D?%B<#eO$|TQzuH6*OV;? zZw;eIZ^${?J5>_}Efu{Yx@R<*l>QMz+^M(MpJMCC9O@Jj8U^-q_Y`>LQYmzTRdV_H z%VOiJtn>Kr6XQVlV7Y*UQs~J)k|Tnu0~@y*eXLBV-)@ouULwj?E*Nurfq9pSEd*r4 zT42H$)`<6B`c>fl=pFgfcuIARx?Y#efa*7+7w8(UlZ5k3tzVUvfD4f;boTq5{VOeTrdj5#rVKo=&eI4e_E(ayv9vLO7 zi+OnK^Mh$!UM!M=y>IN|K=X{tadd(AzgKA z5OB6o2bPAWse1MgIO}`)zv~KAo{#+Ub-pMzbg%Z2;fzJ_Q~hd&mnd_GOc}bk{Imd1 zhq}0}gF1z}wymG9EF&|nY}_^mF1h%!yNN^AFX+k(SC|?}mI^B+>$UmU?}LS>DvZqh zDl=P;#nFOxxo z*NA*7aI4x`09XuK$ev3gLNrvwS5-YToRN`hc>b3G%&yh}7Q6|A0G&ygOaktBo!vH?57-=qzrA=8JD*xfN^YeDhl`I3}XAEDte_qNc_=%cyNBEsChZLFWw-cc1+dX^S*IDR{?O9i&VZiCL z(SdW?GofZ&ikbbs|19QzNpUHnMLWaIr#+}=CZh!7W@=Kk6o{!N}HY^J+OA4 z{06*H_Xousn2Jxf?v%)^jGM8C*O*jGL?fX&i(q9cjmw?)ohRw+0!?l4VhLo+KCyjR z^J~|7xf~fD+fZIh*%dM2YU~0XOT14kSb8@`SEssCM#QsXozvU(Y1uSCsea>F zj2YZnkJe@NczbR3pLP59{i(osL6#ij`I((Z^O!M;#47Z#TJbZtcl2z|$)n#q2BQ_b zV3ZWIj>}zG4L}v&YfSBhj7Fx~7E_)SZ!ou{K*T?+*?rC|nxvod4Ay!F)ZpOd4dQ zs0}1x6Nu8DWo@?o$fN-hR4EPd6N0)`zIMXLvVM;xvdO-Za;kKO_mZTiZ4bD2e+y0) zA5mF%wxB|7ujq*CKV!v3gKXeq%qilejaGL9`Do4w1+ z@Xs|~S3CnSL)m9K|Y6EeIN~Y$QVa*DqoLedzet{XuDsR&`=pk zogw*hFy`rOz+VPdC|loNw$j+2Oe+CUCi%{(o&@wR zZ!T!GB0p%a&PkB_tGLmRl|JL6*pnJo4|c zxbRn~bH;tLTC6}5`FAq8qh{CQ-`&1FM3T*M(wn#O+|KCjx}7$>x;GGI(hI$P+JUkQ z;)jTZQU2)~H%=3QETtu?5=hWPBVuVnrNqW`4xi}I0;fo2*0(|?q zXHN}3P>7SbWgYl3jDL0f;3wBaCtGK=6!f#op|}&sb!^xfwT^6fGn5BTx)>X|S*k9x z&ce+GVz~{)oRh__uKO=Wh=Ho)#{Uc0r&2_A&}8;VIy1-(RWb$E$G4+rK+Q5j zlary#>ASw}o(G_fX0qnM&==w>x>tQ~F5?LfKJ1FoPzLY|=q z+Nt?~0^acfvGfMoMRXvdWm8N%_lRwN7W0jMno_R*F_O54Is1Q;ih$>q1ZpYLkM~2FO^+=RFqi6y>j)VXw4rg6 zRf2PMu!l=J4(V|_VOls6QFO#aF=$I+wUVjLko0Kt+?sa_H07Xie^*9 zw%OCZtnwIUf!a40ZyzW3&^2}RWyMOV)TeZ^Ay|U;Fg=WEvU1Tg=sh`eOUy5ALhvkl z+IM>o2J~LTHJ_0O zlaqwp(1bq%qiD0GWV?*MyJ*Hm+KeL-qSIp}e0CLQmmd7U%?;nL7lrJ(aL+D(E#!#+ z2Iy6VELkmqe_J?CE?~jFAd#=nyb&eiry8)d&uP&1Je}#)-7>Nzg#08A%JWo)qGBsymgF z-FrfV0)ys*eHv$CdRg*Vakm0j5-I!BA;J<6>*fcm-sw2?m2Wu8!@&f-jw*v1+%ATU zxx_Df2d%AeApIxX8;7N~8(I_iQW>TF$QL^zrdDysb{CON3seOHM`m@ef5jMgc|-dj)XpwLjmZ&!(3+gn|Zh9>Os>0_S%+tUb;O`aS={w!=v zHZgSnfxMbfLavm)!m=o$wc;B`+%h8VgCGI>42n0U(S9Q3{A7?VzjK2KvL=$4O}w*F zt5%C6n^qtFwP^jFjigX&caF=DE7P)zFJsPbgx*t8ppd{z_SPy&f)s&1Y8QYg>gwu( z%a^qOjV^&jq25wh&WtARYaidm084%U$(Cge3dUfx6Kk~tIf zaJgGzz4lgpZb88ZbHW%xe7B9~8a+KqOpWcoMEr*cLRQT}{d++pAwfTpuZG_1*8(s)N z(PLt+R*j9W`106K9k>u-R&`U5UO(47#2v%C%(?#ZUd}!PpWC57_*8)*sXmc zpp_W1SB13;=RLcl&)=(Ej%g6it>xB&LkC6-ZJu!4@eWWO%UmjPO|;r`2|5gM1pDY5 zNZ1{Cj9jO0(aq@RdD9(ZTqBA~x_J|i98lJ>9{4hbU50`CLf%kFnX*9$FoNaE% zy)s@&M#Dr=?1KaW0@G6Oravz&^mArrH0%@)7qa;Nk}$(k(HqVvVsg@5 zB91B@UBJtZ8WmMyP5*H)4=$dCqMZA)?L~&=XNX=vcEBr^TBgz$Ou29%$oZH zm&vvTE;k|9>6$aQhej1hrOgJekJq_4fpv{Mw1pNsqd1u&R>U^-6bDpJ3PJ+*CZ}j+ zsFb@dsic9VjyeCipS9b>1paEiJEjT0)dQeQtI_EVkLvSU2Fej9f*lO$!3VWx4iJsR z6_!u)cl;qi8ynRBgrfk&Y`3kN-7*lk-6-}uXg+hy(tiV3R7zyd|LRT|+*^#L5x-TB z{{29=-G1IZ13OozPpFg|{}28+=gR*BNlxuVwRVRo#R^cYG;;2(Dpg2o$`L;vuUn-0bp&J zh}gfepdaTP>~a7=@wrp&Uo+y~KX0sd=UNMnjtIdJPE0wM3_ZDMLH08p_^SbX*WHQP zK~3GjkQIGptMVxC$hutptD~QG_&ks_QCy|(#l=6WUdZR5US#Zk^5l*{|2H@!}pJxVAVH2wtQ>ky1)q+}*9XLvV-U0SXi=?k+)s zYg^m{q`13%>Hn2`@ApiY$&eW){ABm+?%A_C4ikT?Mn>Md_3o)XlY5d9ZWm$yfwcq6 zRkfE)AJ+aL6Uvz@Oc*hSy{t^T(=44hsN?tu<(GtLI4q@J_M%mc35Gp_!#ks+Wy>AG z1v=DJl-+GBzocDCRdp7PB36a*$E9aqGf@V`hw;DBB=2rn6^lke*w$>6LsyR=*mAxs z2nqqz0gT6LZ)t1kI4u3>p{3Ot%)Fc7VG=yP zGcUM9$+2G^3&vi{JJ6!=+7*1(p)=Z4Ip-4JZc2FTA4@!~Q6j11TJ%7rYE7yWxx`}zC=-0_!i zn95im-M@WRjpPfU_*XP&F$xZipL0w#7sYE44lbA!EtocGR zW2d+#b{I)AJVd-Z!Bh}{1Mj^N1Vz?E6L7YVcrbOTxr~AtMT56DuKz%Gd1mQO7f12s zpSFDypX(P6O9fhGP(HOjI#PB-Tkoyrigj2BXV!LV2$9-+qf9v!=Mqah^cJ26T&#>rbcn(Xoa_vj00GG)pJro`DWB+m zv}& z21)*lO--4uwN;^B&{6#M<%zx%AX;@cINS-a66ACROE|(A3*t43#>QZFPHMIwh-8s> zY}rsG9$8EmAvCcgFcj%RhZd`#f6sm!T8>77C$HX^WEPOsw;qhbJ-5W9gi+M37TrgQ zF>Po^VhiTk2P?C~_^-fLDkPKBWJPIm=yF0XL%lD#9wsc`0asE3)ns^IGh_o_Q)1Pq zrHU!s0N+-8Nk0|s{r^we-wMZnor`IwI>@W)`SW#jxPXj@2LOW%gG`wXlZ`6Cy+K>w zV4+KCm`byuAZ9csKttB*EybDw;jwHu$f%6B*AB;G0kau&wV&nzOm(~(!+;~r;A%Ld zY0&FmJw1(F6wY3QCyit#Vq)Au0`x$727SluD+0k#R5BYPP5fvq!fx#Dj|h`00QNKp zNMH7r=66E2kieCQD{f8CBwg_;rYE;%PIoI+|Dpe|dQ(yOmsA;C_C`*!*LYmG7K)J!u-HCCW5sU$klp$k@lyUCFUPSCl{kXv#Y<+w z##i-%@kd0mkX+DHLIiQ7rsD87hZ3{b>GF>?#*vKlFNY%8xSfzXKB3gieX%^D@w@nV%}Q1AgYAHD zV-Wl(1}bD^>vdKf=7g6?8IwWs6&J7LA~E+n)Q|%dWH`f&qHKXP&5Te~*-9-r>6+G- zrpGtINfEsB2wI1I2qiyUZNryqx*O>cemElPDw=~~r87iE$E7NS=IZl&IDem&^TnZE z>Th-}WWRhy|G#M7x$6VSE8ZE3`No11b{fFrv|4^S?`hQcIa_br!y+>`29w!04_wuo zL5Z1;I?H3mY;==yjZ=)t>!t~2M3)78rZo5PBt#jGDq%Zji+k<9yyOh3dA_|>-5c;( zY-fR5z;*wZ;KAxrirZ(qP=Vcb+vSvRxr0R=yrImflg84%ijMSEV@5|uK1m!&HjbKQ zDu(4bF5iRJiunf#1kx_Qn$lS(xqROW%O68~T4lijy9Q^`Z{+o^$5L0D-;fJ9Z(E@> zZIvYeMaw|5vkuVHZbOCuB^q&8val57CAXu`6mrUHUesqmf$b*;h$&VsnXgXD08c6`8gfVuUD*Bw;7b?ox7)T?wk<~ z0Hc}M7YFjeQLAC=IP5As9R}?Ec-T%?0WV`IwdBm2<+XbAA#|uJF|IhUk3q-513v*_ zxP^N-WAyxn#N5TqQE$iE(|>SLjfn4HKHot1#>-r+5=cmg#U_4g{0Q5hA^AdW?Mfqb9?s)YQQTVWsb z)Fj3;HlXTvNg+VDrK)bA#@WUuSA78w#g^kO^e5y6f|Pm#5J3q=VR`>7&d(xM#9A2b zn86aKhQ23rt@-GX0Vk42(e=05^k0jy5rDMnt80mIMdZpaheTs|v$f}XAsV}y^<$Hi z_(^OL#252`k2@f1P2MED-SO(M%e8PRwa~9&e{#4kcHp+p#KP+7qt6|uSH-aDX``Vo z35Lt>h=Gd~N@G}!Zv43~n5-E2IM)Bx2p zwdY!D1v6ydH9)ynfTJn!Ym<|P<>E}w;4aYIj# zc7XKK*c3d5PXq)6+OF24AWkrf>ru3JsZ+=v8(L4R_{9>w+?dbb_D$i={Ej z?z&iWx+nFASOF|MeMh*xJ~D4Xia^buK*V*(zF30?W97^%LZvg4_g1{}UuXEwi`j_f zFU_vH6k#~wAMj+=Z@+M9NlY7yWh%cC2huyzF!75;=cvD&Nu!&xId6FTEYP4u zd@h8}))gG&DVd}r9F$Nn29gdqg?rEk^U~wcNW6D2`W;HPtp91e7JKG2?o!F}E%*iJ zE_N;t)~<;jFq+v^T#V}Zg`F)yKwjKaM z)d!EmG#p3L_~b~_zW}VWddx@BchdLhc-RD}NPgl;gWN*2+l75xl2401yddC+*sI^j_or(FN$Y&*I^-{Q71-@jm(SGs+#O;ZS>={d#i zz+yeD?rX%$eCzD;;5ufMbQ)dgp}!?T(RJ;2bPrEVWourJZ+kUn%qy!nWL0Wc1fi7h zb7D5Q`(ug6eG=a1!$ZTOT+>vArT9qG%cyXP#6%%`)&tF@3)CbBod6f=MTEJF-OYt_ z$HSJjpO>wl#ozFCuY6|NF!9;{#I78qv-P)RVlr$b=B|3tw33~%rT*>U74dfTT_3K; z_k@iG!e2!tMFS7@9094S92Q?Ks<7mv4#S13SlA*m^-u6qYFS7lx5~MyNKMaox2FnL zJG{}w;6`nj({I8><#oD05QRqdlRGW^hBsg8BwaTu{YabWOz@Bq?^O&>b5>>uJU1B> zep}m9SqA1;Eh;iktgR~K(hqwFJ-2hPXPGYwm%V=Pcb$6fv-8+K62+bwE++$qph#lA z4W6v6X;jV>#5KYBS*Wt>ywuTfMPs5+*) zue~`MN5Tf6JDYu2PsSuU zAxJ9RKacmsn4G-ThUH-b7 z=${J8CZR;rXS_7A2~xc+s%iW6x^DzCKzcmlZlm&jnkEnZ;+qh;*sX(w#B+)C<7yC* zAh`ZLB_1rS!s_CBxZBHI+@Qx>0FRr9p5$EN3ae|CCqM~LQ(&-k)hMg4<=dj&mWXSc z!}Miv!-gF^(Lj_3`d$YpMPSDXW=xr$25c5aaQpiJ3_uPf1!LBH12U7?i|Z3^;fhu+*)_g9SPPLUzTJPIF*kb zqCdP|X*j}WxZ5x6)`IRIiZ*aNce#p&Zm|A9H;5ZP8ckaY3-@ zg-z!9{-R?TzJ*-6r`Gf>w6e~r2j+Mng3PcW?`P|H_hca%TE6q2|Kv7m9QHV#ya%-$ z&g~gD4D$RGK_U^j=iZYCcPQn7rzduO%o~V+ACJbn?O_bLRP`;ig=;RUXF1_f1T{1O zN0?Fj#^N_EGY9-x$5)H9i4+1@C@&TY76ze$EY5BQk=W4*3yq%44cRJXp`ZCx&{e2zZW|+AFb2E*0F=7b)*8#LV8siz+r@dYbkgT&P%6E@0T_m zwB`C-s>}0>89Pp|c`^w}fP$y~abYh=GIozZ8o-q2%@lFOGj5J7ktG z>us#yS<)c}vyXf!Z=E+yt%g0~#|o$E^eGkSvN&+@u@8QIPTC{vtt{*tjfUVEBNC+P zV~HeJ9*R)Hx5AP8XrB5L7pAzCEk&0sLH1lsW%_f8ILS_9>4)1rpB4RSOidYp%vT1)R~qs-1ov!cvE$SO^kD~omI8!S$Nk7;y-NpVy& zoTVLBjW-^cN=aeOsToy^x2sczZI15>fbdF5TN8my-mZpIgdG~omK8jHV@x}jrkYt& z8x1PQ@);*k(ggZh8-Ei1Q@*B(@1`bm`4Gix(jjFZciTJ*;Oda{bU79Rn81!=`l7C3 zX=MnT78&Q#sHEM4&Zb*tpTkao2^WjE>a|&b3to~)>TM?!U?O76j*$d5o6?x86S zAE-7KY#@7?jH%+s|TyE#n=NnOYI9xTsTw62i{FFK((xcDw z@~7$*P?%?kT0_Nji=4&fYJ!ZCs6OpI=bD1IBa}0pu)5-C!Ea2stQJk44BZa8J{5&a z)>S}5X<_A{`u@XbC>6VQy3;Lt+npa(f+Hpo{Si_6X}oye1d2m8t z9W;`y)3e{NhaOj$?Q-cfNj&4act|{BWUitrDYSAYvgo(??%5PaR3~pJ{Nc=LSy{Xh z`P<>jVQdAhp8b_z`K%r*)E($9Y0euDNJs5!7g@qah?VBqdu$;w%8$=Sk_``ZVxj%u z7Q&iH1&0q;jZFXb7c|ZwB3KRM8ZnEM@8VHDVi~@G&xr)zvi$VzqBL0?1P&fIrW|zut|H<<){kf2 z^$z)ee-rh+=s3s@L3n!T3k%X9iW!>jBlEA;SXl{PTIZFw$2fvAfXnF_r?2=WZKhw9 zqwU>UZ($E5dNKLP*O@-aq$<7Yt|a5}_7wMx%x9`m+%=b9uCdt~%ZhS|ZFWJpHQTSW zrp(Rdi@TSQ>=Ocgm6v~*#BO1xoPKsY5ME1bn>f*oO@Csu?8k0lCl$3~ENs(s-&8i$ z4s%>0zNW^8L;)ez)W5HHMfmf=(>pmv!QUGjYFSD>dtkAFCE;iG|7!(OK^R!rSmcYC zo;17KKzE7euZYyLwJDdlb=K7A%`^$J%y1*$C=0rEj)Y%S>Pwh!n6>Nx_$zOYlu33) zyX~CpA$(~okHas3l0z2qaF!z?Fix5*6+Jojk9`qIw&Y9*zF^j8b554#Wv0{vzU-cB zryFo&ag4@EfkEdG_HZUv7!IkVfxf8gu>s-5%bjYc<8ELCL|B1Ops*#iAn~{&K52$Q z-9*cMX_vy7fI||0h0C!H$9Tt5L?8Y`gn+ycq_nln!CSI6J0PmiopDj@0>E;F>Ph-# z^SuB=Z^@_FevAH7ofarh-b;S%vz~tMDh8;YIIi{^)6V~uh!-aUr{S$gv+YeTlOa?e zbq5!ycCPN`lA7+W5}Gtck7b_`KPMhqk-{k9tD2%NN&NOiAM-A4oQD`OV<3{gOJ_}DQj`v-= zL~}i$uMFd{S7wd9F^yx=8xi7a6)yr>8R9n5rhbZbKNf1*yAS{#AD6le|B-N_HmQ*- zSoS}56@$L{!b%lllkP_-=A>sox6-%Ll%_8_@#!LuXU3nq`zz@&9v9)|6#|XsT6>CeQ?g6#3wl&=3hG&)xLUQZ`SiHC|?B@Fw{K$4}T=V-eqj9jB!o0 zjQ8WrEB?#TdS&2z>bTDz1@u(UCRzSI`kZ*gT67q{Q~()+W)0$Q81KduaZ;Je@1$IZ z22oAsz55dyq3f!M_E3l(*~8rQ9)-S=5MR^gVG#oZFq`u|KQ`QXi2d)OK-fLxnB7YZ>iTJp^U zG*D3Giu5a>PxrF-4Kf(`S#C?xU-#Ky=hRZNasFxnK76eC>QB9Knhd!BJc_Z5ge7GZ0VskUjUV^MJgpU^OJrfLDFgQ+=iQAyC9hUx$Rs>wkkve=3oJN_jaT|3cdfW zI1EFZO~2ibIA0zIN%GM6UNQRbVDcifZ^dxL$$uU0P;tQbz3nebUM#wnLUz~jA}b#n z|3eKoEz)}Tq4>(R#^4dt5 zF`Bzqiw*;r9AOgYhF2Y9hTs-t!{zy7H>T7BTI3?5dOWVcS54K--k^d*O;G6S4 z3?eSfZ62C6)9b~LvKdpJBq@~iKN9jH*Jjkh;a+U*LaM;orZTeTu0u!n@|a0>^H$m zhEJ^IQFl$BamT}1Es-`bd3WbudVO2t)jdhjP`cC6jSN|w<$jqucw^YOHpZuTF)1FB-MuD$lcxZ5Aa`bTY>7rHLTyWk@h3*&A3GEVYU5XtA~20<-du(z@!Y)FV^Y`XQk-cF zB~JKDo8X3_dD9himJ6GWKYqB-4|4;P_dDscl?lfvJLx>dv2Rh_cq)FRMCJkfuXiQG z8~cJzmC(OqC~s>Z7gx9#NZ=AX=C%6nNu-kEi%2p;&X+8doO#8?NI@6ENlV_zyu4Vu zN#ky#(QCF_B&*|JO(1hZZe$gfW0Msi$3m(Ib2`x(Wj!~GuG&>I=KMh|cI>c%66!CO zpxI_|x1!eCB9Nio(Y=vOXi8Ilxp*wXQ#ITQgLueH zN;QlTo#fguMm5tSe4X&ErVo%t|2_J&i*SLVckBPIyPTHVpIOtkpIMK!9yu3g`SQ|= z-P^ts+x)^p>&^#feYX|P3kUekvZ3QqB8B}Wk-K&*7I$+qf4B6X!v@R)g0QF8TMY+t zlt7T2dd)CbycJ=hL1ugEIrTT8%GOR$1?eOl&T0=W2N0SK->|(Cp6xSRpe_*M1Ht|* zig4`cyXGxhiFDluBz2{sj)B%+k4SZk5D7Lpq@bpNU>J9+HQ$Xp#b1Pz20v=itpRyc z>DG*|1mB4rB!#1~# z;TkNGJMvLra>T;GqD>87W1Y9U^wlPU3iJh70MqE0V)}r`g0$RQa2*VAxCjqd;5iNq zdrd4@^xJYWQV1X+c<|}Dje?aG#r@6S3aU{wz!TM^|DECbWWUqmG41LGK4fs)B6~P& z{F;qi_YOg6w6dkC>_Dj1`az`&u741=~*%g zL=6@EMyj-^B?c!HH0st5S6~81fQwfMjg(}tHkVDvh1?)5CXO@A{h^|B>R2}-a5aF|I6KUuTb9?> z%7tToVqkqoaCvT4+O9U&OkOks9EXx;MvtB%3s|VcFH+`M2Uq)2ke$;JA~C%2BpVDI z(PA3egdwaD+ZIE3!9l24Y!!B$Nu^cyBP+%xv!ukTsG>Q>O%i}h6$@s2fu*Kz4Y~<` z`3}U;U1D;>UpLSrOuK?#VGja6|FLqg=JGB=N2#^?D@6d$@a{aaI6~dlP?o@%X=7!N zDHlnJfa^jO0HJvM8YXRPe|mkF73Jw-!%N7`)=63Q8ZzxD3~O*n zTND0P*ihz!wKtCIn#(NUZKGr})5CLFU;Yx~hE#9u6x6-KFh*??E zA2^depTp3JE3GERO%lz7EVI9I4GHdN^Tsdv(3fpt`9xn!e;CePX0)~-Iy+%maw*P` z%O_2OrXxZd9QV|CAM5VIT<#*qrTfac;(owmOtgZw!^Hz2hLVj2?+WSq2V*C^`)&&@ z|IUm}i3&@1WpIjW>a4^mbXKQz$nf}vt$)H{{^btn+mvD37sc!}ePYs211%0@o+uAY zo|CeAC_ix0V)pR$@zHh?d1UkIfqvh)q<_|V3_WH@xK`M)ihbgu-WZxodEr5U%BaB3l$q;e zb6bM{?KPFpRv7nj*PYw)3U5H-R4z^#K*3XumpOrlIe~zAl8re5Stx$<_54My!|&HS zZBVhxl>Qh=zX<L>CJNz59un1yMQr$qK=dVFW z!N46vUW8ai`L}V|8~<1w!0{|dxbeH~gIkH(H(Eok$~Js6Vs%EQBu2GN{)NJ!pM?#= zoyKaPu@(}1Rx?g1k`JjOM~o(MfRK7-bFKYUU;?o`l-tptzsFj zm;X$CLVA;dj@*R&R+ttoJml(Ja_4H0*cHrv3lGvRN1|*<{s1goKC;-sYTaO*V_j4o z176m5+Sc|oIh`;(#JscY3oJSM3`6(&OOf7*sf4w%XlZ|e7~>t9rs&SyVpkPCe+_@?sORKwH29!ZM zv>)h5(sk_=Jtwu;`?e|2HnzuKq9L+5ia1Sz`IShp04dlC+gNyoX&1T``~56BOeH%C zcU@E(PYj2JsKCyf`X>wcdJZ=q@D+#Ej!n6nUpC;qxrUzepbcD<)@HqJg>pSMY{lq8 zX%svh7LOSgaVz0>0*t{5#Dc+sX5N4@n)$Pg-oJRIzz%Pgx+q+=XDr zSD>1{sZc0UL!XC!8k&up<8ZrDTIW!HUYVp?QrC?W-Pb!m{s5@f!dk)zo_slZ^z-^@ zBF@+kNb$f%pF1AEqd}}ICwVp?ekgtBScRi|HuLRg)#Yz?aeb%Amh*6h4{CMZ6eg~VUHFL9oDM#=Fb(Ore`hr1 zID54`^yLw6=*Cri+}ccX=wxP7ue3fYxcP1EA)>e>m0!ZUr$s~S=0QOs-o@^nv5yub z)%3LK^roKr&aP!);?UV~>>@X`_+MyH!GX-wCG?y#)?G+|IQHu*D^Wbef={!HRa(r5 zLXXg5Jsv5tH5_fKd{~*}`3AdkFPjcrTL%*t`*0Tcja-O%UwET%c`v*@%R2R<=r!=oRsnYy_DdBZ&Z$E?{B*&)X6DHo`rhgepQdV^F4BV%#jlQSqo(t z&cpaJfxG-SOt4h6g;767cG-U`6eL8OzHaSkJZilq{dUn`)A z$cmm)QQGtqS0Pi^<#{$`#P(vRN9nN9Wnb^G%3Oznw9nV6;su}p3C@^;)S?Ib(g=&1Rc|`9R$~0s_Ky+?UuwlO-$c7j-CYv0uTQ2B5FQ%_cWivlb z`I_^(ep-`3cWtG8-e`gJZZ0@_m91u{X2ClrepYFgd^lXbM>gd|5)$%px1MuNn*i}hLq!=4KQ(t>-(eJmsZVe+A+#ikFVeK$d4 zUBtFW+_2B2tz&67FQx7xdOpf4MpZNr@>Vkk_4rIdSs|v_j`_eC95v)|U9SBjbN*PY za+v5R+5(dBTNB!S=Xc=c_vO-A`I_!d;j3&y7_FdT-jyuo9HtSr1QtU9;k=36uj%Qj z2~AaBU-5-ZWc(%W%7OTe@C-y2yLqA)|Mn`Gv;UWcgv-qTcm9uS9=TPVOXd@A|!{n&;h@zZ+##W}+uBQ5o4$QrTMiSGRL{AhItjc}Z_D(JTfh zv+eYBTeGDx1-7S_n|#k^Q(+w2CB@Y7O0k z5@aEoJ)dD;?KV%~z7j&^(cJpKa>o6N!{O}HYQGu+9cPUbH}%D-Mp_k*{G-XCUTP_2 zv&yZ9N78CUgH>)8VjM<9uSBn)C=RF7DQpFA3a*@#da>a|SYjyCT0~<6m(q2f5(_%o zSYbrbwDV(ilQFttKN3oMGS~!hf7Lgb=n~RP3XEHHtzs^KSd6gbBegp1FiM4(S03jF z2h9~(FsR{vz)H}_BiC$~>VftfvpF_tzwoBo-gdgmvoiVK%kVHDr&`n@#k`=ydhZXx z3gLF{$D4?!i$1Ps8abrKhB;o8I+=7N-KUIzRA99dPyG+x&?>}aTYgrm#;@VL7Y zZ@ETTzC+uE>hxy>hLxyAxtZO$; zcYvNkE$3We>i14-iE$6$ zVT9J7OO!SWM@Dru0RZ^QHK1~Axzq+$ZGbu{eBf!H6on4ll^v)O!?ZtWAP$u<0g?BI z8oFj~-unBbCRcZWZ$A@7g;iw-8ZNTI0Mh7XSU=|vco!E2@VWMT^b9Eaxh2H25B<&@ zAMEB|`&}I~reAOVy#Di*Z(hgRQL}rxhu|%FqyQ|S_ADY)tF=53x11NKRu=VTS0A*} zlfiR2y3`9Pm?)~Dbz157Ts5hNttl8*k$4ierBLI%T!yAf%*Pq{Jg^;HUlKPRX0r01 z?j~KY98wSKt%${9tGakp&=9|TzV%imBx8*59G8&lDg38-l!pU+Y@D~#r`#p>J=4f( zsrA)E7WR=6I$T@YBZ469SMo7bQ(HU^In%U(dQ`crY_qcylpWUL{j&3MNY?M{xTpDi zig(fTC)2~>ZIRP@(}z21`bhEMQ(uTHU^j?v-U~$abRmq?L0}ChEk2b)zwPw)FUh{9 z2wbR~esX`8toQbwkL>xmZTH!Q$3sSzPSYy0k0ewJ;RBvDfvL4`=|x6HUiY4j^I4sI zg={Xlr>x)ly<2H$_{^d#Cg|U|H2ps##z+uCETs6z@ zCZ`(UHTVuYpIMRGD%AfR+Uj%hWOmheC@;9Hqu4&GasEXzWNomT?Eih9y!xfrGYi!} zEw=k>Nk#7)uHSB%*)@JKW0%*xDrvLRnY$ZvretSv{xvZ*vg2ox{;?y*zvE8Y%iDWo z6Q^?cKxZiaIA5VH$@d|unAS;inw<@ zok4X>N~v`GR%hPI`Yn&`d$lpQ)*r|*ls#JwtD%8T`NJoz|6GItniMZuxC!m8rr%F` zW=vXYCi$cGqjxB(95HakNFFXQLX3wj7}^uSTh}1ubi5&<`>F!y(*;g^`qGpC{npMq zP{tCOY&LpSn3It<=JC(D!{fUt5c8(*+ujVUW;TGNr+vv(S7=HKHN=DIZezaZ`cG5G z$2UP4P?&bK>#EL;94;f?VZV#gu2n=b!G(;bIx34g+8`jf)=9cB%c=-xttyd6BGl2b zsUn?VIAb*ozx?|k9^D=Th`4uPP%H_IfQN`l$Jjx>XhIewgc5AxDov&R<2rIdZ>9;K z3zt;`Khdm@z;F5ew?&p0wumFZNx5GL-pdo=jgutsI1wEaz{AcFJxO^|0a*}(`uJaL zDp5WBq4hBm26v;Sww7hxr+M)_n&U?8%BTm@G=5IJ4Myxaw?}k-Za+=miT;30@vQ2U zokLlU);Xh#qj?MmUYko^(r{K}RYh!wYXk`!mB)M_ySVDrLV1C8xHtE!^_P&~&&oV8 ze^;rF6<1y>q@|V7YRddq+|rHI;4!hFy&5+9zvaZa=KhB>|GLITr)gnYsP=FhBIjFi zahj6k!{A+o_zrtbc@ZdXZi;1s&rMGxh*W2`@kMOQg1{{1Aokx~* z6cNVgv+M9%?CJ-!l!Fmi3xKRCIKcueEK660(2{!Y{_HSP5S;LI zFoL0;cs4}auR%uQ5b~`k|7F-u?0L2*vRcM9OwZ=uL1Ns2GaczGKF69|KrQLk;P7pa zin%h^Rf>+snV7qqbnTmz6q9utUT)#AAJ`IsRB<3%8|tF-#=AWwb->EX#EvM$0y7hk zYif{#n(INhW|{Wra8adfC11Y4Km%s*xQNMZn7O9;jp-!@| z51UPzSi3DzL4X?)prEnD`Fl>u^a zphwjjO2?kt9bKL?gO&1RiLs=mqEnT5sbMa&vQ&&Wln;{L?li3OdISv4iMfs{;&$uS+UZI~RmD zyb=4O6@kno1De70(oeud@yP+v;Eld12A-Fx%rE77KgS!!)7vPA(qRo0rhkU>3K2cE z!L2-J5<9w5?6wU|tTt?Us?o6%P6)xGnETaVKnv+!X2f;sB%qYB1QTGQN|VP&ouW?D zcg;@jqXxz+1Svf#DG)r9)GtC&k`+`isI=ecD_rfF)O;Nju#mmIu@&Y;G0B(F^s##a z2WHI76pn3bB4Y{ctGBs6xn(`w=4T~hAv0~y|QVx+zodWyD`AVlSHO9q0VbugPV17;nQgTG?39VVpiqVC5!CA)Xp>J zgC=z)G2}+^r zpyQ0ePr>po`k%GYlm`YK<=c*8H(#11D;-Z3e3jNiloXSn|5__gxi2(Lzg3pJXI}f7 zpTU0XwU!*7Y-1wQk~mblsKzLbx3nUZUhz4$JMiZTQcb$nT2DCRdy;Hc@ zYc_r}EVVzpu~Sm-`o846C*cRTb4=yhMU=d04gNcKhyvw6Jt0*~3ds2>JK48(*O*12k6W$bXPF7R`K& zm8&*6RuXS($;)}jlg!~|tX0mQ?f!FNYu5gF-xGNzx)zSIpw;jrr=aqJ&n(XTB5Nw; zpeU2H^mhB;_%dr;OIwEz=(Gx(H)k*S`T@CNzEeY!F{hPuXi<#saHI^ccOw}Pj~-}5 zrq!_Tzhj;n5}*iTvYp!^8UM_Fjt|RqEcd;FahjO%Qj#ZDf{gHa%`b4>pxUQ7_tzin zeTq}N!`*ZfSBw202hoI$Q>zSyt^JOwUnp~F9`$7g6HmPdaNW9MNZ#~lYljLEzm@*; zW1QOL8wnQYq%(5V*8{Lx=P9Dgo{8S|UDdSXX^&0Qp8ToNnFI+ut!%eQmW=h`TToX` zp$V=9tpJ49&r#KuX`}D`bEqagU3X-_X`IwERH?4|xU=K!M~G@g{gOs;A#LMmpO&=6 zi>=5r*9v4ESOo!RZMZrX4{IV=M@{NI!=N7~>VIS48;(Jau(Yx-$No+99Ch8YVRw5^ z6IvpF2!;61$9Xr=SI(&$UtR$8iDC6xC$AU?4>0K*VS$KE-am;(_85* zeW>oG+26hHX^b=eIM#?mb64CbuJfV&MD9~8msSnPN2=Up=n~RBBA<-6Y zAq?>$mT%klSiWDzci!?IM;tN6QuFOCCb}liU*JCAYv`Urr=64GTP0eJYqW1@qd#b| zMy`#=ogXhMZPGP}bPZ*k|8D50&({7me)9V_U9Bcjwnsyy{rwwmQmqb=6DXTsl&5PF+DD$>h>{6ZOWt+J^z-4QOZCXIDvk5{oCH&wS+l-Yn27`!^xn14~-3A z>R8hEee9_ko6)4GBjD!~sGh13d=_}&NC85!)EskiI}1Dywvg8^4g z%J)=Bp(%7*v+4OSR&~x5MeMDq8N*2#Ox^|*k(CF3!<7lAN39Omj3i?q4g#Bg&lHE@ ze?VL4(v%r|ULBHick$`Kza_PyVe3^}*-%qBla8?~gEFN6q%ylx$n))h8DlSi2&MX* z^qcF{bQ9M5moNZt)0eiDlMPwN_3-tyl^PmN`#8&Wi9;@vpqw<;f zeVw}S-h_L(d5--@dxWnHL7f=3wPg_%g+Xa$^g+X z#f>jE$qlLXxNzl4v;8_0+;i}Gbe@OG6d{B+i^*ce>q;t!>OM=+^-0RfHhU3|-{mNee9ZZm&2>a8O&h(#M+}`S*SPS%KiqVgk^y4719H?MO z;U2IRUE5KgL`r2OkJX#4m3Ci{|K-J6wB>1k;}@-jW9uhY4&J5+9i zTlF-pu?{6V#9B5S0PjCRH6}dCHJM({f5Jn7ooGlsE43@v2%&BLwbF{#g7$FQ81<(S zt&3oRz`~Z9=M|tVq{$uELK$D!Z~R&NGyB)wp!c51u2dqJwNK^N>v(w{D8oC6)YbvZ zQ_4048BT_L+7ZUM;PiOo7e;F}5_xx+W%U5UUQ`7YG>b%#T>aLp#S9Mm@uv!_*E{ZJ zukV^!u6D-F#0l}mo1am=f)hc7>ED7uP9zZ#y;BQ%rm{L+NFQ8O9B5^uHJ>q~o#IB) zd>t2sDOaDwq_$aaqXm=&W#<2y8SNj-?CvF`(48b;QlUd5;;7h~9fr`Nr^Iso*^Xe_ z;8@pf-cB^YfMWH&RlY5rOzUFc8?doM>x%O~W0bfaR3+%=HE2CiL`v^UNbq?J%2WHk zVw8_D-Y8ZBx}Hsrbo^m>I4hDo{axuB^P!|yUeb$D@?kQL(!J={n9akc^03+9jPhYe zwNt^U%g=PJLOqF2r;Dw0f8n3bw@1x0&DSd%F#bW+c1YuTMdL3O3-iI8YZ2OSS&&zC z8V0RyxTz1rn?Tn+EaglIm#!~+$E-Dn4;YRU^kJt^e7yl;RWYr```C9qY6T5OO8PE~ zzWxc4V!Eb-Hp$~RH7j3nRIYRN&up_#YzloZ1{{afR3IL*#A-Oh8X5*^K(Y3&VnT@t zn;{)M$mf-Z2HVP|T2pBmmREaI`nd0JBY$g1VZ3AKanemGY%`P5kaoz)uNN+E!=vID z+1q>f=a1q5IP?Xvi*ov(!^hvrYG$o67IhyFyr=AcyR{5|?o=}Y<9+nr)X9)}2g=Jr z9^+B{R-tNJvjoruVrdG!yP zhy{Z$$*$J*uQ1x+1H6Av@~lnVyf4+dEYcn;kcfshnt^r*9t%T}cmZj3tr74itf5_9 zJGe)S?1WPBB}z?@YLE%fw4rYAK@TTQs-Xvgt!`Nv&*2^OwR(LA|o{lZhg zF})3wwDBrFcLjVc71(TxUCkr`==*{ivEawP&V8K6K6WMP$eJ-2V01H? z9(k;FvL4B+n7KYX;oTa=GKS4jzy{b``Ybr7-(lIlWChA#nRCeR1NlT1eZ@JPXVa;t z0WrKBNBfqJ+L21>oe^a!I(Lt;&W0dz$A+9X@IOBLxSYPLhemTI%68 zH|2Nb;8?aJ{2ek(_FW}Q;p9~J%FyEHD;n{q+O9x*bYs)~&J$R96FP=gIa{@vzmkpL zSHqQY?zb4Qbf-%i;wRF2eI=CtI#>;ScC2xO1AUKf$;gfU@H`mBa?9!rT>GpWui7L? zu+Y~{3lYDAmGX7Lh86S<7|sZ#>%95ZlJ|L4 z&-Gu4fTY~qSWk<^M1p&LO}4t&V{Rr_-OkxD^d3;Q<+_!2ED`b*QD7>|zy@BM>ua(< zVTZ0fb~d)vS=1fVb=LwZk5eeFu%#M*;j*3g2DwKjCVKagyJW!8lhEPs>D7{WDP?)N z5v|)JV(IPyrt+dq$B|Q?LsS23`St^==i&_P;L82@I(T;#u15KRh=uH9yz@aAO#g{C z(mlLLv-rZzG*4cc|M?vv5sy&pe#*sr|8a-eRt}#6uMNjbhy6Jwid^-jtcU zRqNi8e-^2fGpXmclDg)Yq2TTa!apPTaGCLE_d1Sr4+$&zU)m53eP`+&V2i{4hC?#F zxMG(tY&H;2O72F;#4PpXGa4(AL0}!Gad;;B*nCH^)>1Q^4u}CNc@l8htH3}(1eS5| zRzxSQl+tK>Yp}l&dLLG0Z65(hcE_8uAWJFTDL2xa>4|b@R-)69#~n{gsWYDrlOHtl zqY1f?jlJ@XGrCWVZXVar|iN4 zB8+{9)A@6$9uN4P9>za8Ax|am?xJ+>*4e|4qbq0zE80Yp^PrX@kGEx>$5X_#lG7}0 zPmVuyHGBvtXI!6_;QUeMuC3I-%!5RaR|o26DzGENCwllq3D6{^!fPIaGy0*L3{q7a z5?}8Y743EBZ1KvZDc@(*b;;?a`1LZ;ZzE=#-M_TwZu_qqpkzzr%m_3$gjl>0l0r}I zcMLOlXc`$?SQvOh?q`#1{`#?O%eYO|P{7F2r$(B!0Nb7MsBKk6rLDZHVz;{94XJtJ zqtdoFpfC1UW4G+QBZQdOcAVyJvrWRK^J0cb`2Ljqv9pIOQ`y>@bwvEu0paAKb3-1X zzECOOqNn1cpPIa!ifELs234vy&IMUcne5$qXTVxE+9ZEnwOIKNl8s!BP3%z#*YWGV zuf?vNtX<^{hiY66x{bCeyK~w^Go$!ylxW@000-5d%dwBIXPb!lU1bDnIU2rEE4gQ@ zX$U^pWY`jfQGE&NADTE0UjFzXn6Fg$kaw(PBYbjT4s2I!dQ!C#a4{c1Yw#A zIOV^n_~tvEe>VxbDmVMO!|3%>EXLsO4@zbZ1{)n>Pc4FEI)KrM%55@p4oO-yPXUyj z6WkZav-oiiER+dY8cmTBJzK(Nk>?lInpM5O^u^RpG1XtMTFDkaV=>9p zRU_;KY}$CHS?Zql?IsDpij8|cWNfrHHMJB94}=J5tU%Z*(fxCniE^d~t0op+M$$=s z@Gj*EMyI`-&d!4+Rng-eZ=6we@RL|z#58{5(3h~pkR@e}p&t9Q<{N)S<(yCHYJIVa zNql^bh<6*6#DUCNK8`m613h!S7>-0wy5MtYewQ_AsD26p8oyO^8vl(%c(?O!`LtuX z0)`41=m{^E(e*dMQoA$vH&@`BhDHTv@w_aNO2=K{hLpd?Ud;Nn>=)B5Coc{&Kj9hE z)Z(5P42yWsmernnws`QxV5{SDP)g4Dr1k>Bvj7b6^roId3BVl+a`AjU zd9lY+|K2=rZ=d!lbNjnhnS+OWu;BDkkI6s@<#35X_tGdA@}gd0Ini;pGRXgOxdn3h z^>VqVqQMFUFz?=Q+~dm>J1X7dPb#;cf|m8Dc(k@>v?+<|^McOoLfQ_EzBNF9YNv%b z&494`z2!^OO>;hF0ChYSgD0lF|aeZxv#hvgERX_5JdKf zN%L^G-KtLEgW0ugk9}N~Hy&6MmmD9bZEJ6@L8i^|LL|A+CcPBB>9OZEK8AJkuKit~ z2-488bDih<1unSxeQ&X`tLmomn;be?;#LYoaw_qUL`*sUJwFx%od-uz4&wE=mhHN) zL$nOVGHreo@^DZ2`M-D@f-VIL3VMzwdZIw`x{06Xtjr!p8qtX%kHLr^M$tl~xc6{p zPxGy<-?f*=Rb$*_2#p0I#NjE{oEmq?^4gRr`)uF|51tkX9lh0mDZ3H+CVW4M5ut!J zT^OFK7hlZbOjW&Q;!XS#5djHe2B$JnPfSQ~tg}0@h1a7m-T!f>HBuZE zc^Z9Tzwq<0IuduzA(Ag{F4+T%m3f`6^#v7kXhz@^G`MIr``?cY`iTo(m;@kmdtT9s3hkv5 ztNC7CP|jS@sslxNekXcvqt-HOb)tr6>|SXH4`mGxx}wi$A6_L!Un%Qj7?1QRt*^^c ziF3Hjl({GtpPGgu(~dg7X{(kPrLA8mwcf1Wm^YycLz9g59`;mB<%jNP>_sa`XIfcv zpjwVC8+*bf5RE50IJIC!r1S5xMTm)h^=7+iiu%Hr`KK^#ZMY2Y`6d1c%AqxbFDhKZ z>SmiOFRH9>=0*=5(GL#DY5bePGN7Ao>mT!9>+kMSdftE*k;BDJ2bma$@xiv>Cg+bZ zZOlnJP8RA3BSIxw|6f^gwanZd)tbz?dbKA29x}>8;6$2`mum~v$9p#P^4+;g283Ms=wgbTkXj{@Bz zwfY(D+br zUr4>W&=T5?QcSPi(0V8WAKUyqw<~ohsnD`7#VV=zRH9X!QX=MD`Y{a!@viSyG8RA1 z{r2;Xh-yNn@o{?cXmbZKYttGu>=*Lk(AfKTuhN+(r5>r4EY#DwYZjg%^NhLHHn=B4 z1Gksq?yTC=TZQ_E7USL8E-IGD=LSj#ZULm^#=KrH^*m198#L>$B>3>XuuUF@?p*uW z{MP#IYJGDA zqy4$I9q!cG1p?bN$|pUX{%~zx)}ZD-QMW^X=1GWY<+oqo7@6)1GApJZR<~$3K1K!{ z-YIfliOmn}Uc}PwE&dMtwExqt1G$*Q;Q7!LEt|W`n8)3~`~CEnoxk=U#K|PABxzG-aSJ#Ri*@3sn~v_fXM|{!NY9|+bF9q z3u22)B+FDVjqmgMlzj}~r`y{iy35IoX#?itfJ#weHoC%Cbz}0|m>40ihEZ*PEc9U7 zA7oh+>v6wc0|TxTL#{i?FV_zhFSiaKTgV%XtEoH#tULoecbEdMGQ=8>jIXv7t&bFF zaAV)`m~fiid%q!QtFIqSz$4`BkjH5lPb!s4!ZnZqpPCl%+1juJ7J$}IzKc3KGVTo2 zo}KlOas9T!qkWjySoC^)J*~qtjmj={Azv>mRN48c#h8#_U|{r-DdYn5o2)D!bO^yD z3^;Y?Kiv~rM=II+wb7coojBIb0_&;Ssk>UoG zm4)w)+>1V5rPQArctPrX_7kIvG}AB@%O70zTBn8DEXv+A(P@`W?m^E<8*fZ#gNGZF ztfS*0Crs&ImPcv?f|SZo7mM^mu(kga!=_Bf-3FmraLf}Z)Ef5qG0vOR({QvgZeGty zDGwVzkEYrOnehaL3PS` z2(fmh3Me9+{L4JS4J#^eX{!3cF;Nt{QH>VH!=nVGdhK5UTc`xbu}|3OL~k}qXQc~q zG3Aw&XN^$8V`)kW58+ohC@m;V%yU2sqr+gD$G<|fr8XQh&Svp%3~e-j4h1%kk4#vn z6+a*3w?vVWjnHYw3l`PhnOJ2?tgx{I`ect1EoY~}LxdX$I_mCBLKc1s}Ld2Q%Am_46auGW5kT%TZ0>}Y+L?pF}?i~w0` zIm3%=wwsKlSjsh*(Pwd_*bmuD-AZ8dt#z5CXRLGm_&+*)0x!1xS6tDX#aF=&*ko9B z0tskXNvk}y7HffqFuKN}ThaYJGmcV{wTEpmot8_;M=18XTqTg8h?Xb&g}GdpwmYRY z>`4SxmY?qc#*Z_4#8Y$xK0N~e;db8EPeV>WJ=Zz&QiP1(s#kyjT#5U~_O{ODZ?5i* zk6=Po9I)N6$#t^gkX?ZOZT6~z)a;~8Htm4%i|wY3TSeiky))!oa?Y2^bRJbRhs@VA zM5TKALw5IQzt)ZQwRP!2B0k4#HVH5vLJOmLvRGa4;HbeZKs+9^%4w6>9|9aFmlOyz zT5LvoErL2)dzvI(errs4{T9VSHpM5(nQT)B#Zpel<)}54G zQGw5HZQ!kc@Ach%%3eC7t2=)BW9?95(qoessbYZl*^5xH;AwYBn#-yC1tR0-SKFIn z?#ZmK?uL&gi&h56Zpmpi{h=mnh^zU9Yj^CT>kQMf+vNw<%$@x=Uo*#WzAqCLs(wyp zcQh=S7+t%2@k%=}bqJc-za*I1#+{5E^Z4dkr-`pnH6*#j(T#n=ar@?;fBEPI#eQ=E zHleVf6XM%1=d~qc4hZ!WvEKfmtM?;~>oaE+S^2t?cA6A*=jKl9(CqVi4%SxA0de1t zA?>jlJmA%9X}9dVOAsqfqWR621jr8#)^;)DjQ-0x#*K{zav|iwlelzYufM5yrZ-c*8eDeA9J76ts8ERkFj3A}*H4lQ zm;(#H(h}bYZ+NZiE^nvsMfzIy`K2jHpjv1ABOzCzBI<=<+n)L} zRQHd|Xd7otx$TPnUM=Fi>pbL#&_Sb`ba~CuhLwunf}Dy(06#0OSd{K<9dCeA97>SQ zQ8C}0c7BC5n7Ispvmze#FV(Qq6Tg<@OgmJ%(+OPGYK=by=7+>ei!_T3sD;ODd@&y| zPl-cZGrq4m`l3bn{=X8#ygc4p6R$GvHDt=WYDuCjo>l3rZ|><#rfF6K0WJI*q#4gFW-aMT)yhu;Cs7f%h8aW@{;_Z#IGSDy;O8=R;3nYX z3BZVN&0afO(d~No*c6Im#6}XDD)*f}{P8p;Ye$VTy0{7Wf@d9vw{^Skd8xsIDoZj< zShDMSR0|ZOSgE6+CK0aUwAsPNNCMG8&|*qAAHFY;Jg_pdhJ|0&^_2Xw8azIMC98_h zHR6t^HfNopgaS++x2-|=JLm5xCY#o2K7>&}Z!^3ZZPq zsGR066wK#ContDXl;a?3Ye_E~foQgy@ZQEeIFG;wx;ylVtG(HYQk!=CI{VbziK`TU zj|zEwR?coW&%AQ|q`X|TXf3-&WzHw1V>`FIZ?W(BX8p(}G2Ud^M|1ex?{MdnD}g=Y zoy8gj#fr;h;G3$9+oSlpROiQA&%e97b_S)Ce_J;H8#e!g);Aoew&>+3Qg&Yu zg_K3dC^ZIY!n4~95%CeHAqul?p0=j__rb84BGE59#xF{(b)o1~z!;eiWU`bU^Jr`r zRVz-M`@*keIX*5_I&FNtdztspUagQI)GNbm0s6@c;w&j!;YcMV%9-pZe=vof`VZ`I zJ9c1Sf0!g9kcHh~*RjwkG{Za+Wm;=D!Wieq?$%ENxUQkZJlhWiUEq-7xn_teCJ~3_ z$@A~69hlKtBy%0k`pX6#0CQ$oGeKh4Z^t~f+VBJ>TX&~UaU526oKY`FoSfZy?b!aH zt>4~fl;n=}thrtoftW->Um;^z)(HSe<*SwlGrc}xghDQ7>fiQ%Z%O@4;ZJpFh@10| z$FZx^0ckraZ46CPUZeB~I(9SmFMrhLhgzk?DqNN09HO``|8 z+qTWp*cjn{6wx~NDFpkWnU13IFJ1k?x2upxZVxq-w0fqxEn}U;NvB5ZyioGC=6NaZRNFgsK25x~cNG;2rN$+q z!gTVi+IXN6Qy$FMJ*S=l#Dy$g&jTIg#_)_jYz>-x|4EAUG(}U@QP8 z0279~j1q|?ZZGM3;nM;P^{0_ae~t?i;%vydkPl}D?h9w^NS0}Qr!#&&lxAa?DknxP1_T4^A z$@N|M%4svwRMvK|FWfK{{)?~NuUve;Vjp1;pjqnNY9KMv5L)&ojzas?0ojR>vLMhS zdT;x}sg@FH5Fjw=4bEK&v{&~no${!=*#79&w)2}pTYP)r1Z?vg)rBnVl67Ox>*C$% zz2tHDJ|1H2x&9_@n@T$%R*6OW+Xs`OX7|_<0=tXMDKvgT?KhH#f0t`r_|v8W|4WJf zz5ZQgO9Cph&hM7INw!z8pBD(@X_ZJF4_lRV0pWNUNoJQeM;i=1EusQ$Fh^UnQRnnD zBM=w@lvoK5Xv?u@tEzp@A-kV*q8Y~|aI&?EW66UBbZCz6zbAT~a;2`Hp$q;fw2S!> zHtmqin^1?Hg$r#krV=#rV6vv3e_wA;SU+Q$oDhRo1qpU%Cb-v`kfkF^=3h(FQoyKU zGh+&o5q20?*gN*Wp62#NPO9cIR)x(XZx^#0X6}BWt8yM%EbS5uWq==9Oorf9pC4ih zfZa;-b+KZs{6T?L0R^rL3+M;V6ZkI~BHVD_$(Tuy5Ju$UH2tcmp^Td9>@=HdKOL9PNQOmjEW!C=PF!3%e-1nl(-s8>MbjX&C&=& zOw8t*{E+MNi|&&CmV3(90TC@MhJVsY3<5N9&`*9g6VYD#h0#?w0lK*bsfq?{-7g)TcSrt0I*Uo z40&;s|8BF=uH^7en?eL=e^;VbX@m?nzGp`2@{N6FvbfejJ z7Zho5SuQ4LAZ0SdvPaFJ%}}W;e$nZDcYYP;=bI}ef9GFF$~as37NRUjo~yg6zkQ$# z#Ai9*`x0;a6E#4;Lx^-D2!Nq$?EWgY#|nl!jg`W_&ti3t;5Riu>`OjZY|}j7 zEkD#VMk3NB?vdOe*Is&*3+>bX>SkIbaUoZ`^ER9RCL{2aUV4A}*`${*>5g>|U!H1J{$s%{yX0)NQ4eJm6#m zZ)9%wZ3qqfq2Tz0GVaxXK)+xz%e?YK@w5tcT%qJfc8?Zhs%#+9)K{IKsEQdQSYctY zLr;MU>;fZ69m#tg)GM6nNDxX_FV0q~3^2w?qnVI}UShQSynk6s$m${W7o>H^E4+==5(b);4>8U}Su6VgY`>`tsyvu(ZdHWT9EISJK1JY9p#;=cEP)Fhd{KYOEfg|9e$ zPG-p`j!@RVGLNGKeTZQ2a3%sua7ddFOmDsNeR21We|U0nsl%mKM4j!y0F;iKz4IfT zEwRqA)FUiBcW=G?)_BV^9@SqpDOEm-4W}E{R4IUDYa=j93I84%c8~e$2Y8%tybmR6 zNpzVkh`(*+P8E9W58qLIDrZy0H33kdG~n$_SE6mdxoO+4i|&?}D&%@!PAq#bz{Vg0 z#OT`evfS}W6_$l2z@o1A4BE8bX5-2;C@mCxUYb7@h+j!4svMe660~`oc6qkiY+tdt z9xb8l?93gGTHuGu0E-r?gsr?{M)oPK9nE9=3;&_;;1 z0;*Q#%Y31Y(631%xqmms|B;%0`Lk_ecN1?6orxeoDU;G4q z=qQ;1(w(HWDpn-16gGlc&Ho|_u-0i%H@?wOcGy|S6|>vF*fBX=9}hh7etO;S`< z=-M@H@&q#I<5#a|3>s;RXqw+ZNJ+3Mn9BH{LxU>iR|Q`ceapyqH3R`Ba6&_qdK7$g z@Bm$1U~Fq#hX}^6SfZEe#1i)x(RV&h(96 z1H-$RzKN;4%}Le8VZM@3KezJn{<$asOX@@ED0zi>=)wAQ$?)b^yrD*{SK;ETyo>dY zeN?s1GD1&}cS|Zw#A9ZC?O2VXuF z4O@P;z0hOkWu=)&xP<4;xQeRxiJ*h8$pFkFa?G#Bp0Lzgp~2)ZHo>*hq*%DY3ELuT z+}!#;)h(6Fah8}rcFZg+cg>&qtGy{>yt3F8C-e6;+#8uYVk30#KGJYuVo3QlAw!^Y z*Z7SEkAzhw34j3Lb1_B`R&L-r5G7+_B_>2uJ1_jmaE7`<+dN>;!us?KCZ%mKNX;jr zjP9_2j3xwO1g)sLHt|*ha0(kGZB^T`D|yh6DX&fpahJU|Ul`M_+59r61$s8)>~*df z9w6;W^`O5KrfR8U(QLh-m=%GT2MG1u>LKdyAT21S_AJjQ^YJ?VaU-t)pc@89kuVq-7*8ADI8=sal9 zyXd^_dHV_k3TM(=FXu}j?o)pk7yi!t`e$M`LfQW*$3WTH1IRnvHQNC|C+4b`DNJ}D z0dIf4@p{$u?b|QU`ktGdcCkoxH6+&oo&>LA69priuWz3-o}+P>SINz0*N5bDVJ}5nRQBX4EKu06BmutWpP~uclDv zt6=fIN8o9xJLHez-mSk7Y8A@)L3EC)K`gFX(&+pb(<8MZG$4ZAQjl4t13Q&4@_3N57dJ$qc+7tTSJdY>1ZkLYb&oV@s=$fQge5Py)bAqEe<7>2zssZv4-7K9@2S7$5q>%SM?zfYY%+ot#) zQy8eJ{ek8#Z62hoVO?KbOa;w2xgxz5%F%tX0`YmK$*(N!;KjA#>eM_|n_I8Kt5Z4d z@1XBygL#lahVN2;5pqZlhDe%?~2&NS*=j*;V>AJqPJn# z3rz^*abl6H4o!lkg9;A0h~`={A`j5lvG71#Wn5)jo?$W^csxf)mF7RD=btIoD|23g z)H0G>_)Wp88Y)8j9ZP-rW!^#OlsCPj#?s>*H56n5WR18GUYtXTsDK?h$Y%A24xwy! zA$x$me12D@L*oAXu?9KsK9d0xwBxz3Njy07F4e?e$R-CSQn|kSi+@0EI~CAT5R#VaL%k&C z58Tt>UlFMXvpgqdt>w40b-E-mUj+pTN&V!czL0s910}PT=egVIOOfFUiT3}y8xwc{ z1CRh1n1QKv**+UWr|aV;qsH+!{?ZA&zsI*x{cw5?aDZaWELIi7@~K1U7qd%BiEPYE zhxc7(v1Ku}c05>ESUMa5AZ_bAb-dR=`@Svd>>>Iu`UJPhuXpNHf&umnm-Ec1eRSJm zHYwIVoZwH-AXP_<+4+oRQjTdBc^nP(7HrQt;yv_eCfscp0=mXFm;M|;cRDxSEY?X` zip5#|P(>*3srSJgYX>-SOfb{3|GMlv7)7@J@2Lv`aKJ-LqfKE?aWP!vV@Q&<-rams za(GKhZi`2Hxl&d@if|;X^Nm%I0wGx%*XiVUdw$izJ)aOkETr4rP3V47m#8Z-GYP-} zQOrslSl)-mdK=tl(}^QEOzST21RZ)JUwH=%jPlt&RMUD0Yu)G(h!htc(zN4n;nXD? z6|Lo7ZQ(A+lEuuzRP{oek0R^CJ~yxB3=0dkS~U01E4!He`UthzzpR(Ccr~IMCWV{}+ny4AvJgqE!v{rUiip3>#+@7#c)5 z6TDi2QrQ*a_fxcKXLtP^^_Ey&?=TFO=H}6weYIUqNe=b}Ua4*{tf*^`yBh!Za3%ad z5Es!!!4tNveQ~lMMT#seR4AF9?=$03i|j+_&pPV7FtGhud*H0qqE7+?MhhixS=4>A z78W8iASEPV-}Cs$$5(}A#-rnO*QqxR9}2irw7+k|bzxDILNA3?Cuzjd4soGdC&KLmID4Apimj~ExqHIWnfLi^T}~a0~Kls9#C@d14)@lX?KdW24Y*YXkK9A#|sIo zztv7XgbnRzX1vUb4xGau%{4;+E$OC=n8V_hzbf9cV94{6|7%W|1e<0N$>zBI+r2cH z!ME+M?70ZR8FthyA^&Hj|J(q@2bxWUdw({WMb-hl8DU=IbSf@HH-;T;WCWek^ilSw zRiDHv0|Mo%=-LGA-G9Z8_a|enH^W;lO!Z9&GMKtVph^Mh3bdF{#i^7Hq*Tpz6j7o* zL8QEkIw9c`xtR7m83Hf?aw*yVx-;1xH!I6uU$4E27BTUh2b|y1p4IAUzn*g&+Z6@K zbmcr4bxv$O*HdB&xYHaLC`kq|dB;4Tm)(*F@B}!hjX<|6q;K zxAVur!v2F;F4$?;f#9mJ$KMyiFF50Esa}|v(bFR;!fJrY-Ln|og!bMm3!a;SY@A)= z;dN>UYyYuVYeCq(Knk^@FL0LfLw8m8<4EcYAp3wfNiXC2xSQM6B|6wkWaa*Z%Z zUJoa_$9>4R!XP7OgG-HJ(ZvaIF%YfvHx}l;h9yK0yD9QoU=I9HyuE&?NHaTg6v9-e zKxpz{C%uHN+awY_JT#6y`|~O1G$^&`DHMvF7UklJsCxVMgM7(=WG%COXdSzcm#wnQ zOKf&LY;C@+;tI%fwzc(i2b;zn7}3_<5&Opc{L4(BH3PJiOM3OSg`twczSSL1XOHT9 z&IiyeRxcWbabI(>h4w$&+p#ZLb*gQH;w2u0{z;AeHP$1`-*^80h{s+%>7kw3{oepo zUE$zZrUP5pXs1pT`A1I*;ld(g*R#h@N6Nt5L&K?iNoCxD0+1O+DO!~qmvh9+^_Oc* zf0}^XW)^%bsB%Mji6C~2DLa^JowY_yLDNv8+}McVR6`*astIh!vd>ED;bxMuna3iA zo+Au5j)CNznNKo9q}v9@fO!ey0}=<{`&Z3phrO3cKeJzGg~(UYi`^UkcJqn50*PYC zcj%$5!0SQ4>DWQtIaF;GY`u~}=Y-R%>@6K&fr!-H3t}70hwhCUPZJy29gp0}rbX1e zjH7{IQFOYMFo<6bZR@nMFb%$ABAo=)I7?;=Jh^G6zE!eY&%ueK`&P90==otY+~=+` zRO@DZZ!dl>zq@wxn6DpKF{<@$ZAY^UJ0cp0V_#c2JU3>CQLmYt{gbZqj-^EJj)NNN2;4xi|Zxf*NYd-5r| zY&Rx(DVAhggYz)GMi+YM!&#oKt?k-=%?SLaT}Lp>EiTKsE#vUeDNg*x1|==bH%6)J zD{Fglqm^+g$437z614{TeO?&Nb`#oeM0pey`GHGUP}T7Oc}vsX)=URj%?xN}Mi5EM zNE(9wwPLngUZcj~tPN5tZOCZgJg^*2k;EQ^Cm+*|*4n{Z0Zm!qdP(v^k0gyKB2$ZF znnu=bd}w=QF2(KAnf@iS44grdwJH*KkcWWcFry)id!;e^-Te=q1F8B386XbRPGG_2 zueq0OiAMoJkH~#fkZ{%Kmmaf~4^0~SJGL>-5)P$n$&anUR1cNesh8k&;OlY`%3o*& zU02tR?t94n$Bd58;c;DP!$@9m*>!!bMQDcmo{u`+1(0l29!Jr^9A_vn)bc=QgC3$eTA**6m!K;l$geHN$qKGi6c!0gmRUV#mXPtg# z=*+P7avgD1AdsG^SaBOW><5uGr}6!PPk9saNv13@YZQIfBvvv;qGE*7i|hndt&=JZ z*%O#_I4@)n*P;1Vd^LrT*~qIbyyanj=!ixKev_)T9@BZz9m;PiGk)3g@H4n$d~6OT zUz2&g_PCU071@`Cr9p#mlas38yPKFAflMqqJuTCHdLL$HB0ugjiJHR``WB>yr6Fs5 zy&vA=_IEImU$+;-9^7G$uXWP7($;^JXAnJ9H)^JjXBH6>V9>-_{g%F;6o8*^w<3!-EZ%Q} zF}5aU-i{yiKRt}af;}vq%{fe<=i5EE`wgk_k26w-x~cSOv~iIHW{%8f=ZwBL6-|xg zWS)Uc5jw^mFTt@}1c1P6Ud7_3=_v^BUdAUU=WP*|c(zl7Vw~Akurw1qlSPJ9itKo_ zgxcV`leyH4KS&0vFtUS!XVYb}!Cyct;U)b1qU!2e)Lai_5gKQtbEiPO=PUiRjImM@ z4KG5mqf3W`Aqz%i516z}Z6|G{-S0kvjBia@-u1W#^YC2aw&H}EK4ldJ0I zN$>AyUP<&CvKp`25h>l3Xad6myz5#jNq=44<%D>z_HskcK*^cSYA(|#wd~V*%G269 zV#fZr+2`h@u;$S`D1a=n0ATfZcgK7yLf~%0n8^Cdlp;nT)YfZW$jSO(s0%Mh;O;ut z-S4j5DBo5m?kjG@MZ77}8ZL~1IZII9Ag4GxwCr0qI!-XGtHtU0yYUmJSbfIV(NOw7 zjRbONV2q#-Sd7?dwuOyOoOvxSf?VE@SV?A5;BY8W6F*RZ2z8wMdsiuJA zgiiMNhf7wSV|jNQtk0s~Ek8b7@tJkuqD@yAkBmSc+yXf>^9DAr!=cyV{cR2U(MMLp ztuBlE$+IP{Eg>04Vp*N9g>&85v$Y5TEpqq=M;&9L)EgveW5=pe zrfR|S%m}(hg?_EpxJ{GEaNB%Zk*lBrOh#MwML76(u0U#|IcCvNuyal;xh`7}$!iP0 z>{kIG)FP>M%|jmtPVX$%r|;Ke=y{0brDyEW_IeIEo>M~@fYx|r^jUo-gb{8jG-dM5 zj&M|sKUbEyv^M#~!foS8vTu#AZ(LFcj}iccy+SiXr1hDN4wpHqbZ5ZjP*e5vI#Wxp z8o7I+=*PaQ(6N1YB?(YhB3Ke@1&-V4lRW(l%1{b?{(WRSo{Bw&Hpma&!|Rsonv+Kf!oZN{DMKzEA-GBAJXvWb1`g&+%H|Pmk(+&v@kd%^*C(+1iDl%%OnT2EhQyr~Y`dco=j6RyeaN3a3T=6>?8+ePf!|Ap}$Vh zbSgm*gh?%uN#)nx3@ErOLH@N2wc);<_Sq3_9$alg|0Nt-p9aB4_@1hBY~C9?g49$U z|L&}X#S~o1Xl>@_2>HR!;2umOt3jV%CY)c#EKN^kmhBAFZ_hz{K~KkG=08%B4fz;U z5#T_nyMw7ZX;qn!B6mY+5`M8kvA86-dh>gVcG2{VvqVQTF00y?NFs@=c_%3@@~(Owc+O) z-bWJIFtr*hUi)c|%Lrpj!`o*bzU)siX2eDo(@e%o*-%3Xgg@)n6t)ZWdS>piLi02UU2({ku9$mb?Nr z`04$+0W$HYXn);8YtD*u5xJk#TuvAXI`Xy4fw6ZXwq%cWirthQOr@2_iG`Y|EGO61{r|- zmSQ2-@~R#L@7}o~tV$C&PYcD5oBMo4omljvBzkmX!i861gbjmC8%%;=O;cfj%eu2j z0!UeP%p=x~ZWKq(9z6dvJR;Fp;(JZadr{oeJzOohjfjnj35;&;cHD$-^}4z#zEOvP zc7ta)zvZ0M_T6~GB#@RJfA-ublGnDlydt*@9u%fz6M=|WE}sHH-^S^;y9&uFQ%gE0 zz5Sr_qalVF9j~|N&vRO_h|Wvrf*Lo@CZ2c!Q_Hlvc;?}tXnOy}QmltEX+|KKse=>% z=#Wq_JEfeZJJfE-pL{eV9y2!n`I#@BN=KLwSw3PGTL3ZppZvEYRsCGQTA*oXn5N#A zk=NR16yX;~O)Q&OULKw-)(}R``w>Dt*g3|_hp56n=h?k2y`D3-Jo9%R#D&C~nN8PD zTZ=WRVueTV-DA5K#kRF_owK^XBzDY)HzBQ|1=jJ9-NWD;~D*tw6AL34JI?eW1<7lGtmR+0Wgu1pkiRD4hK4mqyJvJ;A}s%?bUc8r_o3?=<|pJEx0UEc>-R zzwzU_`0t}$-q3e2EcztA^o~HhJHF1zNsIg$w+{F6rX?X~{o1-;+W*2ofyT0n7SF6Q zkpJF6w|tLszT0xyV3RKd@rQG=@3;O@5ScZf@1=v)hErk3_!jsSM0xz!E4b4*#UZ@!14$W`y0(`EgSh=oILx2k%TP7*wDM*!$-d9*O4p&MEU?vqpNGJ(Ns1mLQE50ZA z64kiO^?f)c##yiDT~VFe06Eb*-w{w&pH7AWn5C5mrWv(*C0hVz`l3MM8`pb^fX>B7 zFN=Y0v;pqrj7m53FU@L#@zCvgC9%mYs!St>gevjWs@__w<_;55gM?tNLq$bA+XE9` z3tzNu3}Xg>JoM9>K{4?|%+w&wR(jO*u$lG;fybMQ$Nu7?+R4*)--%|Dkgy$-XeN)mM^gDCGN7F0$|Kf$Q{ApuxD0sR0 z7clDLHjXxQJEKdWZ|r$zyH^?_+(Ch3+B2>So(Gn9W}=dIrRjiJamZ!LFL4D!IXu~6 zRZEoXpT?LPb_TYZ%SYAF7U&hiB$0x!*yR`~xTDGU^J*Hp#S>67%1=Pi??Ke+;Ji3n z2HNDa#E30Zock2}r>3q%lHaM}f0~mfA>tSBB>Q`1wTbBd%Bf4teM25k zAwP+twt)pFjD zAgZJTXkWGC$4si2_wmFI&2dZaD=jaxv>0lZ7IXk!RukwF)BhHZt@%`&D&J|8VSK4UmOa#HPvb`6f)US)uTYW$QCk^VgyVvG<13O9h0AZZRJK`;%%x?! z!J{hi-F5w>6Vrn!wH9s=8l%Cil0#wMF7|ec%X%amE;9~zq?tQMg(r#`!w}d4_K?QY zQDkcHT#sCSM0@SHBG_`abKP9Oxw1OpGZPCb>Cz>>H`YNPznzUu9*~IZ%UY&1+u(XD ze=*lfFGRDXj_XPVHfL4a*l*-epZ`DrHlH$JoHpea*7yFfoM76m#O*&$x z!p&TwZ-KJML`mIQOwk5>h70Dhl0XeT774Q2cuWMbUK`hN5LE2d|JwV?3B6Nq*@P?e z+;E)*xor5I29urcsrsk2wu(gauOo@vc3^VaEpT5$97JKVJhut)n6=tf{myaU`P~|) zrKbb%*Rwlo^J!W74J|;%C>yU$37Ffj2J7?W=Hfq zH;jz}fWgT=)Q2LE_TH2T&z4Ai#+FEbT4x zV8VT^M~Qc>cN*KS)^hhUyQEg=t-EI!*v`c^2k z7)90qiw!SpLL%NUm>duQ1J9_64qL$yP7Tj``8j(=6Og{9eDBjP8NRyDAuvTVHiAix z7DuHv<{>F*Nb_sf^55L@%?pK*)L%JjpYaNIV;6l~!@S#-6;+^3So>r6#F(t-ggnD5 z!kOh9?cjHj?gJpUbl)gno*8ID8lR^$e_Dkp^(Ll1*>9TPyUFzC7O7+Sgl|;CI<&UN z?*;=(>`FYdvV!>mS;nS~jSb=@GbutMI9v8-bYD+(ghi_;v{KAwKAplro+F1KQrWUWI$ew_?k@%q)2QW7&Om|7v0 zp28)%7?;y3miUzhJYA5p#3B5S1a*3#4-8>2JRTLr%qS=H3vp9FrR2A zK|bRXoIJ-WGZG=1X9jXuLhNtq?uxEFOat;);j!J({EVs+yhsCD5j{r89601StHrB9 z+=0r!F($1CV_a(TYka18WXr&(ov3X8oD_1T`e*1v!{wx6D4GmxagCnay!oR4^Aj-Z zut4<5Dv4QpvOY~sDDSpo$}P<3O?%5F)jFc8O-9LgFH$hHq;X1jc*&hlD#V7&!ro4+ zVb+ZHoYR@iK-VBJ^n|du#*Xg7zNLwXztlIyd)sxA*GfUThvD?RWl?V)pScxMcea#a z`{vr@T*~8aIqd-!fFt;Lnn=DJbuG3`y#3FkVW=r#Ks2BJi2?@?DC*=P!%4`!w{9gfGn$&bj3>M!$SYW`8_6?=Q~7I^(nJdX*!LrwBd$%H|WeylgNk`uwP@G1G>MTe_6Z1EJ7-#PbsAp zZ-a8f4s@ap3{W!-pVnMMc2!0~2Cj z-b9vgr)5AMIGiDn@Nm+W9ZKd`?|4SMZ&^Tyaoh9Y!AT0ykn%X6w5nk;8n${YcFR#t z>oZS4Pv9~B>`$eAGmfFovCt0~xY?2<0932#8l{suUjnhia=y|$s>(3=Y@^S4!OG!d z!<|guT``gM@JC?6DaU_UVf!N$g@eCIJ%=X<#PuY`A{3EnBlBXJuo~0ON9w}1+Rqn6e%LQ`?oVqF4C22XERZKCrOK@x42gJGfq|r}D|OC;{4`HIscm ze3*kt%cd7SH!24sVNqcKIZUZmxsk%FII$HS4ZUmWU-SVe4H{!qSSLP7}56F@NKdjA&KLARA{GRq~ZK=~KsHGUvCcW2jC zJ5z62(+UJIr@g#nr=yx#r;gY7+^k@3lGpVB6_FSpmfdocgtc*(vb15FNaU(em50?Y z_%U*77=Qj`0ROgkxYxWeI}0$J%$O3PkzsAi+-4KsZLlfdXkp~{;;ho9=!z|Lu}Muo8WznYwxh(?`QRWbn(rc z{YU3+d;8};Nw=wKcQp@8E0#SQ^@e0BYFq_z(V|6ecrQ`8y-ogq1ik56)sS%_+d?^D zpsTpr<%GUY$CX9}@g3XIm=4$H1g?#yrWsYMw_i5=h6A2%jkuRSZ;kApPksY`cZzM9 z-f`W!vdM@2`wI@Eu@RALPGo3k()#0+2h0{a0z?j;16y9OlyQ{87)@OCpw;R1yzX024+sy%*zeQYjmO*z|L3Ym7-d8hx*8H7`zB$+4j!4n1Cw|Aoi!#07 zj(D5TI~|B*@J9PD!gxkttl=_6@JH)fmJ^!;&p5+Hevhv^V=7!J7bh^st3IatjB>=f zXBtIPJNmt5&M=xSNNfhKVk4Y}%3eB>$otJhw5GI%GFwR7`n{VA*<%al)&*2H$2J+C zYgQ!TH`;}>XzpF{X5A4w3oT%9MLDrs-$9`iMaBl>J2x% zYBX~DoGD5@uxigdh-@z(zpJHJS7evfO`bH{bY|N&iFS+bi;Yfr{SCe!}DCNejkR+XY>()tv^Apk?zoQFCnZS?^6skatfpV zn-$-8QSx)@8dAT%qq1H}+@nQEGNkaNeEDy)Vv9XVoI;HmjdxM#qkE3)&H|j|aF@T1 zl(e_pvO%wzo+Fro2(PYsc@Q1p2AHDyxW;=&RT*lm$_^}b{|g){wA2*CQs=wYon5l% zBIpYfnAUK!)lh9az2ZmHfL|9;>Ya4mV4+@lV3XNOr+@Wv7c0R?Z{b`MUW$Fx7-#2? za^~|rSP6-ivzS0QE6(uYm3^l@wc|R|4Uwvtom#_wlNK`|HFsX|mDG$9*nzwQcF@-E zM!7B@g)O!hx@Vk_orp_J299oALu}FxN8cyk93hX1T=C6#jCy~woKJYVW*bWx;In^5 zNGC2S%2a~g_0IQd;!>8kskbZ@cd|6%(>W5r^ZpP%Oqh3HTW^OOVE$qL2z^{rzga$* zBt~sNDsOFfhWDI(G^^$8Oa>N+UA57C|D~W6j?lf5m-s-SVuPkX)*8k^Uhi@^dPGgV zgo3;ft>b7NK%f{BERl7b{hapKusL48QzRq20v@PnXj>CY3RBIP^zrGKd9-Ep9N&_- zy^&X=Oh%5auGF?mP37{UeZ)yop@a5gH-U%SL|CO5)dLsm3U=TBSN?rhgU|#Mz-e`c<7%JnQmvBn_SVhz zXrdJzX`|r;Qm^8`Q@DULMkbzygtYGF%Q$(D^US=%s3|4EAKJrK6=jFiC+khKGuuk5 zrzy3bOHF9a@|@9{E^)vuJ7&AA*mERcgTb**!L0{x{hKCddc-tUkvp@EUnAGI8zQ*^ zr|ocn)J1y7vFZIlp7(MG{*Y-HMrRD4m&kN&+ftQd$?Q%uWa>${i6*hwTGm{K6vF?9 z(sS#qkwcmoa+uU0D-vpI`!qaqHhkmQQ!ytz#oHKV=f=116NHQ?-sg*U&gS0pFJu01 zYY@os>_WSB*a^GEA6g$Mhwu`Z{V;5pF%VV67TwgviuMIa!U3XmJ!L&oJmu^3pEpT{ z71xGs{oTJ4Xo(ZpzHTbT);93)pnGJ-a7wf1i$uLaWzFoq9mt#d(KVAFm~R9yoiNbY z+}&^uPQ_*X&dI{KI40j1MHaENcbo3@}2&3P$Q7!nntA`UW~M+Ks)b`K6V`b41| z&3kL~?Mm0#2y7x3pEiP~-`hX-M7$jIX}6gry{HoRY%h!Q_^DK%jjt}vQ$qI3k&GHO zIhDAh4jG@XhS#Wv3ah(oz8WSxT9vPIl0G{}EQvYY@bsUmJ|s0EW(K|&tq}1cy)pEg zm)~+!9%Au&MuoVePyFapubFr;i}?S~EGS?VX4a*QF0~e9l+CUjjw!p16V!+-Xj+{< z*zxI^bMi|l&?<&tcG!I|dO}|@-P2^X_%tovi$aYTeEX?NMMqfYVyOdSHz( z$NbbvUq74AyW}w=4x^|TbK)Q^Mn}7+Tm-?5NUk~WlNL`P54c^&Z<_;V=b6S_y)^|C zmR5S*_^qd}U$mD7-bX!vQ=h57MZe@yu_+$Ta3?fuhEow1QWm*ci4pcpvd$M^f1l|- z?@hF@kD-TX;dK0Pz1j0eL=#=e-;HQz zkAa}#-qv>SFv%5)`_xF=@3ReR8>Qm=#P`mrWdY{WFl^}I*)^%2v)k(FargLUWANr< z7Vq20<1=ifhqZrlH?jW;g8(wZQFQKe>R^-55nV>_kgAAy^QpW9ZY+5>?H#0x{VKmQ zaRAFGRxPr^s4@xN*-vI{wr$|Jg_K(nIlfx$6M|=iY9t$~Z*VGm*Mf<}%3cA-b<>Je znhq9nJAqWTjenJo$QVoAq6BaHR?(l*^*GsgR(fB7JBW|HmgRk1nEpI2iRn1PGYhoK z>W^w607Bq8v;uO^J+c{^f^A#%RaK~Atac+AcVV8quxE==-mmk-G<-L%anoF;KbW;A zm@w7uyv^tL&xyR-dT6|}&9a?4o&SUJ``yqTD0p%7fd0d0p;)8s8xGUud7yN*=xt5_ zJ`r0o<<-Wf3VUDUJ^fwJppwVoOjX*T%==XIFJv*lSNdP2FGJq4SY5Y%usmPM(j+jEsdndlq8cYD4ch5UGNe{`dF5*1@#SNcCd?wf-@Ak^De&!$Wsa_o7l2^yeDHac3> z92V&Ntf}AgQfGbZpkZ@>&5)e0v{Mn{A2oqLLO3po`$H@kAIh&4teJf1eO_&G8?~+vS42^)56NbSAw^h z-@9L^612=xSK=0k#bc!u8~Vp;6j(z(+6ghuaW7W$wioMkq?P%h-j&(R=QV^dV4~>A zbNj|y{l=7dy8U6q9!7wMKm~QDjR4yyP5eb7JW|F)=?925kAMs{7W3DVnk528mjMUe_(U&gw4$ zO=YQ%QmU$$c6N3y?(P>a3q?YV5(~a_L2Fm=lAacNDq7xj98`}~0p&;VwwOOEWp$aV)wmk$Z9X4ldU4?| z07g{AK8g2X#UlXm@on_QIOyfRgqphAnUiJGld?B?wWbhfc7^*O#%~+F^Zz{uAgd+) zyNI*3-)3oq52ZJ1diO*vvxYIsI9Me_OCm^t5yQA_12U@-899^k zJl@!aps$VG&L7h6VLHZ{2|`CY7nVcTS271f$b4grWn?K0p2BvryrTgRqWN!am(|v9HQkPb5@5Rt8_(zh z>)Z2I^MrrnR(5vjD1L5>gA-oywUS4!(XVJ`eAc)wmu@r{Sf5e4RE0?$F}S)tzFHHn znE-unh24fV|GCqXmHhFV3|qx$y=*EaPLc38g;t1rl8(=IBR5-ll&kwY=o;b+{MTQk z2~O1v*)lvBaohaS^L?q~spYVyYetr^|41QL{eOM5o!g;*_z(ZwN^3+qu@2;v*f`7P znA#*`m#57F7twqAUY+g+ZXp|`_UUwS>-@p@42UThwqe@K1C?WbiLDMknQ^|P)d-#_ z!VhM#Dv|grUU0{8AohZiM@}f5%`ETA|-*(hhP%Tg}m;{@(d;I$6zd>;SuQaRH zd5c3j$~9%q*pfuj>Cv0MSWBkQy^PjxkB}@@CYl<3llQahpJjfI53eY3C{5y}HsC)Xw)2^TtG3ItgQ*^Fgp9(@%KaZ z`;X}IhO%1wCq1{#f0237_V!LJ=UJOL?-50fZu?j%D@XQH@>>5M$1b@b9uXF+QoX>h zcIp3R1OgYgAg)ybKU!yegotmQ+AyvQ<~wUZNF*9u!!jbzpB@c_s6W zqnkCL9}7&8di>YL=h=G3_dMI`Y2#!*j}R#$ECPT&%=S&k!Df@U3Zo+*vMuxLs7W=s z*|9?8jI=a##(;TJoNEPq<8Jp4yDC4vFbAEP{`v96knqISyP7Y{hNqx)*}c| zzI>7q`i_xUHJ=JLWFP0+D5#70R9M2J^p>@dd`*iu;N{XN(<^Sp#pojbEf$Ftpf6 zXcMS0r|bA^#y8Of>$JR)L<3=pqB0h}6mPuIjd^2GnR~@{aU%JVCOKIDCdtE-bo0U{ zU@efqOsK0)T~%ePH(v0fu@f@3n%82?ILZ1U~=!thlKWMcW4jxV+^Ui9QZJHh$qJ8I%t({n;r`y z&@t||BT}i45-GrHm{%)Ke~pKz40w+}qf1En2GdIT~F99#!|8?c_Ox9#)syaVH4>#bwaQ9DLDV{->ymgZixm0DhjK60J6kg@wbaq6JP z*5gcO8`;g(GZo(!4o|mw&T1(y(AzaJq1$=brMZVzUNCNDnfHo%%YnC3AhesKm&leN-le4A!5J;69FTpX&xhT@X_W&)Cx6w7C3x+{!9UAi1 zTRHDYbeny<%8>RQ&o@6!>L1zTx1>Dw2RBRX|JaCK-~aEz2u+{L;{uI1DNH1F#-QZ$ zH-`OQj`g-|%Gwd0=Z+eBXFP&sZQ)7LBCl{w)(J9l!eVo~R29 zG1yyRGPr1A@MroSIgZOuNd=FbB1e8kQMei=^q@slGk$}K&v~}}OzS;Z7-ojdZdObY zgE{{5{qUD3f}CK|@PFdfHDd~o%?#if>?6qz#E^o108MYk&kB8sbBnF>=8hSkTHQw{ z=Km^NYGUdy2`AnGlvv_S>)C^&1G;F_%G5}*8#5%|r>E}ygMXN z0`mgKXLNHNpw2F%hGMj6NOZ@60~T02>?Z8JMoPYGtK((db^cq7^DuA~pNbeuBCx~B zv0iPIv$ghvb^S*FtUR+G^R<~Io0oA=&PLY2cGH9qn8MRlnhV&*P^d?}0 zMSZ9g@fe}D>LdiG`0eg0?h2dXQI*~jbwSU%gDUV$NoG>2{W@=VkoPWVT7*yE z{c+pu^Jgc`T#6)^S>X5nAYU1$@S+B^ro*?l`1b&pmn=GJ|L{1!tS!vB#$O5Z$|*O_ za7;kf&_8bU__+7&KL5_{{&C))0-{a~;Ad#*@iKVh-w7T=&5=SdK*DXoQ#R(iN!-7d zn&caiAjbv;=9!`KBC!V?9Z`CoifH&Apcte-QT+PT*3rL{Wv-P%^~Ju6=2d(yMUMZ& z$oH;3r(gAPm>ig;YYMZAXr!B&fl^_dU}~Ux`=&K7g6BP89{D)oKk2g1@m){!qn;Ee zMg@l&M08&6{!^i7X~(;bj_rS)54LKjPlY9`QNKx!4)4SQdiY{LI5oMrSYI!}^q-y! z1f_(8rsVb#m!Oy)Vh_hD2OMWZ zhRzFbiA6GsWTKS!%E^>8qLxplokoHIFK8S~3n|FYY=qJ4q&YO2%rNF@U<~P`DcM+f zsTx3;E9Sb5*Ws~OIA<-R@^y?;4XC~8y&_#%p*9$(%c{0I=n z4q5KihXKIV%HHB(q{RGaq2~SVYA}H*|Kn*Fp#U&&jZvY+ys^>O8#0sh6KAlT_utK*Q_X!It2r>8~Yx)gz0dbK_K zR*tnv=sII0ck{#12DVcFvaAoJQvGrD`(}#U6DRT=m>`U%!w3mJvLq%OEE$8#Tj*|cGLYNY3{gl0%+I1^W4P7V>y3oW)2i&e4+2W=#_~J zqt*9EDtS6TuH4s#nlKPm=9SbW>G4Y1D00o*C(}ng%zy8AHOYc3Gw~mq#}(})=<*6% z9wvgLH-^F5)ZlWKu~DY#!$3atf&Wo@l-=G#@8+Ax%lc)^$V-9*2xyAzrMP zlC~Y*NG=v#asG5#eQxC`b#w1^3eO+pS%)9wU~;r4Pku49-n^qPQ#&~v2ozu^avcr7 zQbEI!W^L2xZ;Ehg;@yFBmyNHq+Y^6$GSTOtU2sK7jWK8st6GNZl99A^>^4H5(W0a# zHT+cGYy8^qP8Z)1tA5rU(cDkxVZu2)3_{0 z&9;YALyYI@QS+9$b*V^>b`NvgEbe+YFSNmRH67#+^CVmB)p-ptV(zLdKmO)Q-syHu zMBUvrufUu_Qw#W5|LskWa=A%-TdWze0;w5|CD=2Gwfq2@zWp=lkv+O{fHSx?gTf|6 ziQ$)MMR62dC&$K@bnd9rur6ebIZPpAN&-V+Mi`vnZV?yiVh1)|{~P}tr_EF_`1UFJ zq*EJ239r%~2#;WDlRnTpJ|%87PxPw*&p11y@BS`k^6p$hrYXfDfdW5-;LOx3Nq1Xg zS_H8tR6P+?tw*Dy%_=A8pa>{UaX?1M;Z8}vsJ}Nh?yk7LYQTh&Ei7NSo4G+qW#!_L z2mzA%OkQ9KradtZ1dM2Miu9@Lql4n|58s^52^z&D5Y&@wwW9Bxjozo1y^X5{qAh^{ zzQFs>9jFxmQb(|K1l}1SV4a+rl4MOb1v=@6O((61s*(abKx-Km=&t8!F$11^=m9xMv;%Gz;UGOJ7sUAi*?(8eY2)AcN$ZG&FgKUs2No;$qfBB z7i!T4>K#aUfRtE<5geSB7nxsJ^m8ltx<|2pCq10{dc$g=yY3Hqdk;rXmVNv-@2|Kf zY?VxTXh3kRFI@sD4+$6(&WT!!B#HVAf5)jBm zMT+2g?0jDD?*FW|r@8Ktz7*w3&f3ZD5N`Vh(#9|G_1%;d=ag8C@1coi|AuU$sf>K^ zYU2FHifMt5k>sry4q0Tr=?;SOYlS>kFE52+h#iXEi8tHPi65E8VAdtvb6blyW=u}& zh0k;8zP-L}p`CoMklva>A`>@O@OuA?aq(=a~c} zKj-YW(Li1Gz6m{8yEEw3223Cvr5P0tr%K3%Qf??g*dcZp$aygy*sZyz`1dZSsPT^? zOCimHiFUST7Olq8pFfQXMXJxOqErG3)NgvZm6V3h8Z7NQTCs0s@cf>GvG>(@G7+n* zu%nmXMx5dMpOFy~5*kCupcH)2fhgPM=F|w*Mx+2L+33^t2)6U3hqj@gJK2_i1n3ZQ zGrL%AsS5f?skmHrkKlP*vqAFSF@9M+C%54CNqk#oj{Ud3LGSfvruyT@zj}JY55Dq) z>pws)H~{7Gm25PLv5^tX6gRLnB;t#$ZEkfnH$MZ6si`T6h))Xe|BSTpm^4exhLTw3 z4GE;ShipS~I@qh{Vy8s)ITLfsMC0(2RQkpX)nPs{vz7MzmRGgs#!Ji^_1xov2Uh!#-U5|T2&#HO;5=wMB=%vi&)6i)9 z7ovEE!&{DGK7);ET}L(HvIG&Y$V;X^dSa4X7uzr;uN0@8`1pP&x*8>Iqj~BfW_H_7 zLSn8Xv@VwwZU@uz&W{ckoTIVwT_0C`zRn@k9>EV9B@hvrfNUe7EV{p;r*DgIZ?96W z@Y#uY2`ae0LnxHsBzQwktx+D9+iZz+SA`9nT0%#MUEYmn+4Fnd0Jv=)n{S*Pb!SQ4 zQg3qG;|^}pNDXsD8}z_;(e0ol7ntq_J$V-Lzn>pNpu^R!gce;8+_ar*fXXvq?e+ZM zJ?9xqg36g;QDo_`BYI%8YHbP0?#Dy5n%wL_@j=TT8|Z$I8)RJX58*!ngVj3Z@d}Q4 zO^(K=D--Sy$KbfRPb?sp&TOfYfK914MM^?DSp&Ukce>~0L1R{u zNZMoWYe!~eX$R><(aOe?V1}|UHw2~)Jv%74uY^@VNsZ=mWz|!DViksoQ=1w!tDSyutr6qs*RwkgXqfM%m_%| zQTsZ@PIe>Z(S%P-bVoA#uSo@i2ESK$1m=ydq|vLgpTcT(i~e2T3gCD*IbRN>O)y zyWz&UzoiR1zQx+B;h77tqTxU?CZb@^xLDNAR#%uUq(4M;x~P9(nBoPTDHpn|9c0@V zvNBZWcg55SoVmxphDYcsoP_{ymDuO$8sd3!ee`(Sccda(<$MfV%F+^Ea1Pe*fL6#h zP&mx3U$64e91cJRsvOA1c&#}aJ$}F5o6G?mrvZPXX|7QWg$jXkaGni>^gF25X%RG4$JTp zaVJzZqDucCuUXagEF$<^+g=SAoh|AVMj#>WQ?CP|&!Hoy=%eU&G-~?rNHsN+KywpI zv~o0w5Z{uw=yilSWw#~9X0w)S#Z-3MW|M@&Xmc8@AQuT4p{DxC1b35-kUV25sqRRu z3ds;=VhH%d960v11_ES|U*JoxcGg;LF?aJJ``9gL+HD^w>g-eYQSma#C&{80=FPnv zEZ0EO`qAb_#9+wSAM`?QDuxI%{_X+iS*-bM@uZVS_K6#VSBZ(az45t9#9VJ^ZG)_c z=l!HxZl;hem&V=o`1gISbk=s2ly_i{l)5H@frggPuB5V_&sopoVKxTdW90*xp`QSZ zsLyulDn0YiI%b`|jHV_&u>0Csuhvc%6tDfa#vM2LC^#LnWtgvS8!YNELTgYj>_4aE zdbHGSzT&Wbmwar5hsOt}@8fzwa|rQa%Zc&h6uRuNDGij(1i4s1c0&daRnO(@D>xPX z{_^$z9dmt+I7E0@apUlrELX8#A~a{?q}1{UDrf#Ygb1w;(zocFPf5< z-vvBQ$y1fUFJE~1BJc;~^(j{S+gc9a!9&g+^kO5muTf<1b)Hnxtbg8Uxq~8yai=0Q zwWwiWm|Ene#6P(}LGt;u&@I7Kr_Rp~3soZmZ+SA*E8d6({BwdSorl;Xo0IJXw+ztH z(5RFKLvnd!z8oPGi9Em6fY$luig>*)7_=cEiDc)+Lx6xN73=<*B^~vqBg`SFFsbpu zpwH79GfAXYL~i{=8B}BhQ1XHENrj|j)`DL?0&ln8eoE5(psmp{IH^#i@avN_<8S28 z<&>XPJo$sL13z_B63TO0P*)Ul*V>sjh!+^A5Xkgf{k2XX1>e@Poouy`)#BQF5$0Sh zZ(5`yL-cEv5puY{YNuIvm<6;}P(&xEP_x&`5WT z9dw6H4F_>u;tRi4zX!Ky!9jKnebj&4^X}VO+X&8_IrEYRUaO7HT zZZ)S?zH)E1TpWe`H*R@OH=H4&u3DLj5)Mu`FgGDHvzi4sHAU@$P@cRF`Gf4dO8SB=d}_9$7emp7L%~%cTLCv(%2hRa< z#GORvV%8^g=)iBa5+wmK)3eXd}iE6dizGmQB7vW0Bb zRL?&ck&z_WnSvgC4m?+h1{c-3RgWBdg-#~m^oSQR>vA3Dd0Nr?A<%Yy*wxkWgbs1o z;KjSss$xG+tRjv3&L(QrcV0<A^xN-Qn#&90N0T#+{ja?k4Cy%!hjv(R#*w3w zrRNjTDKBQ-pRS#)2!uPbg%2U%A6I|sbJ2c;D9&sL$;sNcX_V9nc_kmcHLWP&z6or|zBm(YKmfLCpK z1$x(HonamH$3{b7?Sxy|7qI=YU&yk;KrH}-KT>W!KFd%ZKE5i`K8z%mAvWViixHxk z65V9JVvnms+alMXX0ccSUt~ed_i)K|8Da(>{Nlv4;=aG0@C2<2QH($7X6jipNmj~%}2ibKUZ z&S{UgPv)P|qI2a;j0qW-siNL;mV*?gz_#gf3!d6@xt+WNvC_SAa13ZvQC1f0=7S(odG*o0{>UldNr0q%ccgwTL%#s_bIb=mPzi5zw!#4fe!BO|Cgb3-lZ8AJ3Ko>cY>D7cjO9%>w)=i}8)-c{KBrjbCluc8+#;k)qRt^-Fx( z3Zi30t?(Rf0)1%E%FjK$CpUJcItb3D>L z_O=ZhFQ^HZ{3#w-(Ge?=|NX4#xRt1hfQVn_XUW>nJig#8Xr1o%FnA`|!PL@su4^wt{N>tpSG(%SiRhPl zwZX{#_6NE<^8lOL39TP*?Cnhb3Rg|Kg> zFRvT4-mN$NWlk$KQl0W|Vbrb5y6vdrIEd%7n&zVij4nKPL=Bl<*2;j|9!PJ%cr z83Ls)+7Rh}1>-qWf@^~O#NKiiiCXD?x7rS55=o=bz}WOBZGySu+SQP+%e6%LY)Hc_ zRJU!ma=Y6hP(R6*Y;daTsj^9*C51yX4)**#mCsX;u4>WBqkJ0@BN?h zx-s@G8|E^YzOS$KCA6)6#=10@xW7-+)VT$#>cI-j-bVTVO7&Pn681cKqVuHwaIX37 z;{bjsq{H1B=W)I()R#qEv3`A0FLfR@IkCMz3>W5AGiPV|yj4M${xNO+#ai&VA1#6GY7%-U_= zy6$uhja6=~>e_n<^)k&Lc}HlK>Er=e~1x!LhFYP*GcR)NsvnTEf-I zb`40t0VC7oa2jhy4u#WLsf*f#E5rM=S&(=JN!E#8eyA^fgMjOtvPWOK!PV5z`>>nmVn6?pF8gv}4g;*LVNDm5OV~ zbLL<7Wyz~q`=6INnnuOCaPp{30tl(x*pYgQ`jL8LKj-nvmrFfaBo+_Nfip zpjTzVIqfWkLWzb?`Vv@s|{eG&DAfmPWD!&pyTY% z#B7tXoM(hqmBkF}rRo|6Xd7hNWHz*B@HB)MPz)r58mtdYD73C#Ii`^w8?JD$x)062 zD~ONTvC}QhJ>GXs7icZ46tmK=E4DAEF4LstV?%Nq+=tE|$P@A21<$F?Si;R-Xc=aa zu2pBSL{!?8h)TIC?kAP33(aP#cA+UAsQeSnwTYwir>y**A68z-h8*wTlaL6*0kPXE zpJHKX&E#Nlv`HteGSA+Z&Cq6g@ApVjBl`DM*9RoKf&tA}{Ar>W+|ws6Lwgt*eyIBY zimTYEEKpE22+OjeBhyM~Dpwh9Xf(E#C33&!yRQ-cXTy8U4Ce>F->qB3pN?C@e~Q+B zhZgxui@v>#S;#HMGGp$~<**~};?77GeZ1_{>W{v-$Ej(73Zo8yf2#;A9=6$)MV219 z;aUgW7zJ58d%cSY0~ta|cZy&NqG?xdd%~T@6cZSo>JleWb{jdFT7Zz9ksH@7P>(tnPLp zBz^Ca&ujiBed)YKUgpLSJL3yDL#;K(^rq62h($X&?dXpNJmOnWWRs!l_RR<(=wJeu zgiW_6+v~~pe&~?4*N4Up&fEgkDH z2G5nwdOA(dvRQR-Hqq!+l;YeYX55UR+qU>=Yqq`D`XPNV{Y}V%vT7p|Lss%97K|wL zEJmIhrCKSYyHvj^OeTjK2l+*}J1l{!hElhwbeS+)%C+1V@VtZE9djKUHdEm^nV+~s za`1HlT{C!1EtR%xa4IV5()c91veML%{PeX>NF&8>LMHZW2o){mBBMc0E-6xjCgr*Dw}YQEbe>fdL@)h60(fi2HzBCu z%;KFW|IIN$Ufp76C6lPaKz>Aqt9h>+#7fPqUrK3`hTTFZ7YzWYY+k9x9t}=b{Y95O zX+2<#A20*CWcfc85(ftp0Qmf~@D0p3d-586_9iY6ULXbb!pNs;Kf?DMqAxd}4ndM_ zPwI&cOM^)x9p??vh-6+kybh_=)F+2?ozkuwH%teCp&s9u=1#8S1X()9=dBoomgzjr zhWAdYcOFWlNkj8C8!rkD=W%^Hj7oV5G$-8<*=$8I4Lk!`*f1x{2MDh-U0XSu%9`6} z4OJUAc%5I<-QJ5A3?GIxpPpgX)(2WZ?@L!&GdE@%hM0&q$u5$1YR4}nm$ie<^j&;ZbC6afra>U&;)lJ+Ft&w*l4W?!w>;5n%jZ(!h_kLoe|S7LjS@0+hOuDb4fpS4$jrd( z;RKBkiF+eNc&nS zN+@4?#{$x$fbB9haVD-P5S)!!bda z`D^Bge?K@}h5ehYm#pW=$-|Q`{;$?iADxh9%GD)_55}aFU=mF{`iMF{#8vK_DaCMC z?kF`K9+p&suz0(_WnH%09`;})=7>|Q;cT;VEG(v~{Os_#C!m;n^p~#aMM_+{6-j4w z>$!wrzB_-h;Bbd>VfA>X{me2B4QT}?5MlUN!uH5(``vS7*8m8k1^-vY*t)fS3NO0rCprP{~ zUqe)gihr5%9^NWDc2dTbe%rWQQ@ z5CRMw8VYnDr7TyWmK0Yi5)q*>3q+_IkSr$`nrCPTre0!w3fTOtV@5uYqTdsvBCvsl zg%04fzhLcm4o(P>qXM87<<*aD=+#f$ZRXXNlj#7m2mKkOx*Y6Xz*_TC{6Jq0fh;%y z`-tL2+;MUCcztw3Ng8nBPm10|yo_loRD3w<+vZY}pEc1+<6p1f==#E$vdLzln~KSS z!MWcB_44ni z&BYU>kSDUz)rgt?C4Az0RdK_J+u&=Yo>)g9X4^$BQJzC_S)!vr+s!|&MZ0#N5-}{Q z3KWMJ&$utyjDF&Ay$(joe7YHKI4ElA_5#fRvhYL})9X7`n$g`?!FIV?@7+9;FLF-( zxR>*#n=NwpuH8o7$0hEU?$S|Q;Tv7o^h6?H=Fc;t97l#T(nSs2vQOvVqknE|crLX+ zR&r@TQW$b4kf?)WPv=a>KKY`4&Dto!!2e9XG5MeS?^t`Vw&q;VJ;I!?F)BHvNV+qP z^=hOJ3dgujZvfP?`5Fmr)OMsc)+e0R>=X!BF-+JMr7p_X{n zg{ZV&uHwc=o*OOwFX3Bv7F)mLBG@dzijZG_ zQt>NoND?+IN>#j=9T8o56@3yI??v1FCIUkO?fgIm&J^7#~35d%xY2-luHhNakQOY zdC$V4M-;Mm5puYeXP+IFl<#N`0NJ9gtDBWlva+8D`^$tiz?@u?&+1CqG|la7I7+|P zGtm>?;C&FZpLx3S^*a!dA1X2WA~(0tf?LBsm8pnIwZ0v@Y(Zduo9$qsetcr$Y%MFy z-5vLWV~SR7`vf&Lb(z__@Z-HRAWPYnXRhDk(Y=h~XYTp;b4>o*Ex5s}f)n}DFCQfI z8l`o00`e&C;1Po9!+TUj*b;~@`b4r9=U~oKlGLwhZt~8IN@v6FLTN;S!zIVPQNO)i zX%LeXb94eMvTOLXtgNgyXuv@$wa&;xf~);Wnr)hR1iMIn)5Q{3x^kP_bK|v9>Xvy^i+O88Ew%LN>KghdoIdCbsyq zf?)ZDP2-;P|2o>*cqtfn&C`dTdpW$LJeXy|z@^1xQ2VL@m6U~>S0Rkl!MGQ{mCs~B zk<;^avY{Jcq3Vk1cH3XBT^A8ikdgifK#)OAip5B(t`9 z28t!m^mF1@<4FC8e81?n`%dFS`VOIy%n_UHM61RCcF0i#eC=&h`w*O_IaxcIXN`#HkV2P?gh*ALSR$WU@0$EAKS|o}YOTiR=LzR~Y3o;7g(h=kC zWHl}c$w!a%>0N{rI<6*6XCP}&V7)AQqulE&!B~Q#Pq^W!lsq@MB}aGT)9qqaOzJK=+OWy{aoE0&vr>xsoAIA)JG zZ}&^W{{B?kRIxJu_IuhL2xX!(Tc!h+_vA^}t?PBRBYrC_gYTR_^lRLno=bTRq|-Sr z4xz$4Dwe}+(eS9mRb0<75-H`VfZ;S41+%x{ry=tyxri>g6sFeob`NS?C%BnpJjQ<%Rf*5>lJ{Hj8jp^xA;#%UF8JK zS%BA+0|hJS=2>riC{P~s%E&(ln01{QmvUMWM1O8f(`Bq61>Tl%jOF7l6A)lzCPf+v}}F- z$;NsA`}zNn8U9KlS>Wa$1@~7HAbLQ+e+6)SbkP2blmC^&|07DhHVG!fc|ETxpi121 z`-%~^oNaB@?anSP?;@y$?9Dj!8;ibuHif zyxFo;c9pvg-}pjiBYLIiv*&WEmb>}g%m9;Ve!S`Lw|M+qBiRmwiqI>-jk@Ngm?Dgg zMT*UA_;~zBfu_Zsh$`?A9Q;4(dVc-&-&YE~UMhlm@@9~W_4bFHIW>g>Q#KK>uX%k(#bWEShyx4dMQhX=D274cggWT?wuf3Pu`^U zZ{(S_HbD3qgDvXn9N`rzzZ$|vP{FOepG^qtMF^n)e3u4t>z+IipVf=?T(ZWZI)Um+ zfqi^@{5di|T_S*4Wu>eLTt=PsTmJn3QVGB;&W@HA{0Rk;%whsqH}bAG50;>6GhNA7 zM)C-o74X$oN{hJX#pE5yzx}&doB0g$1r_|$!_=}8i*r26SEQ`J`PE%$a*3-Q`2&868R%3Vm6RMg=Vbz9sFM_ktM_ z;@%E;nY^9W)3lWbZF$h!`3I+pVXpbxNzacCEp?5s;8^4)NU~)e1lC+Uk%JxCraTl& z^zZ$#Xwx&hIBGwZs{BoUR~lZclvk)-#C9x_WPzD77lqNGA=>wd$#p)e)2BBQ?k8(p z>hFI1?M$o)>Z`t`#C@}ql3a1MB;;*j2UdoxG6f0`u(Q|;6_oLE{YJc*CEV*H*R{!h z9S}!BZ9#*Sz61C?!yS#;?pp+1K?bJGl*uj5jtSWrzZ#BRyA+U^x1xppN4s(m5u(Pi zJLsGLe-^E&sp%WIzsRJsF%#Tk%do1Nb2mU# zUsSXPXRlitRa5d%AX!U(&sY1Zp8jSJ+GQ3=Zm5+WJnK(O;X{&WLyw(Q`EMK_mfzXi z?NobKNtj>4FV*v%y9Nra5gJ-(>7WEqG!`KcNqHZu-+ z)P}Eu;*nEVe|1@udM>-8e@skFBM^G)m<=?TcPI^?@V`(8ThGD=N8b}ZpJV0F`?k#E z(hN4=$ufCcS0|wU+-zdO3I zm9JxyRr7#Rf}ncJvJ+<#R2z7tP37w3RkjbNG!R)R7DNj)5{X_dDRsO znk|NT%+gGL16jpy-a1luuGMv7LJ~Ik=`#Ld5>t{(JW1RP?-V1C<5q5q>VG!ov9TlO zzNwlIM(&eL+ZMy&)@!*&JC6VC70MIhlEGitgZn?8d9K1= zh|n7+1nmY75w$CZ*gR+2vlrd&=KD0_>nAlxFV{muX4l|$<{Xr9-@9ItzjT3lcyDY* zfsOV=Ny&98lQOTvDZ@pBWT|A!L>Ufj)Tx9nGu=DUcr`f$dD0L)jd}khpO~g-}GmM}7Mk){^{JK8Z z40H#_IP{9yDw~--g3@{`&pt1Zw!BUCJ>yFA5z_p}!%r=cm~s1=v?yk)GeAlU{AG!0 zGQt;?B&8roubAiZMkee^uCL@|vYOS}28-emq}kTqEA7|l1bG7~F?NAyDL;>0z|zub zyg(F@Bogx?nM@0jZ}NF#R0w^0OmXU^{$}pz^K+TqckD;^fK7onH+pd?rLsZ#8x}0IV|?1 z01lDFe(sLGx9C>4wJE-4OWWs82_dVwBAkux^Bm(zjhwO8fv=6)vE~M=6mRnSIrm)o z{Lw-yI92L|)X1lmrM({>G3(ekHach+#jA+^Smp{N5BHmA67YvenHvzEIn^K0frkUT zy{b@b5H)wZXciB|q-<$lI&Oo!J zRCz*X666AbFFe+cy-=?;~CR<_jY~o5DVBf69<_hUd+#wGdEGeHYF9|p_ zuqGnR<`!vjE{Dmf%WVF^i^GHca?k$B(t(D73kNosa}Is(-WAh}H!)@-`(ol#=6(RF zRzQ`;>MEH{*X&-c-McPLqXxqlbKq67)6<3@>;7WOP! z%HVZM+^AfCHsO3M@UiDR7b(5;*1@8WVoh*6E4f97Zf5_+w%pmREJbnVa8Xz*33KC_ zx~TGvSd)*9Ehxo3C2#*}#voe_LgxV`RvSo3yH#7SvM1N^gMw>Eg+OU73r_E>WNB1( zA~2{SHlaXlFJw%2{Z#k zd0hx9ztN^KZ~-o>OZp3BL6vj)jmponLPI|I5cYnMed}zuN?MPn#=yjMSi=iK`zxZf zr3u$*^v)K!+W`bvTRFm^O7yuLSJjSr=g*t|!*c{Vh#N17SaY&`q;70SVXUV-6{`4s zB<36ak$+vYefG_BJEFp~Ip>@{aC&eU{89*O>8TS;{$C1rA8HdO8=Z2!x>v2@RB%H~BT|&Om9fC7v9v`z#*1 z8t451z1GxUy#CD51c+%GvmLdU>f7V??b|FvCljY4%b~Ti3OiP}d_jgYL1tVjTR{-Ih^yMdAQM6{US!;X=dldh5JnxYz z(L&*itO5&Nb;va*%Ukl|Md|Tl?W!Eu#ZrGqe|<5YHT=+Is^zkDyc^NvWyf1z90Tv7 z6@N+N`sHEGoUVCn^GaY|j59B{+rDTdT9u1MN}^3OWMMrd7+dc=@#%7_o`2JjmV%M! ze#=LtO2*vG){O0ymdzV1Q5fZWxJH!_yAmw_6+ZZDn1xMIN5Gy&W1vJ zLd1l`b(MEo8tFE<$5|^{?cpy|54k+>!PyCmLrcpA2-RBuyu*L#W8r-ZqC#Um1XJrN zrmAN{$ZV`wQ5#HUcl7SzZ~mD#z*d)y>M68MAZdG(@KS^%2EC7!`!_vk~Ne${^J$%=U#MBh)+*l zU(xZFs~19dHMp~@Nsb5Lqn4K$h1kVlqg}w@4#^TH;@n=udZx>nQdXBjg!{Xtc)t!d zLBkOk+!nn>+5E(d&QfSmrk5l=n8R)dfSq2Gt`7R*b^lkUC*%|($z<^={zQO^|OJ?`gq?^a=cq&|-;G381VoH5jzzu@Dt+4F7TIW&UYkqP*jna1=t-TKk~Hz;)0H~TW$7KA3ID-wr%)*MvN^`vJsRxQqLZpS{A=Ht$@yY?lYmlExk1u_zhLaWFpih!g=vm7_^zHhA94Ew z)qN8XV`BD~sXnj%bzp7TU1I*QL1NHRABrI2yaRaUNDupUrQrwXvozQDg06oL7T-{c z?&5h)@WnLvDoyq;)CiVu9(jP`M$maspHDCTuQf2Bj8UgVvoi{iJv}-=T<7YxV!5Sb zDcL|Is!IV7Xy<@Y@!%27?&$g#cPvdopupSUgNR17Pg<{Z=D=Cz3VXqYU-a8M3$Gdv zUp#?(HOT4Qu0F~)e1IIhH};(WK>+_kWHdH}#cLuob3fz)4JnTD?=#agCDE`rVa{A} yfn>S@`|hbJ7j9l%L&>|4fV00w+3yc?ts}K)Bg@G_cb^0*plEA=)hlj22>&nNBrbjc literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/concepts/ui_preview_drawer.png b/docs/docs/assets/images/concepts/ui_preview_drawer.png new file mode 100644 index 0000000000000000000000000000000000000000..17964acc3e7d97987355b84912a29c84061fbf6e GIT binary patch literal 155287 zcmd431yoes`#%cu3W|hEw}OC3cY}y@DcwkSBh7#!9piv>NeCh(Idpf2fZhadZM-~-)NRpu31@gU{a?KMjYB?&aNQt*Ro2H70 zeeDr6V#?X!rGS^Ye;A3@;54~;I0fLVif1mwx*pVX)5C7*c;G~;c zDf9ckFNE%l{D0JCp!%e&udqFgmX>yb@k77|{&xXlBemifss_Yt3F$1rEVjtw&5d=4 z$MTdEQt5$iw6x;yeh?Bpg6xal&03(-+`M@F*JK|(nhp};C#-yx@VShYf(ceuI(`9k zPkWWYy1?$;`1=@Xg>-kWfE2Mgu}Zhka|4n)jq{r#%n zpE(gbzRzuR-hD78O_Ye;O_>~fQx$y86B}8fevNukc^dU=f`9o8t6TQ?bB4tzaIb6t z&KbxM{D>SwdFj9T;0B2f$y#!jz{SA%&a$999UNy?N8ZyTOK+9T!|Rh@=$Om5nKJ^B zf1jO^n``k=A~sbKU#D2QccLVx%-84pHwOVqrP;*)Vr{p_*x?%<9yTj`C0xBGn;kSf7oz)vh{iwUrJIVb$;EVmoM(|cU1gG94saWevp4a@}=~PsQ@7JY;Hzay-#k-NR;vEw|KD6WGN=?M z#MN*H)vZ6!|DZcMrplod8{Emz3s1S9Ypyn2j+I1aEx?gqP++Pj^?3l+@M~gXxtW%m zJB=E7xzx{;Q^xsHQj(zMt6VMPU9F$dj+2Fvus>JH-xTWh7)QO~dB#XblxJMpP@inC zamphovU;*9r>xAU9P(iZ)}PB-X*adkDZ48*tkItw#Q^8mTsq}jaeL|Dz$OK}=gjP_ z=2$bLS9g|;q()~eEQR2|=yahhL>Zn;Y?hPvIc~kx#Rs5CXx~zE*~c$hzuwj|$!6;) z>Pm~@g#?WmL*gMaQTz!d3KY{-4VZn{%N#i2K8WU|bSdTFkjN8tMFl@sseemej_Z2? z!n+)S#KFdk?t&bF47p^h1>>+O!xTAPO?K5;<^Ffg)D*w&jN!y2FSo`{#|{uN6>8T! z8pAQcRGL-BB7KKB&_3`tE&lxUwG<`_5AM3IKx;F8c<&DmDnV_{fZ$qemgXh5Puy=Q z@vgij4erL1J&|Sj@bb0~6CUy@n67r+K3B;vr7~>Hw9+zZF0*bgVTYRNftU041C}4M zsZXg?OFxt3DVxvy%CB!=a9-cj?8zd@<=QQBfSNAY!q=6IJL|{8Vuc54z0?v9XBgEP z2Omx}ew!@+dvx9SAC8+b@UIP)+pB(Q*)xiEH1Fdt^3Ud&n>{?ZvOcMm>+5EGcrfSLkv{$Bn7;Jqi^5H4cC2|%HZ|0jC=()>2u3ZU@|Ogv+2h7s>2#E={t^{Zck>i_#>)N@?e2)7f%TQdvs&H{=sU1Hzx_)M zTXA!$Iru5dt#ULS&5;X>b!Y1P$n1FaF~P!qWmED9zZZ0a$X9({z`}X@( zsGaWSI{1AGIhlvmncxC5pu6olzapy7qYRz%v>nf$ur@5+mDRU@k~^wqbIPc<;g%p&KlCdJo{0OPQf zS^F0xjm^y8=u<&^iHQd}F;eXH{YSMd(&->JERW6$IIknOJ#}Qm&L5ZzgAZ(nxauVN zVI}cHI-3_JX069lZ*4t&wna#N$QW_tQzvmXSXMi<;$tbGO}3s_tO85z5|9;DT^G!a z$mxsh(N`U>41K?Si5a|vZMxll@$rxH?QW{M8CNnCMF^;FD1A_$g zUh&TjPN`C_#=xL6tb?>!{CgKtkFfAmqS9&<8ZH)us4ul@kgu@A8W4lOCWcx?F7~kv zQ`Mv-iet&}zdReXP)N$im{lcDd)JcTxY@Vqr-!P&n1xTOzNHGaL(U#v=!4vy%~0`N z;^G&ldgbO&yf_mhbD$xjYYk##hFeWA~CU8j*Lh;vuC=iX@)8V=2u9s-YD8h(EnV%C!7 z%en-as_Mlc8g!>FBdsHp3=G}#pz1B92p4_;uq*^NYQc18O^d%k`hLb;)E;^a3$>rw zH7DOBCiL2>MJuPW($dzAbi|gJ&yL6(jXfArNF{n}pw>13z4<@@rsyJzWndWG`@9b# z7HlmZ1-t^x&v9x2ZCkBNP7vS(Ju#O|cdt(CWJm0R(s$21a#ySC$b-b>Moqf5#1~J@ z;hE0+Z-q$oO1C0?J$Zws()%CgzrJ~LDXE2JR%$HA?B8TdT%L+LfuDn)n1j`tQ8HlK z^2RUkHNuW_gthD3MRn-F;2U&_mPB`~tXsQl(8IBqDI79VC-Wku%Dd(|o=9Euihu;J zUQTkZ_eU05=h>=A|EKJ%Ik9N*LccWe#`0=Of(B=}q`9JBK7+eOUgBlO3*~BGD!tx2 zVdXL0SyzNUyXSoqWoG7TX4uU!aY~f_TjYkRW0xd}^hP``BdqXcBLd9X>t<<-!3h8Q zF62(Zn{!g#d!EMb^d3k*wON;unzxSqMK+H@I~D3fkV1Y3NduIwhuD0MXY_*>y$|#R z*Yh%h+Cmu)jM-tan%3iUo_9v7PU`8EPzWfA$mh zyBGrNKdH3B4E?(DAaIh@nI<)iw*gFNk;V%xf?u?}YF1j-!pfyyoAHx-oIvUiMhiqv zhc*Z-(ch@)b=`9O=m;B+w9;sK2M=B$KY|NOs}}WocefNRWa(>74LTZ_5o4^ZO%(?V z-4WO4%sD3h(65jXS59@H5>b@j4|{0vtg)9x*Uus%p9fbvG7D;R(TopFyA|J&*r9De#mLOUwfU?QSzE^na0$=Gdjp?u2%I6u||5_ z1Ea;bL<~ZIoHn8_rc6v}mRb++;6uS0oK2LGg1PqM8+BkL>2ZuWd*+MLDgTKs>cI9D z$tE)*^{|r6VR%w|Q^bMGVM*y6)B&Jglr=E}U7k^^=EH6Viv{HB~;aYRyL1+nA zbUjIQ?si<&e9B`)iIG)9ntJ9WZ(J5yLDJ2RzJM>6Ou|%Lb|oF7t6M*~h+vmrq1L$=;~I+Jg$)iV*xq-4BJWUm)jC288==VZ|>(&7C zRQ-U$K6Sq0)$zR}*ScI2x8?Us{yEy$hskbuq}$>Bb(;twl(W{^#i?bP{D=XQDibyi ztK3ovKdfaS<(R_reA?=}z(!aj1imoNj;aXKSePby2sS2x$kFTIIs=;E?Iy^x~8(+H>b>G>gR zzI-!RO_F^!5b#FZMk~Cvh5$R!R~f%Gy5ao6J&nja^*1M>-StfD4(6RH<`CFTt>e9h zi0qOiThz~Bnf=fkhl|cxY-(R`y7;>rY5M&{8;J0fo69RAk@E^9zP}I15e;=9%j7Da zkI52@+rL=4fE!k4#8uK{)M=C}!z_hf++@bCEXqfIZ|}RR+xb^T>Ki{Ek;d&ocI_I5 z%ezM?y0mX_FiNBc!dFBT|!`-xr^7HCBO2W67UUi^a@-o=o3++8kkS=g-&g z^Fbt}q5o*M6mpRlG9&rA$a22UN#6`aOtIb&HMc`+k(9r{!BHPICewP9;N@&w zJwHIr&gm|kkS-Rp?WJZK|DiW%;j@Rg70Nt;vueS6z2Wm4UZ^p(E!NEO%AJvINGi3C z2b;orM@Z0|sucaW86*MgXK;r`_DVEO6NNXhJ5j$%;DqF zzN{si*+Wv8IEcRPEh=$^EU7ZxOD(&kCG;a_s_QgaWPe#;LHouOo?2T8n445b6l`5u z0uB$V7kE!So_RG>GTA=Kow@jqn&L8QZIl>&evdCSP`dS~@GH2(c^jfDQSwMuGGG7dEjRew?3fGYW1!YtVoQ}-TZ0`5o_P13Bv}*$Q>CD zt5WqDg?TxW!!l~u_S@?bJ1==0ZjR#Hkzc>Ue*DOZw<{B#5%w6~6*rgDM^)%pY43^}*o&3XyNeq9HSk8@?DNs|C6yIoJRn!5)~=`0tJ2=7^1 zPR&iBRcTesLjA9;OEme*RwFuPpLh?-A(~8mh-%1uej;bSf4^V0`k>D5us#UUbRDw0 z8&)xn?8(0iG39eLROJ0(+-`pi28Z~2S#!86x<7juCEMsze|FMHxLQlAQRvuT*>vhK zzh~N6c+|}|?{Cpm{gTiMFxWP0P8Bw-Q?0|5c=MdblBK(D_C1r96=i|o8<0^a6*=;B zE#){X(}^nu>Z4PWON~)|vh!@?dyJh0>R9H@XA-e^%#sG%n>Sx=r98}zt1Qxe{3KVW z<}Qxg!heHCXuCutjoTi8;S8xUhcn`kIsRnR=WV=TWtlHbmTl2dOG=mei57GjAW=#)JL(J+y= z3C=ygr|5v|*i@EU3(A%R3uXq{wLFn8`&!GD39&J|n9$G|mv8``c;X0U>Zym#v>KDL z_?y2NiwVjOYaMdlv1O6FTB?jlP@8nL(|;L%o*YimS4r>#t?m`7`EePaF9Au8dNFGd z1dATmiGaq`)}OyiDq2Ad3%rMaA2vlMJmY?q9-H>%+;BJ?WNK>2ABbmSrb+e9cDJeE zz(?(5Y6|^e3Is`+`(?8}q$};0F+x=m-cQ-lU2QW;Z#PKUAy;Y|9G^<4+bn{L!kYgYIxH5YsVCI@lMopGA&f>)VVcgJ}@ClQEthV?;*E%o~mSllk2e5dfq zPZQAOHD=o_KTkXQ?RU}X9O3=lyL;~*GJf)Z&hZ|Y>ZfcBl}LXT3ah3qM#l`QOXK#b zsk5T$Nmn1Sp<75qcSfV-`IMKWc~r;F-J+74Rk)47MJ+kV#iycSYr-Wqwxno%)wZAp zg|ezk%9zz0=$X`XKB`3Ue?B;kEy-VHgmyx$8$5JH35xUIwek}A*7gpao{fKUNZ?*d zcB%T(<^I4rX}JILYtntK1WwfUuA&b;YQuBPFyHc814f%bv+$VaA=280cco;e_q?F$ zXzK+Hqd`qjZ1HSs%JJ^!lJ~4rG7i%`q4aOP?0s-HR_nV^p4R4vXbK zh!D3o-&Pn;6#&-$LIo3#qo`5*j7C;4x_HBT0!Dq5{S|DJL3S1nE7@!jR>P7mP>KD+ zKBL$!e70QcZH2DaP39KliHky#_~Xcr65!TNml3D2cY0DWlL_bwjaG|InN>A+YuG?O z8q9H3tRDCQ8H#0H%)A_l<;@_!fm9OYf*Up2>q+p`z?&OQ~q4quR-{x=7`-Cro! zX+OJ>NM)a{Yes ZKo)oUoK@Dt2yNNc%!D)hxEVn%e$N9oABnBG3hS= z;yl$MBu1E=i#2St z3cYN2Bd4+a^UiNzOFdU9t+%3@FWy~16?(mv!)RykwYqSZ_3x3^ea!cvOSuUe37~hIvu{kV%IOr@P`h z%B(Y15aWi4F3lx>z>0ci+g6Xb8(k-dN_3TsQ*;*~*W;XhWjo}2t0k5(P#_GLa*zB1 z?%gb^BKg@k>`so_1@HKFbzOEtJbDbhg%!M;Ik&6{=v?E5SzaZaGl;n~)^@icU+;%e zXR2i$$I3KQzo$D}W!n%=W$NzN)a!G;3f@XH1Pvj7QP8KWXKH{OY_*WfvC=j*`GG2H zqQp0hY-lj-k9_+u+&6mP0W*p^0q<9g+vAFG=7xK3{~{j0v0cD!+E7uldYkt3N3u{W zx^3A|7~;1z>&EZVfR?O&9usqzG{5dpn5r0fKx{X^Zr)1oPSG_uT0Z=)JK#-FHafU* zxW65~o!IboZ7Q-TnlqUvk&_l(T7a~YkwSe!oAu+!K^atBwJ!l~(gotFJ{jz#!pwd) z-DEVU)!{#H9SLjdC67JSl9K$Y4Mi4}jeoY5nNMAKX&%)8z7SOQCK8<1B$J(@yPD{L zI?9pTfONJu791-nVZ4aLz12NVWZdT2B@z)v#m<#<9`!m^{V#8V z^3cVF`yBFNk3_N61RS$O@iu0`%sSUz%eGH1#OQsLPS}*cJ>l0Ss`ILwa}i21H=4ME z*@i_gEG?%=?Q+n)$vv46oi%fC7`E@|@v;A9}iQyTi+JdM51Eaz! z@Bn8Bk?YJMEBKTM%DPlDIoUN=Uf<0-)I5QE7$(e^eFt+oE`>ka64b$?@vYY=~X$b40+5MlLWhE;Q=WM@RPj0u&yKH zKLV@ORGkFoPPX4R|NKz1`i*yZR$J-GyT|tudH6MB6DDr20yhCjqcbfgd<*}x$)!_G z>bnZm$TX{lx~h_Yt6=*K6hMOGROM+|*>>Fv9tA4j3sTc4(k$O0cYks&Z!HJ4yP9EY zwSOg=r(JB|11uBiaysIIfk8NN&xBG2Js+2EkI0HaJ-^R2ri20r=y zr5D@03qLc*v6tp9Jj#WkNQ^In;jy&4CT&HIb%Epk{_f$T?$)-u9tz6Xl>3>g|uv=B!SKTXfdfXq?%P^n(7=7ctjL7X

c#E9{;w_!+R3)9knGbY-u+VbJ{Y zaZbz=u_Bsud}f&HTQPT8$!ZjTDY(@;km|O^Kn*GuDpTM$w7a1=nCN?uc>LOE9@`+j zu|UhLX(4sNR#gV&1JO&S`<~m9AiMuMF%))@^ck z8k{5{NdvAxqJaCpvv?)RTr5(;emAo;@aE)`s0G}ke5LDW(JUUi4`CH?{JtlZz0Qdj z@4mks*j4XyLMs+`^l~7XjB~$n>3AI{%*xz#sb}9`ow(-xVk4_R?e$dCg!HR1EJvD- zk0fB@mWZzQextS)x??iVsp4>4_6I-Dk2k?s%EDs0MYDO96_4MKO|+lU0x{ZLl|B2) zN>D^k_s<(7Vy1sO4dr+RNHF?XyD_N%C8ku(7U`+pbiF%K91+nUin4M_rZ1alG0zm} z2F70|7kp?zj*m?gU#|VS)Q0R-^9$;&!nkuLFr?==70vP z{2;-O6KvN@IR<{v=!?a=kg|h4xt~3=eJ&oeo!oAOtoo8d084gf{8DVrjTCeneJWhY zFd(`p;uHC1q8ugccc$!ev;D(?H`j`*l!|a?s0pv)&|%k)BWw^Qa*KKF=XLFq4>Fce z&lLCVsfs^E z6|ZzLG8TNX#rL6-R8R%vod%CGot*zHosn5!D?Ccyx6T0fJ|>J=FB+bdv9h|F4Vwv> zpm9`SO%UB^r<_l(^;ljVoOBtpC$EBr82i9J=u0VmW;BWvQ`xQb@;SL+!_&wo&%Ajb zwF(#AU!`WfGg9DxMzjJd`{FEq!Q(Pr-(XJfKIK?k!A!{f19|P&+1Wn5tNF;f(tfy3 z0L42^-9uyiE7yJi^39vDy;vNT9wCnJm(9Bv!<{WY+OS;D_u`}8bTzuZlTCGM`ywje zh>=A?KLTbnR~bn+l+*{==(p$ezn(ILOv+RT?dcsu(J;HH=ZVBAA3lN<|7<9Xr0{pe z8Zcz{M>f^fY<_h0x@z#cUULL{*l^4MNzICZtj0hlTbHq^)wV6C&*|yX#a*phrRl72 zO*Jhoa9C`AzgsZ=R@=c-zwUm;uJ*6R#py-xrl)TjlIq>>+K4-pYIUZ zcny1jOO9_7C;9BxVm`hjQvt@idZoLr%sMBU-)+`}b%yFmOeV_L?bq!?s|NaM zxRXKe`@GhQ63fd0kIBP}3Mn0OCyuyfihN#q0+Z*hm15=Eey5#y#oj)?u*i>sa4~|o z2McmDV$g49L(XTo*Fe^1F3aZq?(!PvuCpHXgSs@k+koCrAAygSWm+Z;!|bYBR;p_F zz!!gnu^I-Ofj5NX|}{FuBb2sw@_h znkS~PcCDTQ>c5MG!IiN|hs9Ga<07(%62G~g3xK9#a$N99mG&>q`;(wTLZxna#{`mH z6RYbGIo@#yqciXE%FKr5!F0WfyO^8O7ms^%m(A<=rUgm_(3-1CUz%dGk(fy+&?NWTh$qa~e*~iWlRZdpg*f<$xVqGY1^@suaNooek;wO> zjQS4BTwn8#%45dp3j+X@-5S=3T%ewh?oeyh4|db(K73YZ?v4Eh$po?M)Ae&_X7=+_ zV&z&Bf@2a`oO!9mHs?S}B# zlNT=g9G@boY#FxY^@z={DY!7P!9vT`T8DZPIcq1ilHD2w(T$a|@H}XM zjMVp1iYTRu_pPCQ$T$HwtdUykbil`EY#h^lMDq! z^4K$%R~QVn9k27z=n&~bm{Xh9@Z`>L2r<~W6^>YaCcCL#HrxlCp^cOC$t&h>HLP8< zcQMmFG3m-RU`r{-=z{|48#j} z;6G^#Pn$_di!-~KU-RtjY>)$quTndSNODhx%#0};cS11)tv%hBP2_OaHvxF-EVqW! z^y4UsQ}`Hfse9>Qt?dy?=pWfN@PCZask}Zc#tA;1t~|-$2(JR| zH^M6^Z@BkFZHMn4?pyD-Zt@vz$ce#omCfZ0tGQoW`rYDQK%}sD@3m=~mz{jXG0TPE z0HdUM3+gE1z99x-;+~(S*1CT=wI9rJmVxz&4T}r-7_Ac!nzt-_axrLo7Hwy>mRxmb zIsWW!A}V9E#7RY3 z!UOByn7pR~i>4fuUk;b*9V}OW>f;n~K9hiSunCN#K-Z`cm=~)$t8QXOYvS9(ef&~Z zS5v*MTbG^y?=>7waXv-^Qs@b2pgm@*JAb7tgd$yMKmR%Q@$GGG8GK5&aQG%j?8}S3 zs^x+?dF5n`wxwnsrTPIwatzG$`t*0CJX#5mB$Lm{$>G4A3Pl@ojB4(P9(I;!9Y>0c z1X|iM8J#Q5=Y@`rwqtxeJe4l5UI}T9Gxn!y$S(l7mL@-tNuGI58M+p==PqrDMld3xQ>^|$x`PVxnUK6(5H zEinf|`qyg=S6H7W7qo!Tap%Rj?aRtPnaK<~O%@eAlMm|S;SM~KvOZ*8lD_D1~w;Nwj*Y}`8wlZ=jIQ+v5dfd;3js={wc?#t% z6udqwI6z@_c&yIHlPR%S%43GbOAC&Zfp=Br#$yeol*J6T)+R!F(MVNeS|y=`<=DQ38WmORz1TOoD!txH=%5s+KgF)&ztQWGyeY$Ic2(|QDl4D4!9Q4G zzrqaoNXf`e9h$CPu~8I-V|6uHAz{aK>^j1_aEHTgUmfM1f`pG}EHr!oazpA0k}dTj!>w_-l;9EscSSCU=7>s4--Br`xG^JP6+m<)dhbl za{k?@nmCd36NcvH`ukFfVoI{I~4{o&JolNSx%40{St?xpX9+_+8Gx0p6j5bLb> z+lpsr&4A5y08rZNVg!TsIOgK&814mHC&qTsufNu=5IuwM+pm1EM!346+UNDXJ|HRW zfi!Tv5nC9GM}KC}_1*@;)DHl$L^uZUo)7)b5pg`>89;Sh{gluVIqZ6irtf^krCD6M zU>S_xyBb!9umn))L1ahPa0N?xwXHwe-ZlKkuy)o#0t~UT2=S^%3|j1^knjFDSzf@) z^uWgli`K<&7(yjaP4SqcAG|54w!g13OXU}t0_Alcd`~0gpr?I({;Q$-vi1BJ7r?=I zhZ-%K=5NmSSC-eqfCYRw)>o2Qn;T!ZS09H&M1k;vb>cfD!D212{ecxr5@cezvN*jn z1aIqH$BgcTnX2#3gQEy!68CP@9Io<9qSa^ym2?dj(0HR`6_6E3u?iS{V zO;N)9smoF2c;-vO=EeRMk(0Zu)*0$-<%HVkg7q<1E?ku%%v>URCjmiEK*W=DpzNd22F>k;=i&}(yo zE`v*6qHzh1#RQT{9A5(DDgOwE`+TbqP@8~06{Nl41a!OHgV zuIDP$N9{9(eT45$hmli%2QzJg6IzPCo=iJ&T|1E1jJC5KpOH57Z=xH|uQ(SLI!&Yv z#_yM9QL;B)OUCRptWGQ?VKdnYil8+OBM&ZZdrA22Z&?EAK1{)Y(JRo zJT#mAJoFfJVQqGKAdv)l$>V;Z9UBdolSoIJ25Q)D3v6HCrF@UNqgfn9m6fxGTz-}$ zx^+HJNnxG+Kx?7q7iu3&hxGQm$=;>(+NQ@f^X18`??>o1y?R(6G zv9JD)`2J0nM%c%-d=GbZtloT1yXG0<-SGBYytJwtQ(*YUWfs64^JaB}RIy>K7)J@m zjTR@ct~iQD@oAL{PqeYqWF_L~-K9!gs>Nk?eyIWxy*RVua%yH1t1v3nj=cq)uC59v zC6}f_r^TP@gJMs4{*bhy0F-ul6mAtCm9m&nEDaT*QBR#|QAr7F(H#7!9J~7La-Mat z14ySoYzWUP85z0CJszxRfxwnlP#f?oF6W)-jIMURT7P8ML{5vVb18+sZtU>dEoBDA zu+G#z>qDUu+UR2Y3Vc)DzZsm?EC!W28(W^A2f@}lYj;# zN9J!yfQ&IjTmAwaQayPrNQr5g?vC9Sf-9FgZcOEv0V8LgQHAFIcpQMs2{5^}#Ib2b;9Kc0 zvD>oh+HmXS#N3`S711~W1@~4Jhmvn)onr4#*4ykujL(!E7Xwvx4>pT!%LU$9Rg|f` zuAR>svaLRxXGgETiO;00H-h<>rx}lIjO+UkVWY7nP9+q8M4mW943@_|_?&NIjnJJ| z)+7a3GgaM=>?6*X;kwbH^;rJrinlD=798t9bP(2GU4rq&Cv zn@AJq)i3)G@Tp$!FSip<*L7NJU4xHaum^cD)nB$loPTFGfPyjA#DrE`6-pw0mDjI9 z+CZ5*P;NbqOBfEid478eDSoFzoNN7paQ8LIoS}?V6w;9&7>u}Go>4<+_>U>g){(K^ zjf~NR0=B72jjWQ!azRxpa>U|pwt%OZ<>|M_k07E^gS5BVLqmP{^Hoo-Wa56$eVV0DtRYkW?X4Yn zBqwbN`LBv(GjQ%3fLOm<<7BJG?N@+S^!E9G7u@?)h`K9|bat+{%K`3U$mPP(mv*_) z0V>YX1c5CqR?)dw0Xg6yGfbuO>ZX5gUXbOw-4*b!1`(a1)?@nnxjteVfA#bEuKLdq z5*}l`{rwfl#BVbG=j#yBK(&96HZ$A^3A*x5qLW zwf{$5jv7pKG?$Y>zGrg`ad~ZK^2^Z{rbOTef7#N z<1v#l(_h$;{kh6tg8etA>SPl>Wo7tnnIb;seo~+- zC*e6-vK$DD*yob&zuCu5fx^J!aBil86Z%2oKdJZ^Ee*aZyn3r=a&EOyoX?+hDq-4M zZ_sX4qh*lqQHmAtix5ldg6Xzq^Iy%3WHajx52YwMr3h`@p-e6(s+&huZD)WC(^sc9 zmDGTgO-ZvBGdAz zq7tCm zdudwUQ7;u0AmtDr+jgdcvDg5nIJn%Iqbkn`3CiF{2VybIEovW%eLsDf@}ZC2*<}J3 zGJ-q+nUOif0kbTOlJcYHW;%XWoDoQboMp*;{*o}KtD*U-xAy)rA%LEf@!Pk=*!-}? zc7%qn;FY@cN4pqDlW7ksHO;d%iWv>|6%eBsWMgYG>|S zT$b$wZ0YGs(DUcKw7Yh(r4162pE!rC~@CDcuP~ z-v$mfIpoy$&Np>3aBo%dJDweG^k^DT7Ru1ujC{Y85c~;A2 z^lOqGja8G@5gkPVp$Io{pt%t*1}5gug?IQs3D!W5c(28~rZ3gJpC+BVyA_pDZ`m-e z@}xhGl)b1k;T9ceX)pCsq)efyIbo}s1gh1MPsmdg>kWkib`4T{+ns|HDYd%0pB~2L z*!T3gyY_N+q`D}AyXgvkoQ_SIVHNc?RWR$JM+?`7s)2Vqx{U=P*4Tiz{;%d<_&{=G z^}}2XovNUndWDj`Sq*VS2xCPedh_QPt0^5rqR@)*U5(XT|B}u6OdlWG$u^gA1H$#` zOgrOrVf{~XYUOj=e1)YwX6yAYECvfAKV>d$J)El?fcf>O>Y+CqHi+(w3)c@kyQ1c{ z?w%)uz#Ae&ofQ%^q@j~_At5I`jA$5_IV*=#lm9g=v#weOLf)NlB@O}4*VrrIlh zv--iRZ@HfmW)4TCS8rlUEqQ`;XR3_|a3rd6DuEm($1GpGZW%|ERhUxp+& ztAe=#u4V_`z5mlHC}H|R^7FY(6+?Zp5tsGQmL+F-Tw>6Cd*Q|V{$!)B__9v{m1_p3 z3^O+a1MVhhDbOoP({RnV8Wf7!d_3`+^}XHnA_b1%b7#d^2N$f-vD6bLyrQmv$pu&^ z0Hl}?Kykw&{-fl9fyh$S3J}hfKE=>qwUF|lTdYR2V}N{CES(=pfg_^W-ucA^e)W&Bs8`99U%^$@Dm!9l$G57 zehtg5lVFe6YMso`^6nv2cs5JZ9SRH!`=w!YN;Y12)$U(D%=DO!W=b9>hZ4aUPm-9Q zH{d2f@R;U)2E~9H9y0>ouq?^e_K;y5rMszu<}X#vt%wu^;$xZYeVZmjcd4TP(DrN^ z?8sya)Owwd{jx!;`hrE~Kd#wnR2gT4G?H3g2Fw&yuKb9D9bm!u937*ROdf&Cj>_gJ z-@gI%i~OwtGhRqZnQ3iVRrY3N*enNrL%))4)f@kejz?Ynln%7a=DuIyz3xwL6!54n zdkmBzQ_?!8CV32$k^%KAFI;?p)c@@k9?K?HjCWRHDOmnR(Ll)JQyUFJxc}O__!8?b zcl=CD6cf{F);Q>2&Ppv&U7g;tMnK6#l45-^AIOAJ@M6YhFKzy_fMEWox$qR1tuzgN zPg|bESu%oRwv~BnD*se0JcXy?U1B8OCsr!Uc7Wwlh9uU?@pJjUVE_zYs?(N)cQUv0 z+droU9H)18J|BX$^0<$eSS-X+r9jF8o;;r0l~ct|3j?F<7^%KRb2e3UIEz5&mUwC< zR!%*z0i4nuzpzy-ZYp7LxImn{#ewf@!8Fo@;nO}5iAYa;kgJaJt!D>O&ip5=c>OwO ztbNin-Cxya^%Burr5E7AL|1E6>f;H3wgA;gYLIKSXnMT^iS+Jy@s&jYYlId4<)_JN z$;H5x>Wiy7)`nDgJ6K)!)uK{;4R9Hav`n>vf{TX?7gy%DaA#4nerD77VyDoOCAL2Dl5<43c})EUw!-_W=U;Ec@S6 zjSvxsQS_Wj+Nw+}?;CjX9K zM#Df?+5`ZQH`Jan37B|jKb7jT*)_z$o0vTFP`aEhAsf$4@;NDP1n#3_SDblYfe?P0 zLE~!()9g_>&R#7aH`mQ~jJf&?SvDZMPsdfHWFH(l;#Im5F$fg8=zxiD(U-&wqv8h# zTQ9_+`pE#^9@K@-E8y++0>EIF;}v#GSY;n4qMN z<)OlUsHS&tf$T~JS)}v^atCUz=+oh_alFio&8Pb(rj2b zQJP$XsEmxT$#LiD{WjB&ogo2wCa>PUYOxw>)l^=oB75TAA3i>UR$-Z0-T|uk@^e?y zeXVstonvX6Yn}a2Iyb0oem72dM!J4MKb`=Zc~d{vd|O|dmmgN-3m8{jo3*jOqg}uT z%`iLn_fND(a|)dfDgw)}gLfmBo^1k@_ArvoU~Qw|{fBP4L?<(w&16yYO*E|>KZl() z%RKrDxYAUd4h@f*jwx2gQdKR$2wL&3k-e2TD?sT0D^Vpleu^~&eVyHUeN3b0hbHjm ztpA$xN5mg~OPtbRp<$_^S3VaW;)hU0LXWRnil>{17d~mirieT2P;v5N-5~fNG;q)` z2rn4V2^|v<0}fjW*Zzj(E{a_Z!lF-6_F)vTn6tdtol{V4FUfs*kMmH1I}3o8rPq4} z_dS@roBIA0&zCt}>LNEl$Nx9e8K>WJ2$=;?JpujXX$HiX^RQN^QI`Y{AJ*ttm>z_8 z4L`n@8M@8P!Ol9BG7TguAXd5Y*o2bmeu-dCbtX!r=jY z)RV(8gcjoS+_w(3?1NiO0Jc-~?k_7jlWp*qn_}kivye~46u9vpfPhN1*7yNE(wklx z2%sQrqvIJ3!i9vqGv`Fn|Cqts6Il-^5Hr8wAirnz)#e}de|vI)nl`@D?<=Eab!%g_ z`r9LN4?$E7rE!|xhUh?EVw)HQ(BW}Ofw+$cY4~G;NZt6#Hg+1|+V5syF0(=3nz<={ zb1`%qu2PMTGg<)B_RLVrA5q0jNWY}e72O!{_lVqrsM2EZg=GB&3fw-Qpd5J6@8`p) z{zQa;&N~jfxKep4zZNi0}RaL1jcIL=-v8CFK1aR79{|UXz z`YQMd)Bbjwwz|V~e&aVqaJI}%JlKYAe2{hWzx<3_j<5Pyhh#qAJtxZjn?>El=9SLB zNgS5o%?SEk_Id%8&PYLl}vNC%c{Hf6^EdGVF$aDYRB8FXV;#?KG`JK()eDiK96Va< zBe1-60I~kTHXcD7T5faE*ajaH(P>%&NJ83Lx7qH3Gh!2W}P?o(aziU{kvu=ZRHdc zR)Q%US1;j?PeesUor!=2HK%MNf5p`q?TgsM+1MP(-c=db{B$F+?IuKE2?)~f=El5q zOd89eB%eyZfFb>zl?_uMP1(kV*=xVS!}F}+?A&eZaiez4M^-(4HN&^cuC8=ZQA&2R zKOsyiVm%vu39-q^^5A8Y(NQiZAu8?oIdA^@Ju0kpY$^I5wN>f$sfF!5a(4p}a63yN z=jl2m);DdL)|2AcDCh3Z=P~EUua>7|x!MhhB<1|bTwERVvGtDF za+BcYCQXON|Dx(E!>a7MtwE5GQt3vJlI{i(DJ2vnrMtVkq(ekHwn$2M_m=MN?(W>g zw|L(7Ip=))f*&GmW!-DdIp!E+&c!D{g4q#H2pwc@{F&WBvoQ!6%r9`& zMJC0m)&e`~;5T?9GY9~2|GXB7%^XB%L$7&w;{CD6pwhId zT~S_~aVslna0%JukijTmn@yF|U{*1KFv?()L{7-h(6ip@ZcCvxAC3r5#w0y?8$~8` zz1e)Qt*EpqEv?8AuNWAJS&v}*&%2jx0^Xd=SV8hXodso4(HaR*;XJje)zEMpAD_FQ zT?Ee*yIMn4Ru;qg?l?;D{z@P5iEr0g5vF+jB7XoI3#7Y^!PsW8kom()n!~OJ+PenTy|q%%KgETRAZRcDohR=dPfXF` z+Cj1(BgW!fXSX+VRFUyQj2GD}FCsLAlymF+_Oe2HPo@@Gw6+IjR^D}dX0I6@-Sp?M z8UhV>NLXnpN82nq-;xDSbwtR3m95}xt#!x`^4_aeRS$!<+i&m#H#|(2YMIF(f}3d)4`0)yn)yE%N%EWYM!#8-Hd7QQJ+9u17Q=hHgsLFBP~mg zY8RHfw}%Kg*xEhAXkOo`vv)A>( zYa`d*RC24!Tcg{YH#3DsS!i#WApf?p+_GJ8e%)~V$;UMWO|KZ%ZV*L{!=H8%HdM+# ztFzsVAXv`E>8x%}7Pe^9!-5kWx>rEj9P@8Z z4Bq3c=VDS-jSDeFLPbJAy!A@K^v~;grUi6O9MBdVx6!)q zr1<4az~t^K7e4J}-9T$w}VM7OJ)_1wYh9ATIc1Y)W{OGsd?Z5kWs}8)~-2*gC z{{HUK7H9afs(0=c< z*NLyy70RM~GAnSIvPfgsubO8~vMI6ex6Ns+b!-+r<>b0Qrl2u$x@Pn& z%}Ci0sy|E)zb!uFipg?C;t|gyBb{@qYQ1=BbTafZrk=cvqEw+wiDr5r{)}9wFo9N?}!cz z->Ck{MpaZ+_btoP&*Sv-OGn!QVLW1s6yg94|ehi!&Xo@S`h z9N^%`;u;EG4jNy1Oe@?j&?FJ>pk5_)_jaetA8HwF8pQladIu5qq+?+*o~bY$o8*a3 zOT$HdPc_TR$ST9?N8m%qY0IBdlfq0A=TP^a|Um>MX3l26E*@oafRW~>O>Uk#t?E;N%dFHy{ z@q88gi9}-?@LA$^Zsuh-EbdWiNB#IM+uQZ71UZ{>&=@zOL6+uN-9Pj$@8YGX*X(na zr5h8bTlPM_+<+g1;5A0kI-*p!BSsEF;`}x%HYt12>m6Nl&kH?;4w^!6Q&3@}diMha ze17Ra%j~{++Fuun>0Jmlcv34fr%Z(YkY>Ig{f%oi)?kRY zw;EimwYU2VYx(VUaqvv*o&tJgu&F&7=EWPo zeN-$?jR@D-+^cO1&g;ycrSHSXvvc`VK4ll*(geyf^r!P8;16Ja37^#7I|bhR{TsS6 zcU6_w^pN~{(GlVWVk^xjPWndW%N=L&019-hbj-}o{*jm{t*iSgQB4i}VWiqx8;?o- zucEwA#OO8+2S?0X)?i;MyH<8R=E$K9M!!}alRgCmsIHGLoYSrrl(nm?t7Y~0la`iM z^<<+S`(~Omv-j2fq1svZyIWy$`m`?^R``H~9OWF>QgI4N6LLRZi&0doF|jq6X%i1~ zJ?Z{)wm0plU+6f;$jpbVg;JTM=^}<&&cYY53D4{jYjijoj@%()IOx6p1f~U^L>sjr zshRw4#`PavK^q$n)}FmE*JBcQue~cs78VIk;=-P1(s9Z+w|ujlzi^sJ=(@)tQcN zfg$~6c_#jlnUW=g@1dM+iOOdgrJW8q7B5SizXUPH_wYd)71+9Y!GEPs;#vNSODIS9 z7<eetrtMu| z`_8ttbEUaE(uR1T$y*@U%lPOL;`mBdW}2#VFSm|r>A+37SdF-EgR zy21RZwyb!qHpS7L(xNls6s!38>`8#Z5D@+0>vwP!$A66&N<@YS`j$@CN4>OiIVNj! z=RQdjARJ`WvS9Gn@M7>z5c18@ijaQFa)rS2^XJJ)c*2*8H3=^WBQME=gUl}%_~z#H zfRT9P_j#g&-segKQH+8=><8(5SyViN%!W64@0MWnq~5g7QHV7@DtecmYpzqtQd92? zuB}#fDU9b0q6}RpWN9SlHm$sIH;T?G+liGVD!y45&k!u_$dSd^FT{v0M+ZAFTL5>;S{=04mgm#14qlP2SccP{i=Q)OInOUw~y}eLQ zSv+R-u6gIh_Up~mUKTGeChI0X0O#MN$l=T7ph11!Qur($h9QFTiSlfZV) zPNa0f&TY$mcY#a$_!$6@4(v}MuoM!Xb}D(A$nt5~z151&BM-Wv9@PwiUb2je!RaD7 zqL@)kI&ylBn!~06G_}@Nd27d@GzOmPb4;7XCp8y#E*ohSDWplx+zrQ3Z*wZnaIate zAHPa!M-h5uF)=R+;***=<{jdlM7CAejlM+x-t{MpdHD>swWK(B8!?HAAt0Ra@I(!Y zXt(yVG=~}z85nMY6#Xuzl*Gq(k^C>K25+hrI#k-xkrZ_FgJkjf>+D-4C0s{G$AoO~ z!{OmVM5O+l72fGRpWnr1If1hXBbwK4(FRu2MDC*H z@$RDnJKQviaOMua_!)hFOYwYW(!?;&Gi0_P_~%?#n^f5B7Il^EfgEZCEzxX}^D>6O zunni~gWhE?nf#d^N@c6%1+$SccPWgwW*;A^T{}7Ti)n(#oZL(GjgG332xgr!RR5;N zRobY=x&BI+s-T@B%zt=7ea@?X-j5Qw!Ke&J_2$qfD+^M7Z>e%EViyC+*XH<2x>_M_ zz7PRl)I{HvO_eIZBMiFk1y8XAx=8DX*Rau}&UhTB+By~QyY<@`nqnL9tr5|NK?>Nb3 zv-FmTi0B=Y^*);@b~{qmu$g@Qe6gV#;uH8eEBsnMJ{Liw&^CP$~fF6RbG-|w)b~lET*PpWo7Ja=&Dr~^xoIK z2)9?A_^hrchPSYGLW}8!7x4^Fb4E!~mHKs9ZLvS^PmxcT_a|{B-(Ac`5po!@+BLtJ zb6AZS8ykDgjQ3el5h}~G(A9M(!3xTni&<-t1rK}W6}|btD1o$*)qE#{19bH3zV=oT z#G9wrqjIa)39|zFYr(po>VB}aVaF}@)ONeg9#jBc;aL`g%KL1_=JUPGefzH;>=>Og zO5+9ie)X(0O{(9kW@db#;d?n@sKRTPNj0MEwCCc#QtUt1$m+ooQ~zLT+hSX&q|Se} zU3ek9FqWpnDLwS{CaIgabUapIZOM-cBko=x`<uI*3u5MH*A-bEitmE;qB>B-!??cC? zB?Sv@%tp4GM?c2dwwg?HlaRFhV3x|^%O}|}JjRXv#=XLwsY#(C1TEw!dP{$O(O5yn zdvynY>m?Geb;EIg9OVtxKK5*HJZv-Vj+Qpf=1C{Hw;*kr3*{!n88a4lJu@@Y1~{e5 z7QHf15M@BfkHalQ!BB||>?CsJP2nXelFHW#f_^jPgQJaGZ-Hav@G(Scc?QnxD-J3Q zYkP#l<_FB?>;8TXm*uB(PP@g4JeQ;m3p606r7+izj31uAJVRzh5M^aTnJEm!?j(q4 z>`FTfriwCH{@pH<%$>TjqDSU+WsOeEA0SEY`FbQWacFTOBTBffBwftqYPtEdhDKk7 z=_tTtY(eC<@8|gIqoU_LI}tyS^PS>)3YLeUmJK3p<`kJheF-vncmbd>d`#+1WT5 zJKM$RBdN@GW({Hvqpj*$rYrti-c^?2mdpCkNN*z2{4rs?sBzC@1chH0y* z`Fdw-8o88&nqaBw%>VM!29r``%Hs4m^Fn@cLYO(d%fGYhQdG3OLb5)_uh{XIGS;74 zI687Yefo4Qpkt%2uS;+H1lQxJ^@)O_BA|6Sd3ZXX{tnbt37(jkV7HiJy}uX|LnkX^ zQT4h%FW$Uret?NQF0H(LXBndgGpOdrNxW~51#i2kGF?Yh%Z<1;Q=Q4Qih0;4Of7~? z2#`Q7gM$nPEgp6P9?Pzl5~f>j^Ex0tQ1|@=A;@_oky5O?moUIhBKpDG*`M$l^yxk> zCW+V8^4Wno)-PkE{pZs*{5Awg1V|w-a+gakWt|!$Qxf(IK5<&?PB6{cc9Pz%CK|6~ zYoComPJ%>kebaxU*HRXKle`SkkO|f*7%jcMQP^DPmW_)=wqGWE*UT-ar=<`Ld zu0e7L$jjm>l$v8kWGy7MAQA7g9K0-c+N zhSaMa5v%ve_wPRI!ap`YH(hE0cGp;1UY?c!U81ckFc1kOn=U{&Ni^TPFSDY1dCgZg zoF3F07#WSs&4ojkgDZM5g5p694z?>8)M8t&XkuXja-aA+d3T5mI@RqBM+t2Z)gz}h zNw@%+(#JthLVO}BGn%R0>=jNXloTT`oH(2z8Iu@`@RoIn3jDKvOHwZ8yn0pG@=BSS z`H#e*01n32Dhoo|RF@}k_6u&wpED$=ALmAl?9<~|LVwaL!hy$6%f*Eo)hT9XX14ay zUEtX5O2vb+{>T5fb~;H$ufL-q-qy@B3*T>vX}O={`oW9HMqpShHl_YrloXB9JFz?I z>g&n;^~)!Mn1|i_-s8=iH#T(&tW5qoLu5Q`+-vsr^I$SIyHQ`OOd@;4UJ7GFfBzgf z_6_$pyI@r$(+=1 z+x|$N0{;2$XGzj_FDl8AW^HeP(Yh-qHN*@J4K>Uah z!hVc2Mdz;N+Qi~*;KS{v2o4U;()kUWEOvaaH~^Qh z!)6gcP_k0HA7T&)Ud6+%VT%w74i4<%N#bWzo&Z07`0#=EW-EixxsMHf&fPlH{p?u; zu33p;uY{NL<{{YV_dx*qBeno1Xqor24yT6zQG$ejk5rbij0++0@0n!_4z1#-voi;Y zD6;;)igL?GP|OVZMK2$0j;;1KP!h)={p!w^-uz#6PLXaV(1y+p@UHLghiB&I=8AUZ za$-I**S@xmrPTcJUzbEzQTnF}cN8Rl9W_MR7&Ysr*15|?Xqn&GOrV5lPxx z3OeMmt zSXC242Ce#&2|{P^VU>hlDa(_k&}H<(MM-;m4j^uu3{hZ;+}cD6U8r`1^C8Nsaz0gH2w;bLosX;Bg8Izxu<>%EW;OC-$~-eJq;Dz9u<{tYT+(*KHE3vj zSQA{+5JMV&ze-bnTA%l?n(P$$Zg`%B03Gx(s#UE~-Je1TT@>cO#KkLWe)Sh<7Zd&b z>RPwXjh72lfFlH;2UGBfqNwS{>_S9`6Rx=V;+gmDDmkH`3#)OeBR7a-tm5KAxkW{K z+arT6o2k{;SF2IiD`6~jZ{Dm7cap7Mt;!?nY!DaQ&RSM4pSs!B&a1|WdwL2zMi66& zC+2D=7J9pro;bidPgt~jnD0DYmr(m-0(rY|2}r1sLY`IC7eW5)x+mmvPF+m3~(F_iyJR~ zgEJXYKAUAa`b?P%W4#X|w~{-YK`7(~=ZkBfSWnsF^TKnxrzYR7|K-Hzwk^?l`qvu$ zDfBGIwsUNR{af(xc!NppL59-;wau~?>ZPGO4a?zMv$2wnlgHogmuDA5fXDFhwN3Ot zB68|qR`evI-Nd^MnUPVUvz_^{zB6 zz6HWXO1Y~EG@z-3*J&{K^!9Xh^{p-WW4)rHO2(Gsjl7eL&}$1oyeg7ZXDO$nzFN!8LGwOKYn>W_oF22e56 zu{0b#xpu8ZC*@9A@Vo)ZQ+vT>6=N>_Emx11kc9t;jiJfe%QP}!%s4|9b2XrNJ|5G& z{5-WvGwQ=87#X<-D`Y3n4B!^}H*dg|3{Nhi;Pu+cRHpgHE6>-~r}o2~UlW9j+ykib za^1|hV=8)ZA+@wK;CH@q;qSb>&{txCKnPFZt=CNAF4R$SB!g1HoA7(OKUKX`qo443 z;b7=BNh&rxZm*@67@MiU-N-^EVXSy@uQ35yyH@K9{ylSbf$xTk43nIaCvh3#PN#D| zZY?&mc*4$TXa$09Z=VR7ZhKrUciuYRdngEP16BsGQ#wOU0seJ1j=9m#7ru#oemA)8 zhb64Do%8VsmIRIiIw5<&LZiFl=g+M`>Fz%D?nfi?$S3Viq02ca6zd@(JRBWFOMpngb4tHGFZNzv z3wdmIK5jc5JjvfJ-Yl$M_+3;K2?X$-o}S#o!gaud0tl&>NK@Q!@(kQ<5zjC)GI4l` zje>Y|?EwdhT#1c#<)0lYp)k)S9+I#jYgbpCIm0cXx3$`k?{`N;Aa{H}j;(mo8P31J&oe{84aaQRd5 z`W52i!Liq!Gms;)sP-%*B3eJ+1~{z!n)hI-E}$JMOT z(Wmy7%_N+wc(jGb$GupvyP$JV{CiQGzbT_@wbt5x=$_x{a88o_{t)rbSsqRA-@dSE zu9f^Fbp_a5k-nO8rsKhGaZ{hoR+LfULd=!sgH!gG3b-Iqu)W zQLY-z#72QaCJ3sFT=3q%#YUA#Yl2fYMUJ+zvJwz(z>@H&v~bFrnVYkr)3)k--`lg0 z86_(o-8|JzqPf1lCUF=7gH+m3NgT&MlVhPnf0dQ} z7?l@E6*y=B4jIZf3_XAY2m&gz`fE;*qzD2*zz}L~ymMl%J!2=q^ru(MKH79Yq!tiJ z-q|rD!9@N~HL~hd51OVxDOc_Zb9&+n2k;rQAXoU+q$4kDWmE*hJJ}!%sHna^m5>`w z`C${7&0CKTqVU|D#$);M-Sa|sX~`2V>@7v`s3~NyoRNXqChh{5Bt-sMM^jCAv>yJG z>3WVjN4h!=uag+a_qez?-dfF<(Eg#n2{t7N>038{huCmTIs%>YH(7&Xey5w1!Ey1_ zd9>5ot8#2*Ui~WJSMN^bWj5VA34sw{zOe@bI#mW+2mJKKCJ}9W0}!UKSUIMh)P*PF zU{=NT{AER%ofYCX^+|m8OPQHix#s`28cuWJgdPYl>mOdi61mS&tE{I31}CKy6{)uA zP4_q)=r|Tr+Ie=HvPx*yf#Is0ike)p9NZ?`q{!IzET479qTNDjBWXzo8jt;jf>)8%aOLc?e{sF{Q z6%E^`liJ=0%+AkdtE@Iuns0E)y{=xly1GW^4gUQ3Q_96{Qqws)F}8g}HktRZ;dH9b zkwF*|C59#R^AR6Gqj>$&gxscNN$%DiIW5xdDfp zHoP|Vnq%YRfU<3aM<)5l6=bOPMM>$iii)JBCMo#u7VI%zkXMT2$R)im*79U!Lg2tL z$jBSU-0cdP1|-DG|Cr|_h2>}K_Xegi-VGNNFb;@3-2Uy}pP=Nmcwyi~ffIqs5W^Hh zH|^;}AVY&njh)XThQ@B(^YY|np72-1=u+iD-JTx}%9r?U=?1tN`eMTg&*PP=qf3fy zccq*9pI4^jT2aSe6*J%W3 zkw?pHYBhODFagIv8Jp6o0|&L4N;m0KG}A@ST0Y_+K!4vRuczKW1JhsZWJL!jFwXD= zdJ=&Irv?U+KcGySSNzDerQF<*$nOskgl~_;2KY8fxGkny9`3FO8NW8Am>1W_frTY3 z0XIlssA$q*SYS-$@Zo2#W?OxM90T>2B2aSaC;!a0l>3fXAWAv^LmPsDxattab7vrrhw{O zL1B)QlT(iXiJF?4#D0%$ZEfwSe+CS(&jkTs`4mP+M+e6+Cp?p>z37$VdNI9MK6n(s zs+Mjd>2MyR25<#%U_%<`-DHNlV`w=5@mE>9pmGYlcQWk2I2RNoJli-#QW#f`7Oz%o{RImpcmBBvM22$_- zGC2EHV{@)uE?jYGt%>m+I|(AUIL0n~d!--8NKYlOA^fF4_c-soKpWRfs%Fwe3MlJE3Cfe8G0!ggdTiLiCHC95qdKZ@6 zKa?y^-gwEfcEDtikuIr0it*Lf)E|D( z<-eT!2BW5cFC>_Ha3ny|(M^OyiX)Aws^LX<-;>SZAh}TECAlzf;bb~FIdNHwmgIFD z*{+$VZ@8byzrC4k-bi&`SdLZET5iYJUP~TP7!W*_@p=dn(MuAYi1mWTs%W$Vvtf5n z&toOAq^_pcUAvjq+vt5S0;EWQq*pqKtqm6DYC&c40v!qX)o8h>zfEen$7(M+V3!;9 zhoI{!thql9Ll+JKTg-kV*K9*B zvF#_ly(($qG{lxIios4=nflpxh$Q#;7vR$__7T_K7&?4tqaG^4vD0n5ZC_D>p@dKqSqQ7WS^S#@_-RVPgbaeMjWq$3(PQL3y z<0YkU?&R)zH!WmsCCs}=o6N-rye-%}z)p$`xYPpe<}|K+mDP%vuiyz%rstcg6JXL> zIX`2L2i;qLii?dO5G3qoG8Lzdj~;7U;2iY@o~gY2H`21UpH;t0dU;{WA)rHFGcfqK z!qAN%uf(KePmkJra8)IqGol%$15A7(Hd*)%%pH)}7)T|q6*BDk>7S7e%xG5-n*l6e1JQ1>H8@l-%0M&24}|KiVD{* z@9rzvpk%-%%Pc;dJFEBqHmp1&Z(O}oThxQb{v|ED6)ZFVs8&9TY|Kh4o7R_@(X`4I zmwK{1;=QaLugERV)K%SNKUTwrPRJDJ#nb@?};-14;8DGA4q&I?jYKwK@BNjV9OuT15YL2Tya()@cmt|Pz>woAMXp9wRsBZyUvV# zYr~2FgWlAZ#%6pv?k1UeQ$XS|!h2H;>HSHFx?6Y^K$u>t{FQ;T64$0{>%PRxYHn3S z$e7tSs6gjA^>ihpJFS;M{^s99Ycx_muXzpG#%^Qn8&~i2#|BNR_^3G7Ya@LM+heQZ zY-TA(&F4NlbrkDL^#^RA*>-?3ast71QEY6gis|GR9nY?t#REgG0^ zBA0DIQ}WbXz@5BApIPKXfQP}d0UNoe=qp6LaTP~wRpUDt&+zT>`cH0udQ!Hr=~{e5@hCNl^-50htF7x zxLxjjGo0BEPL-ooij9qCdu&+(8zUUV=IUz}%Kwf;&=gT#5xGCcN=i=VTmPvD=dv2X zbL1kZ;V>*75_ZxDs?2k@*-8s{B@cF}mHey`ml4c{!}5=kAmT6WcU8 zs7+-7uvXMVXuS_l_IT<4wSI7iPbTrBL1L)9(UF1!G@KaOp6V3)0&Ppg%1*q{XjHGNiyXq)Pmig@)h&K`iG@-(^&+`k9I9j!H}3{4)2!Cg0{|$ zGNU(OK#t=o*30{K zUj@V)0a`+-9||ZN;4FXbP|1h}Kr53e_7gQI>t2sckftV|P77R`%L*#ePjtkk3@rQ- zhiwIrllX3rpxg5~D8=V3>n(k>FlYxN&Xc-an>e*Ki}yNi0K3xkDR9_X(ga= zC%9Hx9+`chLb4#yT<^9d>Obwg_&K`M zQUr2Q8eJ7@HT6zfr2fZaIA5jihguhk1eoi;eNAhUhII)H42@%w04juY{_qSF z3Rq#FrO7X#e2jbF_9?2t&(@R#&0 zxvl@xJ5~=8$b$P}snh;UjVS^$<{Iz}MI=ig$K!6B2@r?IsU$OM>8gaNw_H)xTZ@~R z|4yev--{pVe>Y4Lda{4X?A@X_aJ$tYb~%_%*K7~nxcY=6CsbuT=kX6hzdisJH`(x~ zv2O579f3k*^%C~yv6MMqxx6+#;W}-8@H9~|C(=>Jqrt=M#iT<0_M_Ad za|bve`2Hy@q_3@+rp)bPra7OUh7oOH%;w_xEb#r6mllp|1L`1}Y%q?E?(8g0m@)G5Y zVn*pl`BoI>%lCn1|2?yHT-*XRY)B#X2We^Dsi9Z@_^5X5H1DQo{{!KKLH`A})m*SH z!P)L)lo%%8>uuk|t};r^eSvSkwXdiewInedNApY0)4hyYOfWsU0{kU26%x!@zG_*P znTXqGD((ej?A=`*l^f;l%CzVmHeDbN8MYVuq4@U}{vU&M6IUf4`8b~UaeUX37rYF*yF4(u`6(IAj7ICk zZMhFO*<~t+CUm#W^5*(8CvH;m_GM<4REdOgk%FuOMwZ9wXyWh-F3pT~o@Xfap=YzQ zvKCC23SY^CZ-3O#iF`|UH~x`K>Y0Lur=p-{jy&amWBfgB!(e@fzl>cIj293tZm#Ak zvk(k}Vs_=wiNuzDU@>n3!M{V2LdSb}uvc1F=KzaYvH3vC9q6P&KqqDQC%{C8 zFlqM8S~q?hJj}@}`_Yk2LKi_(r?=))qPdgiDp5q32)&%Bh_V!4UJyRhBW0V7oR2zk zjPJ!I%IAD;R*!}m1S04+Q*{l`^KlK^_3>yJ7Z2AFkXnvGwkgegM z9xFNCy-rJ&fEoBAQ+0qt0KZDl%xpAQQ;LJXJ~}oRyzG+~`T^{0Hgu`W%;@-3c~%|d zny25Mf~xWJmoI;X{V&r?|D; z_Hjiob}U&Irz}cM>q*}~v0y$O9U>sTY(K1?QYWL}n3q-#ynAX7RrWR^2G>huvJQ&t zmv?7d4%;eR5y? zf&kr_%Lwqc5d=0u;tapNYooxFG_g$Y`2;HsAX7AH_*~LSgCSq;F9U}*imsyue9)l3 zjHs-7=A20Abr$Nx;s}%nlsHN>EKed~!c@0dDa`ZC>nz zN8THpDivv4m2N#W|MlmOZ(R}*ks0W#lzzoSm7LPYxI;u_YGOvoA_7?<6QW~$Ln%b% z|I2WN=MGT}zQUAn$!2O&7A?LvViKPM1Xg&2i#Ec%vPyDVHpzGDK-84iiqw1oZg)QM zta@y}*|-qkJ($wJT0J~mD&UaY?BkI8=mv0+m@6#xvTI;K5A>u`7v+6)JU6!9r8cD; zSsxKXf?=Y2etzbOKdo*BCTV#It8Zjv3)2XN#q5QJ2^Ch7yCM0p8i`Fg#R>EF-^Ss!wMjYI}|L#j(48P29$m<7E%R zj_P~G@+JCu--somKO|}zT&udJ`fDG%nIl4$2IBP@Kgn=O+VQ>m<^>pmpAOr!>0uKG zlaAOBV3PTslSS1GKKg_$+57z=$xCDU?sik~*G$=|ZWi*PCyHwI!bC}!MBiKgbeZC)N>C)5s0RD84mR)|L%+Am9h2=wvb>x9`AdKD!^eR}A_vZI;k0*D(U0sE(Ea3?AL0@;<9jEJL*fU)eH-%C3EbveObB$ylge4mi334@GIp=Bte0_h!?)gi zc78T6f*786e=LN=Y3mhW7UJ<8%oV0ZFywm{aqT` z-e8YbPM;nAFf5VNQZIAKriP09r)AzO_}^-s#tn4SViuzDYLF@m1B#K+PnVnsYc!Fl zkR%xh8->xlf9=O9bzc~+R+-ee9(g53JI0^MMlh0Nyv?|D<|8FxXAcX}KjkwpaQCLx zJL)bYG8$moyo+K0L*aDcm}yA_N31r#{)Dt`dG2%9-TR2EWkt>HnOx0|rMT?vd)o0~ zV9ts}fr(nJU@OuvjwWrLe*KF7t8OA{c3tPlM+OP2OGe{AbX+E^v;`dzFp@bnH3=IV zM&X}~OKs@PZbjU^$;jG0v(X-$m7LARUaG&fct?TCnjr2|Qi5R{u=*4okvO0g(aC|%H9oWzySODwvek(4{r-zK*;%~pXto?BAczY`H zz+u5n{JI+>eilRe$8%Ebh=BpjOmtGeAab>U<5g=hb8|Fx^<>-Y6KWv0LXFB_F*DZWMGn7tjF2U(EZIYcVFo*_}JIr@wd!uPIc@Q>VjjQ*iIAXDP%paWAzy$2S zyUxCs>FepxXGnX0J&7B54$E(OV5k1QtM|z-xIX*+Qc(d4I%z>f)$iNGMYD!|3;$JO ziFX(X7=z=s@8N%4=bf`i&ZuT=JRtcnFm1F9h1#adRmQTw?J-$)96VUGfzNmC(cFW( zmCwFPqK6!XW0(m?wlws1bWD9u#EXC($Vt3Qd5I#R$=-v-1MWCr$+$Z0z1sCFw~@G#0aeI`P-02f%4pv8^sR=g>nxQ8GOwB z2)Kxp^8J+<*s`Dsm#ffh4Bbi~0F?%PY%M0To}Qjg^{kL+q1|tI z=^yZ2KvlD;r*?31a((lD-U=THodB+W9+R(YC^6VdI2j*BHAMD1Pe0FK+s5ztF4gh@ zY`r4YY9zw?u%B;Qdzhx2^n|s%lp@H>wc2}6<#lH9!b)V&RQypGtd(NFRxSU%jb9c@ zWzoM6v1Ek|^s^Lo23&WTkI&bs6(5}RA(R0(|EaCsEZ$-ZZc93p_IvbY%`$(X%lKuT zT2b@0ctNK}-yrKCYquNj_z6wl;@ywM=c!f&@ejw|t61K1sBm4i`hkm*H(SGWOt5Ez zYY&Jj#WzmMd)9t1Zb)!Zm~ZKm>;I+k0gP%RVz_ML;$?VhD zm<}#&DsO#eE$`4Wgt{oc9A2>5Ca}@Nmm=(?>F;g*w7FeV`a;&IrbqJGe5X$^*cgB z!Vq`_Bse%w;~qyn?2;dqL+;QQy)9u}VGx%_=TF;9kxGtvp!WV^0f z6cvj;Pbjy!=$xI{_-5!jp6=Imb%P>AZb!ve>b2b1ZGM%i$@FiZH{j+3UNi<)6?VXe z6t7LpX7elDmBm4#~ssDftL0> z<^AFKz40QxHYF7mX_mG}SVdaSZe(;pJyO%>5b_pJ`D^`JJ(Jt`0_!ycZ!p|OVz%moW(*5 zPIS_5qON}rwLqjnBhi}hb#iLUO}r0Q#lGR*1&Q|-w|;96mFlUl^|+A<_iFq3#`AH8 z-Ep%l*)n;$Tpq&WCPDIg?UBmMLXEI^r@%wj`jed1?mNhsxa`SdC*UfxKw`W}qmZ}r475O~j8Zgj_WM5)BpYiL`ijUTe&P}lh~^GNd^@x-UU ztSA)gST_5AoV|5amEHCRx+!Vt4oN|}yFrnV?oN^JlJ1ZaB$Ni}?rsF7k?xXik&wJ= z`+c5se&hae$GCe8z_EP?ynDTC&3NWBpIK*H0-3du_0oqZ`6msZih|K8s?6nU&%(w|d=ov5$n<&KaAu{NE=GvhXn-cp| zC2!tXb%R5o?Dw0aS)c{8%({$(2n#u^C)-Yf2t&QYP&;W2nCk3D@2ktJ)iB{3^Zbz4IrLd2C8!WKvmH#RDZM&b z3nwAOfPvLxp`&S#<3Ef4*-}c60x^5Z!mFoXKBT0K3#N6AkB`Ho4u{rX@PN(^8d^F} z1GsT+?JCsNEx49<*Y-$aKCAHlXb)5VA}-8E!gz74UXq=qnudMeWj?G~sFT%|CLx)H zC%wiVNjg>C_F09sDEC>ZJT*jGH7voC7(~sOs&nKqg#FuSN!YOau@!VYrU6;O-vT(6 z@LE1(vD>E>#ZOm`IZ3`-2F@GNr7X$o%k8U-&hOiA&DtXMn>}NfJqwSH||AsBF{ zH4bZKJ<7R0t29YwX*H}OJ#&N)V@QNdk1-H;M(U@o+L|ohwaq{I*iUpWcavL{nzauv zshmS{&~1)VCl5+W>eUW~xro(Mj^wK>iSM`Ri z`Z`4A<5rS?wPgD2nW62~f{eXZ^7}n8`467Lv}!_r-$E2SS|j7Dd1~vQJ&AK8VY9UP zZ224FlA0mJLR`f@VAxP!F9W6|XdK*+GVV3zXpS#h-IwT|IfhW3G$T8@NxcZigt)lK z(BD_Q#r5+g8ZOI@S=&p*JQh>?d{M=)dRDP_+Apf#nHS2!W#DM?!29ZIBa>w{*00$= zNP4PD4q^3z{WPEXPu`9dLO|rtM2`_ZaLkdj6iUSJzIvQ-hpbVm6#%++yX|nW$cRG5 zsVCwRd=UFyn^95vQrP66m$T5BHNdA*NW>*Zs$#)PAz_+%+#7nmF>JMj$s2whH2nIk zRtg&isTxf@i4qnQq3+##Cb&SP1{%pgNZ0GIB`lbhC7AKoVS}`5R&pdGlNnue^EEqG z#}ezEG`;%j(!4A<<|8W`LS{+x?OlR3C|q5cs%6*)oRk(o>R}1%~izD-Fg0&`$c)Df#;(m<>R@*h(i4TcHVLnm~NgTPi~t!GI0 zJ;D$%+7B_+`Mr)mrOb9Drbvvte=w<)5BCmGTc3!BM-;A|Lv6VSG7g3ZBQ=~VgVp9M zoJ!wfb;emd5c+C8tiRT(*LmCxjaRWwUUPgD!n$6QJuiD-P%fISaPG|P>Q?a!2aQDM zXpcc0gRCziD&oZNbHK6sp6C@TMGgu5Q`z1uDJ;00XqaXHH%2=YSeItfMn9D7-=!G` zNy(FLh?xafw=O*eZ;?EW=2m}ujmc&cM;3(Bwh$SO#cnAN-&Y__nDh(VLH8{@74;;8 zdaA#1&|ykCnJHm1C+_1G|CR!Dv8}H!75PvgJgNR&5syC?ydX-_y!c+@gRl|v?DS=L zgVzNcA3rPz1YgM&1qwx_JwtveGd)t|o`)rw^WjuV-7VGs!)K&LZf2rfRa2pfe{!K~ zIC0w*;I2WX{A5fLW36BGo;}0&I;?TOyan^g6O6AMp=jh$jvIZ(-+LoozIqk1WOrGc zJyp!MNm25+7QcSp*W8uq6-al9wpG2}3|a;hXVop>!OtE(7QRtzl%v6qU6g`7tk{s0S07FGA$^<7S(+Uq@?BNQGO<#8;a9tUK_ zIN8hxaP=&k1K$y_W)<%dj%12rg!RM#a=6jeST-Tylh~AxJP%6ZL+q0GrP$4Q8cOuzAM9Xd-gNe+EZQy$SUGjj@uIZ94$ z;tGG=*((?3$7CXF$h{0R_{KQ}u6a?f&fHD&_#1(vem9?}_6$^<+5l-4KIII`fk5RWEm7{?i-81oc52C)5e=`x zLpx!-XpYA}Y?kitP2FxJAiWiBrn&N0xQ zN7!Yh&>Qs~x_MhP!#P_#_aI;SNFGqsFvrZm7f_qcvzUq#;aQXG@Sy)bg{v>XILIc2 zS8(905*v?pHAd#W$BrO7^sA9h5XG{`<<4V`J7vJY?iZ@t!qF@(ePJFlYXy)R?5h8~W@{(PkiWAdv$GV+Mz zT}q|WGR|E%45dHaY9f~$SA_YR8h2z`le6>{V#|$AZ9>_ORFIgWOogv5m z@Zioznvqnaxv(%kJsk?BTj(`=6CEC=gHTAyMIH?#hgc*87=<^9=CoN;F`5gS!96iC zF>dmiB6#3jNm*Mnj${Z1_2oYTWD`m%Dp(Ms$C(r9E6~Adk5TKF z##?h~UUQO(qZPxn^?wtD2Ezg0Xx_;@xZ~11w&{|6ZbhP_qe}@B9v%rRMe_KGNL1m@ z8?(>*`?lfbuQuo9OBWAqnLnNHu}BhDn*8=&QKB?Om)Mh%o%#5^+~rc%K5=!6U}mHD zc2oA^96kfo@28qE<_%ps@8%_zCal zoAU_Ecjm7`&s8Gv2DdkQufH^Jl=RMj*$-&#zpGz7e8o6j2IF#5p?8DrX7OX~l&Q`{ z_2EpG2y+U@>DrKBVBf>CA-m3+B9$No=+hAx^M0UMoIzpA>>$~np{}j(P9+daX(q?v zapjyoI7)VzG3CTBoiqq*B346>QE#7d;+!V7YsH(TO$}6b=HA(&vd`Oz+)Tk(O39n| z>N;Z@YnvC9dhx6&K$S%92>*-Hhd+@j_$EOWIiM-4v1V#x!(`WS=LYolHm<&~`Ua?% zXc%7{%z@T)aTgaZY#f~T01~&H$TuEJVGoat3@p_!v@$LzaE=pbFDTXU*}E(ft~DKh zGf{h9N{(%ohh9nFiA59;9*#6iO&SN|;^LBBwTm)h*ck4-&63rWhZheIpeNH#f0*!y zh)`gc4n!;Gfty>A{+@IsbEvXLNmj! z?=1=0D4?x;JmZhC+>pjHHDThJdN!SUc3qxrBn^mpSnj*xHii`|LiKrbRXZC!B!D;UrdDg5rvRE&5*GIJcS1+o;HBSj{hQ>j60Jrqy zMGdTm367cK=r~hraeW^iJWThb?N>p}EDpObEc6Ju5@UF|+7%k66Y%;WpR;Q9A62sv zT@T0@sn*%=By(%eWmX@_8YPquxTLGJ?OB$zm?Y0LXz2Pf)NhhC`r-|0SLEn4JQOYb zbm&~?)1h^mjO2e-0924+ceA?$$|OZVvd= z=IOd?236b4>+QgD*HVf%rm>#{o)(RoYX>qh-e6CTaZ+^$fP`I2`VVjkl52f^{hfmY zcu05-`bfDOllD)f(9dXJzNykV)Rp0tl`)4q%mNeit~UT~&4G`N4ft*G&RKTT_Z)B7 zsB)<&XUTS)+{EJ{sXGt~vG@<6P4S;=5jDCEVeA@EZEbBG_|q%r$aY)=D8F$Cw4_0C zJvu7|lMDCupeMIR2-t{EJq$QQ%C~-bevT!5o#Fj%HVQ#jWu0zPY3q1IYXki?4=Y7?48*5>YW=@6QP%^9O<_oJ@$);vN!CCe#m5qI2nGwr^5h1vVh+8XFk6sWtwib+Voz8*=7D9Ct=0-D#E$h{8Oq2dm}kcmr4 z!9zVLAeI~b{PFCifY-v0jh^70WfYk~a7z$o@zLJk^)q9W?J4OyX+N;*OI5@Q@TpJhL`#5D-fi8znwy29DQXJO+3=0ONo=R5a4{ zy5j|{b?>#eT8+qdfLzK@>S_;_2un;iPbZqbby&%E_<;8{ZXP@AWS0#TmxVk zvs+IyscC9%@OJ!0?~8pByK;Zgu%&Jv^$q8J05zW(F>0lkc8U-TpW`gsPkO9zbd89* zkInUs-D;(oM&&LYP4XFBScZqJ{S^JhtB`R_jWu>2!b}53%tOT1RyoL)zAA`!xZFKRbc^@@xA~!L?vzQ2oPO&?>a$4 z2V2dGby;W5JyydPlBU#I<&1+IG}?hbG)iQi!&K8Sia&*DM{vVHs%a#ZF6q9-Q_@Vu zJXcw`*xR;z*z~-MUpUhz0>BbjJRT@mSfU{u@jh2&d~!DUqP_%#-gtpbJ+E=tDW2kM ztL7VnUF^`J2bc~HEsL_|#gIl?Kw3J*tTMRHnRcm zAH{8xD<|bbt)@ZVTO)d7&*!%m=$RA?-0^KJcL&gAEae*AbM?8aNzSHMW;LRh{bN2{ zd|U`d*l`a@meMc9V8Lwft85*y`KhT8sQm^F1biMR6o4D#xH*8QxY-BPF&)>s5%ii} zkmG5@{UI_J8sd9BU~;Kk{ExY?!9yM{>3DM@o;nmYRNdiP3Qd1B?Xu<%=0u?IczAgD zQdYM64r55%MIJXk0SD$=bbUQfcpMgqAcQEl-)QfH&DS{N2Enm0C5#4L2{SWz@FaDe zU@$3=sLY5kp9@Nf2kScJ0t3%MgM_)}CI^8B<{uG*ynDt_lY;#j;4+qW0y!eeL0Rtd z3mv$0uRQ}pKX%mfj7%O|V!&cQIqiR9I+Dh}^;`%nHk9TH1dkD)KYtG7us(WXQBmb& z0bn?RPI1jdKixA)+C>fbsXQTc0nbWB#%Dymh$6AiVMBBNF}pKi>PC6}O11Vb?#pn< zxI>l;Q{|}?NR1hWy$Dp_h?3YRB$Sl(RTreq%xHk2jRfvc4I&^!Q)xHCg(NQ^14enWT;MQ3VekQl5&`}wl3QL# z1rrQUYIstT2C0ZQJmO!a((L*O;y#PwVp6)4vz1fWk9e5=cznE!n@y7OUK2>n`niFhZlNX z@G4GD+>cvK)Gbm_YRK@_5(r8ijmbc7n5#1 zscLop8$@_>o1Gw+w|!T`7iAFY#Bgy0R@ z1fb?2!~3VqEzn8n2c^&a0|VWkWfItc9unwHgc`F$H}H>9XGq3H zgHn*Hc9O8Icb$(FhT-zqxbFLB)B*y;pqDK?Cgz2U3)-R`(JReQj&%TKXdux~X8~R# zD>oMo1lWNTov&+vJaW&jO0g6S*nMz^WQT7oEx8XS*1`efVfz$x9IZ>8%PhKXGu^Ht zGO~LPnB_&P5q#%BIuupN5Q-=-XSoH6R==9;a_CJ!FSZ8|B|)EnF;i~^?1O#BYC= zgOIZa_zB1~IrfVcNQl1_lR* zYakF1as9EixKw{Fhm;iV^e^?a`Pp2Z^Bo|U8)A63r|EG})z1ckwBFucAX#JjYiAt# zTqlcE*}bnEXmRTnu&~y|q|81W7t)tGsn*U385ht;VoKSA3A7^D8r1{UrM0VgQsFs} zh999!-+;9Qa&g3aB&$wMm_$U#%DCgeq>qd!fTS!7oCENJ_>aUq2DRO;*Q&4z;+WvV zli_UplLFB@qMSE9s)|CBYybi@j}tJ#AtCb?epKiT4J!KpP4TLk zpy3&4i zh{#SR6ph3z{Ee-3zn{-30SHUbfV^2BhTj#M)AkR5@!`kQ^c-PQ&JzY-Sb!!Qh(8e9 zIb(vJJzmA1Z|v>+K|4IV&$Y|{YwMm1>I`a?y~X`Q0Q$&jVFEgKuXYvvBB4itSF0d?iHP8d>rVF2@z$+E*;Od%PlM82;Jctu#^8s>9d{%UP?7_u^gXkn;LY(c&Uq~l#dQ*ul-cCeCOkyy1>aE3 zKhVOC!1wlkAX)d`6Mu=qhiqh5Qp`tip|@8Gh+$DNGNNwu$4Y}hy1BV|Y~BCuCzG?obIM=)wNRxwPg0W%htrtP$w3z(7EL1(NHy86`?`e>M64Ybq70phW_+VkLi&fCkxuq=*ZT8t3PTeLt$k=&n zX{oN0*88O|#o`|;uFU#9kkzl2&E~(TK!9Ean_|glF2$g?hDduJpCM!8;{m7yEUVBE z)9D9N47qS5prrsO*a>d2s0cY3MD(DB3P?qiGT49wX9fcl>ni7LG8n$c#5{(kvhGVC zgSNJwx_}dKXGJ0)ATZ{z%K>Nr-(Tb#fBzwqBEXIMSQ;LLT~kRN(CYqSdODx?729KS zq2S(L8YaCHpGEf-I6#AU7?iCm0z+;^3zpTLuZ6x#Kju_Ca)pNFpbHulajO7%zErp2 zu^YGnc~4LNBxc=EplAU_Q-P9p1Ns?QF}p{=jq{d%?=kIw*;u!g|1e1V#NP)vXx01yR% z5ARQ0-@Ig3r(dDcMF;2#%2LwOh!hZ>@kfBjlRObof8i$8-`9nY6*67#R$K3$)w3H2 zkCnVnass%7{J1hP_YF4ubYpF~5m>Z|N{`}mS42F+r(5FnJyFGl7d0pH^y02Cs^ zCJGe)W*neb0lW#~G4OqS(i`FY{QQlbM&Dzwat;Fegg_dE+IY-!ryp~1Q35Rzot*T%WA~O~FarRDMn5Lr z^Ul#{XbsL@HM{#(c#KfaTfO~C3~T!pENG#E_=8@abovQb7)3Jp(d@o~QgmAo2v82aAN{9jHcqv~agxY;=So z?g0KS`Ip!S1~;(v3C>S@Q1V|r?J%U#bHfo?|5g~VkL+l3NIEdriTHtJL z5BVIjux~DWV6>A?PkLfOsFnfjJ@u+v6Q%V&D(r`GnOzNNmxvLF(LlJ}3&cXALH{Y} zq2s-p@w=PZCk?mjgPkC39-zjtW*i;_p8g!eSoN8Xn%a-w`vumCadG~Dk3A{$v2e6f zAIt~{H+N69A5GWl?Azc8P5P>7&u?1S3 zH%0_4x_1vGzzRWD0XGB+@llx0R$>vR^5a9%->DK?KG!{(;u1xp$wDrnW*ee>g+U1y zm#6{;b=I-ps9dq-`i7b%!41P&6s7P(cpm_SuGK`6vVyAqX=Y&yLCN4d%dZ-0I;v*# zU+1ICl|{IRWn#E{q5}V54^V78TfN89G*mV|7#dyQUY%;Sda(Om)MT#FiT*|=_gIBN zBj!Q^CJ~%TptMNHqF)@uBp3ef9Z)R~q(Fi`UmHEr94cyPWdwB39IQOxfi7(T70q3J zQ}hjNIcmju|9%{#h?R5QTO|Ti){JiAB9(y5sA(ieiE)Bf*GaXO(F` zMI;rNixgXsc~99F-GLs@B%VYITq;ta$1C+FshQ`~B_5t4l`UUWBJB(?vxe;e1!!;K zr?c`Q2v3VOWq+33V;PjGN7 zMKoN!t~b~pbuQl#8Px1@V__*@A*U*FQBuM{lr%I#fr|jCFV^PfX2x&u4K&F86ui6r zeMZm7$Z1nTww=r7-iU|c$Dmjt6fq3~%n|6{QiJg*munWHH$;CP zWCUGCC&(MHKtcurVkmu>fYqRPuEqiy^ngkhvTDA3m!jXb>W|G$D%a|{57AAVvLouzQlVHIbLPLXwPgmay2A-x zfLrJ(OzhEG+=%IwT3u=OTb`z50<4as_mJMuKIMe7RdhJ~p!>NT)y8XeZC6w(S`=oo-eLOzIAO@0-+0Ff99 z&l8Hqbe6Bxr5a%>OukBkhwx&{RrJ z{v9BM_fFb+4(xxo{l>TS*6)6rmMUlU{GSv2N=~i^#3aI_)YR1MpySf}*lVTdvi(vR znqGjj;agx09PL7`7;d42tF2J=(dDBYNSx5wBZPl}9FUIHg8&1t;jiT(Sy7Y%ZU=lq zSF1v$T2-(>+^rkB6@>17O{83oNxmfi44*T9jmBNnQ7q)rd-G$=IPIi1Z;D*C>ONRN zbYHzy=mCCOajNdiR7L9huztAwa2z)NRqyA0z2EYmC1m5)J~C|c+&Muu`yqUUWA$1% zBPMl{yBcCkz zR%n!%dL6NJzYeap!%(y9s>dPvimDfC#pY@9NWo@dorqCgwaJ`B!Au_BS~3De`jteg zYN}dVNDyF-K^9zBmt9+nYcY~04!|i01xU%jXl3~y3ndf6Z{i4+p;heJ|+c;yu zB}k%n{N^O-wNkt;aS-x$QKMhQFf!+m`z3Fg^h|z%X{6QuzYovBjMm_%9EqySzSnbT z5soka&2e+mSy8|9Lc^Z}`C2%C2WqX3Mk+}+oQ0FQ2EgI$8bUn_fAYrYA9_aFZ_=)e;jQk)J8d9-Y#l2G*m9eqk^Tu|AYT5!hyu41;bC~H1~VH=6KCADt({El~qqH zyo~nu#6y27r=Z>_{kkrasA@8)ZpYocj&rhk`aP?Hv`l)pK!e#PRk^8cmV|3Md3|Ew zb#FoJc-<0$QVYTJW`@aPlRSNUwvY5|_#Z9B4h@!kA(P4Y)JDeEKF=cISpETe|4n>c zoQ>&=HB0IfrpOnpeGh(!oiIgzYQTXw#%W&8>ew)>3dV zkk$5wBYGJR5AqwJiI_1}0;C2)oVQ0ns{a+B992Lt?d->XZaeOC=>3>^b~;o;y(W9X z!l`JH-y2I?ILQCWW#e0jVwK}*Ud9Li&rYO53iSNWysI;kEh^ODQ}U-2{Oj>9R13wY z1e}HHf5YH^fDw=%T7h`^?SxU@4s%4}-wJ}X`;=ShzrI&%xUezFc?Vjxc;cu@pW zq|hzJmv53@_W=81rI0Co{nZ#SxWT`86`^;kPA{q$q+d@5?&E)|CDQI)*pkXrd(7G1 z>o5ZCgnh6N-yf=75KOQ_wR!3GVL4u1;WlmY_tLM8oF)PaM9lE3E`aD4D1-J1MISh7-A z)Whvi3^ke|5a;9i)c+tQCcxUw$k7`PaeybC<8X=baE0P)_$$M+IxhejuBvS3^5rWs zu#2gAedy=E_lbS5Bm27!2qgZ`uhp%s$kPfPq2)(NbI85asOdL zfyp(Q`#Pwai$DJY({p_X3he*g%gwH&-Y_^+_C4K%ehUx~AOOz3co$ z?~e*Zdq9o|Zd4E~(sfh(9;>p-U7jb$pB)XpDYMQ6N>fo|n)?d1ercr`=YBS4M7BD8 z;6P~~bnMdXdP2UVZ+O31@lx?g^aI0h9G<)W7ag$}^=)Bb>7D>U0AN+&o}71&0aL*D zNX1&1rEWTv4(IQ$2Pn9`dv>nsoJ&V%)_R0k# zI0B?{tM!f>LkY~$Ew8kXoFs!hH9C3(|Mv;n6@GHcvP%osJB#8##*63_&W4Y0ab6Q1 zqZ`_Yx~3iMdpPd@U-O_Gdw0Kvlqoy5B1#%ic*?pu6-JGD{)-&qb>i~blV4SL`INO& zaA;e+l}`i~$6z*)pr7&V$y`o}fbbRU)17Ib-pOy5tEde`I(G^lYe|G+Tv_qx3O~v; zo@5j&nGcOm-I!%5_gUE*d_?suSt^7mRjF%R=zsLpdu}c~dNE}CYRZw#=fZ;g$wZGK zZC0?mNCNwzh~RhTerfe$ZS;vrQzrJBer1Qx6&tQF ze6*~&<+rmt-GZnniqcw8u6Z%&;{B_Z-Nt8kA-UDo7f7+5>=TJ}?UsGE%Oo*0+h>aK_x)}rl7a6hAP$M%Q$)kjgN zqr@YLaIw=(RW;+SS)$M*8y)G$W5ZZkqF#?ZT?SGGTM=HZzCBI7!YYBVF@qAfjA-c2 zZ@|;KYW;F9w9#EtvcxC2ur)VRpVv7u;~mu1?6d5ZZ&aTZdWfwub;vNm6lm5XysF+X z8Vwu1Jj18Zx4&hC%VAKVmh35xtS-mHSM~PENt#X&@%(3(NRa;&>p_I;#uz$ZTS@`?>q4&57Ay%jj@oagzThSWP(1Ym7@C}Ck7_!g> zMu)`PVYk)-#pl~?!LF(r;gSrv7!8)g9gj zhq@iURF+BH(<_^IMojP%NqhZYa8K7&VECRs3z#HAwxFbNZFIj+D4Aps9Xw?pPV_gR zee$i-#$ImemkmW87GK_Q#fSGC3T*O%>U7lRIpHqhDcq0wybMYj)w=5}^DQl=*w|`q zQwuk;S-d4KiB%3gOpA>4Mn3o21G?^kxd*o9sXNe^pkPb&^YeB7{3eT z-S769W}jdoIBehO=(#5vw$cL(Q+d7L$?Q&XNk8!@4uyLLQAk(r?v(ET26nouuF4Z% z2AD(!1sKj6SN0dh;aC}~a@|F8fSHBE&N(jls$--OSO3aOfvD!!7p7yb9=?1^yM@&> z74bdQUE;W4)nuS?g1>+&vD;!rQLG_mr7-oalf9uz_`v#_K^m*3?;AbyrN+gzkACym zZ1Tg#=rFdw+)~&Pb?EPM>mLuZrANDyQu?c9#CaW0@5@z-ozh3s_K&zP4Yd>K0F(7L zbLJio@VU0;8qih*pUHD`Pn#ZRx*3D7+@h*wq12sx4V63EdX1x6?>9peb<#5D$)UD? zT?f{ANJPWU*>~;)4{RF(dEiV4Enk%qNY4nx9YGA zc(Kc}5+N#g+RD$K88i5MsU#*<;w8o_k{Fa-pPg~aa{s7h!umSSK%3~+ysX4pYrCSw z0f8A)uiDGoS(tlEzHBwBr_UC}QF2B~UV03(7xDQs&28q&Eivb7GinBg0il~Dtc&b7 zUS1@!4=RD{!V8Y4-TZp34)|ZZ>T`dw(t=VbC#%ALjHQd}TnBK$yP5aANn6ZaXQL0K zfLa4C;$?L+CG&2sP$n3Y% z^1X#!)BT1j&)|aK(n_+fIuMzP@cP>?<3}9qU)p7r@0a=4dkk-{3g#E`e-NQwE4}wj zX?ke)I^AR32a{|t0em=!j=uFAfVAGo5H=&RDBzB9R*xF1z}(t)ezh2V!AK?NbwZPk zb;p@fFX$Jbq{e>2>94ew#sU{SPQIBw3XtdRSR87p;>3UC@1f<>7GUWHLb!P*QNc?|=J!(rgm1UwtolPjs~@y2>sT zlkE2~CN{&Duw&-6Vl&w;AM9ORhH4V4_}gJo(>c^@Ef-XB&&E`)I$c#ZOChDRL*9&M zh=y8k2OCBY6|ULd`S&Xds)+TC%(#dz5)q(W?DowA%iT=2<*H_(=iyd|vp?DS&7Rii zV{kg=NuxUI1S!@8v3YAd#xjISy*K;?QN?k>D`xE}+0imPwKuj-Q>&FGB_tpopt?ft>}f{;5JM+2*Fz4 zH)arS?*7V~*yFX-piNMsOcB|z6RJH?jv^L*l=~vKOA__TmtREgK%N77!R%fCrIM;M zT7Zbb-=_=;$zX_6M9XnAPU^A`0bq=DHiP-@VSZO|_jfC(RUW4%X#%b&7>j>5Dbu2rok}b_XvZ#9Y z5L%-(l~tc5kHi$)9+G#hjy>A0>8(==KWq^)7%OjT`_a{qwN#2wwSDMq?TnE+CoSV>QgK2+#9xOxs+x~}Js=?5Z zh%JP>L4ETxy%tw<*}}`dGuW(-MPyvVq)~rPaOBFHLU$8WT9D)EBOQD79?G zE2}zr_PUPs{Ot|=5+#Z^20e42s^}Sc!qio zz%w7;P}|qR3mNxt^>D0NpR?WzhCU_=^kZD~r^~#5ztaD3_HgsCF_8GWRQnDURC>OG zo_T2i_+g~b%Kj%=##1^|Kl^Y*cC)}+C~(27^C^`goT@LTjVvMGj2cWLYo&*PCR>~p zQYLBjsfIXOWXDrvLiYulC^GjJPvsnubMrivGNDVm7Eg`Li9Wn3&FFtps-@EZ@2pe5 zCiMC(kYJ+(W&MSE`%5CYBOqVYlb~4I+vvDa*>P(P3^L&s&UpkUi_i@*+u3hxj5eh$ ziDiou^y*0;AuFQK%P2IhXOY;GyFpt9GpRGx4G67>?u$nfKCS8^g~UT zlv2;XWaTv>ZyFwQvQGO=;pXnRf8n$AFbIZQy1=3PoBie7Gd<%c!o$P6+89X}3804n zW*r)+NcDs2lafmHj8H25kc`JR=e}%beC!8}{C4A6W~!7bcCUbQzRI<=qz=S#9C1vx zx4-EB$x=T&OQ_(-M5pt)Dc{SEiQzf8J0thjzbA0vZyBl)Zcfv`YQANiz1bE9iWQur zNAL3^sc`Sgl`b3cB)&3u+j$HRY&c)c{pa?YjUS9UR8?|^jy!VB-OKRuXUl}c(V#W@i+x8U zX-YTs$yAF!iVD!MLOHJeb{!Se5m2GB2waAi7xFW(ss%Nd3zyjAu56_FRiaCUgchVL z)eVU@N*B&<_2{hEWYmc}Ta)g`rPgs7B9G5HI?xjGhx}=pPS5XIPshv4_`J4oM>60@Dy3d1OcHx~ITS4N=v4|&!>Gj9$|Mm2_ZY}X zdNIdnHXA1&4^fb5!f?W0FsCpR)O2z4U%%>_P!zVz*hH4n1)K|D^KS13S-rLr513&f z@~I;F4Ud$c$kuH{2eOd{Rd+!D1&dg}`^1MZT%x3#sj~e0;gefUA{^KLr1bQ=%dLpF z)l8B}=AdqQR_ZU{bc|h)Wz=S!6xi{`_fj@3N!qRN~|{p*IzD7eCx^{gh)8G<6*g z&V2Z05M1;H0_`6sZhY1iZdkG@5f$)JE;1wM{CVw%8LL1XF)l;>_kq~S%wH0|!)N9g z1(1@=UzU`vQ_J}wt0WlSQsvO)O)BJp2}V(L_rwaVf7Ap-sj#i#bNHNNyLqUp4CLyd zM)CCLpkFK?Ypww}#Sp|xF1k<(*^>(j&ORmIi;LcKMF$C7GP0nL?wck@l5#>5TOzga zoW}#tU254|v)vvTtQ=-6 zy~|Pk*sRgkIWF84Ydo)}Y-V$LqlEv-M`syaEN*lG&d)8PGrNvx2?-#&1_a2wgg8`J zVgKZV`&q|g3gn6oV>2lnjAr?Ba14WX0Hpir@2fWD*kDH#!RHQaHF zYGQJW>j{3rdnl;?DOk!rG4H3a?9Jk-P7p=Xc@o_t>9gUrce_4HuxSW(mH&Z zvr3y}#Z3)qYBCj8#K~WZJ*^t%bLL24=PPkI(Is5Cdpgof^De2Or+`ow7BROd2gwh5 z^0Ws|qerF?i@y=3<74PqiY3^Q^}aTibh0$_4WQwIII|;m;hRp@AbrXB{-F%F2IQYtXK)o3HS=R|F!$% z^qce(pxUz}Bq(L-7~9@_=KiIRf|LGwOffMoT#GAP#t@-c!}u*NwK2um+q^EeDHT(= zPvcR!UMPtWO`qHIQcv-Brl%W=$;*eheyRR~epwi9iTF*+zn5W_guM-7LwY}^a7hRs zStF(YH5uX8f->o?nu4O7?vkXY4{_vL zMpAvgMho<8wMg9JIlGkkZbUPN8M&0t^IQ(pY5w>R4tlPcLl2bRD&ClDU&uEs9Du>S z$2yOoApayMD2hhraE$F4wqJ4T=rS{4-C;t!-A9Cg_DpVF9g*MlkJvUPc9i{r;prEq zgR^~);GI9eqO%?&PK_CF9*{Ex))W=(37%Bp$CO}?$((66-#05tF-x<1m-DoydpX`r z4OWcuf1jkwyA&=@4jP$m!-s1Eh#2VMRG6AxPf!#EXVU_Vks93OD3bvfXCsv;xr|(H zQBzVP7buYTAEh5}?Emb@8k{pXK!coYkGc`f_uU)cJXMSXjS^A%eoPz{-=l$_EZ4GO z`oeo1$03Z^7t(UljL?AnwhN0pmlf-79iZ^+EV#D8$BQ-Mv zc$3bM&Kf|y0R#k-jA$@`aqR+m<8;wklpEM5svOKJ z1~zf>LP+ikdGEMAMkkcM<4d9QDY4^&&V7*g**b`B`YoOui&e5K>Y z3-ESM++>gbJWGEAQjcpVQI|HU|AwL$cGU|9V7Ciw`T6mG z=j`)@Rc7Syj~6`_2cLa?{n5G?hWA4s{C_AOpne0UT68~L_xttU|ExIec-YN^S~H>F zfW)~Gy|TXAC25QqZr4Tq9?Qe*ou`0uV|=Au9qMr!yW%k!w;;G_2eM{eY~>1+1tm3{ z|2nQ!2Pr_zR!Dd*E~V!U3pMFExu!!k|FKlz-Sfa2ovb|EuvTtfKEJy3W9`Mr^n4Wb z2!n?e-;Ml6l0ZPB5Ic`e1qA6<1hPXDH(JAw34R(lX7>qE$B_!w*4OpZWLO!Y&d=o+-D z4}Hxb_TvKGMA{FI!{x5><0lOWu~H%ktxF*o%%KqOSd3y})|NZ-AGbOs2;N8l-+_t! zt-TFO0+ib`P)Ns@)H8&;psnn67;4Gou5V~e%^H8>={5VEiiFZeV3Li)-v2|}TgFAz zw(tIQBi$f^A}!r1ozmSRT>{cGgoG%qbcZxUNH>y7cXu;%H|#au&;8u@-oL&7@BZ^b zMn8kIX3e#(bzR4K9N%-2;Amcb+3hqj8_*Umc*xvlPn~B;W1)$$5wln@;oG?UITcJ> z&S~fB_#m8Dp?Dw3s1MuGsMZ#q_z2Gmn{J-c4mNEr`1RTsAG5@*iMeJVvTb^1B)q9I z<9V?la3PY=eTt%FP~`CZ%ADOq_VmvGww%9p_NrtSv|lZ(pWnzQJk?XDl)1*4YSOCI zL(u8lf0=%KRqZ3?K?xi{IvmE?)S~O+@=Q;EN3Y0^h)K(3;kBW=U#VP_`M=6xBLh1* z`Q=y!BO^1xk%RYF7B^3Y@5?h@%hv*M6BESNyP~iFYifp>pFZ`yeDJTp^F^PrwfC-Db6mN08<0(CL6 zvH|sZ=F4+TnQvVt}-&!@cD{}i;!0lgYO#F6C6qs|C^qCsPIU%c#4#&QGVbjiUc|n^>xz6GI%O8KIX%IxZi3ll=;F`cE3~S5jGKcrO^is_kAZJ%i^I>kc_khGthM}y|){9*YTuCyuX$9 zV9z!ChA(n>QA5P49=boCF#CA=F`BnPFA>)V38F{QK#otcR~Cj`Z}!Otqk>p(-vP(c z`bkQ-o+-3Qd2G58rtZJMU|>(R6Vf(F`=mNZ6dc^<@$$bKGM-vNw~9n9+15w`$I6aK z;#NK@+xbUVaifAYllc1R+Swhj^@PuB2bgNEfShJVv1zL=X6wFvLA5UE&9foCzz?=2 z+dD>+qjF4Mmux5LLF(_nh|p43@7M6xG%`iEo=BeM*q)oV{U{XT*5I%`*SHBBw@ZIS z)5Io*<_4v1L`8B69b7^TbEz`MX8Wts&5rIaSL7=NR)w`xr z6XVC5Avu1`C5%PWM3cipL5ImlGKD}JJ64@duCqmD;)tiui_a?xZYdUuqv_?-+5=wqTzEMs237C&-y{WLpm~;} z!k5Sb&oYX-o<5DjLC>I$XDw!BEi{i}(#pke;m@n;KBu^HQ=9>2E%QD-MFDpn_6hyI z8!=S6xV-qrEa=KT4-;J{Z{@;1y;dh0xN+5P`Ec5{H?C+}EpKPM73uoP%fAl|xNlo% z7@M)rCIA(p52@j4W%VD{tQ2%>Ut|CJQ$)GOOgS6pp!8@dt{Dp+#ji2Vs33B1jEAFi z_0i8o=yln3_mr$ZGgD}T+DJoPDe)(-tLm_&+J!QHC%R`i6_EEIe<)UJe}m>ZukuW< zR;3jTQ&K5rdy@@z;_b_AGblpw?I(9``X=|HvG!dRdAG|dVkY%3_3rInxvrd>f3&c0 z7;b26y;Id6>1ALy420Xw{gPbUXwzx%5yIqK)Y6Co!A+{4H1ynyP^!-?% zU`IDUwMQ3h521fX_yUutw;+OAOheBV$uKj=W~|Qp_5Dw(r@Lg$waO>Ij5gX_*Ur{B z8sH(TBLudL``Y)xwitLSEv6k3zjPrEyGEwf^#cw-ojo3-V7iE!4L>p0$+ZZjq^wN4 zhef&C{M;V0UrgXtOxMrp#D`nWIp(7D+cYwtf-Y`yP03c>axVHN$+1Kcjp0bM`HSZX zI{a{i-Ho*N_P(pD&J4RU-xDi%Df3&yj>Htl*f&*P27P(6$K9s@0RdR_kQ5j>L?bMk zJm^vl*`gQvBI<|vI8_rI=6m);DVw~L4On^VlEdBQGtgvSDj2a+j)TWWOgdCOc~dvX zWQ5@ZED3$v#A*Ro3M`WIsY94KbF+ApQHrmOjoAp!zuseR09Yj2IB@;()&PrRxOYf* z{@8`^)Z`?t-^OP#j9`BciRa2_y(p4prlUypq~f(VupsgV3@;cmbwSzS zi&sPv1@`|H-+)n#p$A-_XA%^;el9u!cfcxceCcdPNPzR>&;RB`VIv~OSR*X_;?1ch z)DAo;ny{^%9f3`5OHr_BO(p#y=jZ{Ot?4Nry|GUA@G)4DaM62Br1zp8=9n36kAnG) z7)X^N;u~t{tPZr<&*?x;mKhVTLgG?dz_0!pZ@@FgH)-G4T?zoe8Qu51@&)Mm|6xrk zi0YC;aG(-@7ZkdJC0!;2oT-05!1j9#bU(qizdW*fy1qmyBqL7 zd|Lm$2?7W5f3tG^f4^izS-xGUj6bIKHRsSX+J+4@AWrbZD?9y#JP;@XA|-&~={qoD z{^NK<9v_`0J`t2!`S}0(a{p}y1HRvX++P4DWm8_tOagefx(e5F>^bcUnW9$MTIZIL zx2Xb6w{|uH;}l`7X{r*KkISgJ22==Dj{rYI-fuX6PLh+F-o%>m020@JE<}F7BvAId z;8Y2>{LkKihb31vq063PQFq;EX=3la*}3Rx>rT^LWontvfaqY|(Vksf4zl}tvL#t9 z(Q=|lUwfmHziV!)2mH|WoK@QPqo>pBe}=I!kn{ihk)852l-}e$dusi`ixPwV&IZoY zvuCN!EBEFIPbY#ukHrg?L&PuHO@^F#7eExm5`TOR9ItYN)-!&~$rGxok?Ehm|1H~= z(_qe!hz%@^g7Hs3!YPP;4ftcW2s2lu!(bS0%|p=8wMlg9s4{mHZtVEbZ}Dm!;!Zn+ zJLzphv*r4llIxjSm_X=2MUH8W{})J}Td$$#eIkB&GNPJ=5a0^}4F%`;`e*@cq;QWV zFiCK5u;=B12Mp&8gYew<1~+&c)@eGWQ~m(37^{F49-bNqG;o*6@X0wDd0-ejrMk8Z zg?gJfHSztmE4gX>;}WvQt3g)m{HB5?XM^-6$to>Ib(Udygx){a9Dh;3+_Tq6W{zMfO7j+2@v(}Y`bc!HRU(g*eN{o<9cLPJP(;4R8oK+lWPyqt zoJqshPo7JZr3k&#P*)nOp4u^zopI{5A8A;vQj(CSeIGR;+^}-va61pay;uRd z#-0mj@H^954kTOXhHQJ+i|)G?s~XmkRB!&aag7%9DDh%C=SrYR7QR#i8Df1UAm|T6 z+5kMeS8LRd*6H>(BiYiVobN)tT!tkY{EEM*)zuP*4z+*X;ED~BlTGsw^r(D8KP})GTris9bz^+4|ZID^BRt) zw0#b{pWFR*=~v-fll1=a5tapO&iS7Kpmz|o+_t& zi>fzw+jrgVQ$2f4rwk0tg6o~$U^WEcplEp=-;6wYlM^%jW~ zu>BtIotXYIp1)C8xM1@eh2HoR_R!CLo6BTQ0~@?zv8NWvhu(8PUaUJ{kE8G$9q$Zv z<+v@Hm)r8#*~{C_N4g6mGk(otEzXZ9nsw1q5o+Dku5H;eYHygpR~Na}FeU)SpPr;r zgU_u2Q&bbb0Z(5uWh&D z#|%I3OXnWd6QwX8PgKuunr+J%dlV1vX}^CybbanpY;1tzmq9~Qz{Va2xc&)XfGzYNT6JO-4(Lu9jZP!GMO~4Y^QZQk~Qz5$AwY+qp$RaN7HyKH~ z(SG;L%;GtQrH@sD{d@A+SV!h^vlTkNlYUmisQP2+c#l@M+xcGxkRZ858)BmHp7~$J zgkb$z@Ayjo76-+Ew6g1(a>!i1PzVA=9#1dBu+|fA39b(J54Rs(gpr3Mdw}vLr}0vz z?={8XK_=YuoK0bWDbrY+n*u`ky6<+oK7d2A76CJ(978}0 zw%2&mJ?LS?Fim2rSB*dA`Gz4C$qzM{3}SQuq;26tvOg$(mYw_x0wTWV^4d+Dg@7~s z5u*e?qW0)=Yo%>Jo*nedbQ%az@ZxoZV1>->142dY>p&DUfZVqETNI#4#iUX`)p~B@ z8hb0?_a>P$s~)9?^#||`cTK&|_>{5ObdV)zoYSj=wv+~z@FO%Fwz@*I6yb(=Cc9I#uvztr-5z_)(vlyJCq zd(5dw2N6&5T|K-S|F(}C47u{`?6~t$5h+rsf^&8b9b;1jZn^Nlu2?mOAyb_C)y8xq z#FqJ5PG*7MT+8f+wmSI@72+6wOLlGW?$(XCed<7C86_Sj0VEGF{qR-u@laJxqG%Zm zLa$<7$@#L z3vLN8=+e&TbkDnCM{VZcoE%7CFK$~gfVX|Z;d)oyiro$jv}z3F3Dx(OH4TTFcw7Tp zZ^jtRs}Fdtk+yHHwQr$B_>;{q%{$dyCo0Nd76x*Q@rctgUL6X>YL&=u-iobQ(sQ%3 zf6*L1{|rQx#6<$ICg&(1FNqK4bW!p;EtKK}~M904oNSZoF55w7<;O8_D7}->qV}>V>~;MOUpy~ z?*0u|;Y*E(R~CFrI*Zhbn?CwtL$}v?8C!?Oe162xjNRHCht{IHVFMcD#wpjblv>2F zwW-$Hz-xQ@2D4;>=x7wU>LbFiNu4z*Ox%Q+0I81l^DF3mEv#uEMINB-$E<3m)qWXD z2=Xwlz*u^b+JK}IoE7CNo~GrNLmrwYV3q9n^(~;oei2myICP{uq)^gt4^eDd+R4SJ)Tj+8En=*^G8WV*t#pANHor^?35_``27RA_OnZ^1O zjD_5&VYHS>l53m^D>t`Dakh4IO;hi}b)ghZwrg45l9G6rO5?$U-k%$aW`N3P(%eY$ zrkK8!niohpR=d{9YFE<552);yhBruUklzH2!evI}79qD2#@}pAjOcH@e96>$1GII- zHLYe?_y~=f62Hb^ftUYHOq4MYH|_W&#+Dh}W15qqpstP&B>Pd-&hA5_0Lc`%zXBO% zyL7iTEv;gBurU6&@Jjr{I+McL!UemluSwpPmNoinpMXJ<$JPWyMvTOWO;|6I4H6~~ zc&c0-O6Q-R@owh|>=%*NvNMs;3*9)$hsH4!7i0${c{a)WBMR z{(=zALlY-B~Cc4g%(7;D{@kR1ecBq@;xC-%JbvT#*5f11SW}bN!oN!R?5-7 zw&|1I@lOJ9Sg^eYpat9{cZ@6+asvL%(~nMlvs|y5{FH2{N^nF>#8AXr?IRbi8d$sa zCuU#VE>bA?7@JQNX^?qTt929iJ>&3H$jvJ};r9pnA(01YQw$qEOyi2lUM7 zxZNDgcsqBw=^2LQdXha|5d-lq?F1FA_XAJRiQtRm7=;bj8tX3iXR9%V-1h+SzSwGZ zFii-1jGQ7)tZ!IiBnWAP?YC2$>i8+is;G(SFyu94o8`>6f+)icwcC4^AbA#zmnZSy z8+ZTjAz9xC!*J#F&l}hJbV0Mcjt9COqvK-ORDy&80-}$cKNmcf_OB(szE^A1xmOx% z*-`GRv98#`_Ob1|p79vy9+Ym`YQ|CVCpOHqShq21c%fKm$XEL+VyGSe+*STomop00 z5(31G%B{&9OJ+YFke1e#gEG!%t0$`Q&yD%bGpEPwih~o<&nL8VH+^IQ+^N`1=aN^vOY{f8tWUNWu(ACs`rkNih1JKFf`R$mXm93CwGMP=h{8cXRqX0C&>MXp6N@GDEog|QT*_L$R<-+G!;r&1*o?!mwkABExw;}4aU>$k4XFUq?X0pp zkM-_m{?PoW4d^hulb^v0?0RTv-Grt4ikkgni@krm#@$~lHB0r;%%H+5mi*tnu+aHeI8{&C6-TIuX^7_%}Zbl3r#Gz z;r%UW>tlRa_hS*vqEyu)3by5sMp%wr(T5g&8GwHufC%WQ(FpLE86Ku7lM>hAn8<(R zye436tT4B7>9#hEfG;YxM^zTrt}|_v1q75}e8uS&u+U(-2qqkW3~Mq=79gBx@oaM0 z_~NLTH8v}M?evJ^WKc*!C^wlvZ07Xs#-i^e>FD}C%2B|^wW=cf%wh0@$&-{^3zUcU z2uE^lEn96Zhm{wicApEIRcX&!mqYu&TLhi=f0hOgid;-6{=X--* z3=I{1mvV@1c{a``UfQ-R`+JMSRT^K98#WK!b|o&+-etFC&^IZ#!`JTeOS#MJ^jRsP76s zHchQHQ`e!@HB8v8PX|)! zG3b@*X8Udr5=$yc`{9mlp9we<4UUci#EjVZEg3CUq)g26ac+B`sRJhN{_)(OAh}OE zd{Z_ry2%Zy!OS?KI@HtvJfdqQOh$neuGK<-fqT*+`Mv_EZCm% z(?wS<0`y{s$-Ylw;ne~I4T#*(BrPp%y3z^@d(wEA<29FDD5p0 zIaM&RzxnVBo=oiYW4+2?d5s|pU~Giz;3?WjOJa*WVJt7tcz(6QwklSda^`ed(X!=Hoj>=hfLf4 z{At+95p_A!c)4o^kT}uSZ@np&P#!{2Z?JRnk!jb1KuT8l$DL&-E}DEzBqOEWEOL%1 zw;=B1k`7~cQ)Z_&TXSjiT2F-erW?~HJ_UTltx*H)s%a6#KfNQVhISrsGry0TY%8tE z0Jgyd0G0#<=l}?J#|rxplmOVfZ_4|M04+iQVnhc(7pidGdIR*~SYG)=4J@*&ZboVC z%ivd2QexP9<|i?rBroPh5~D+A^Q2hn;p39Ex`L;}1Rj_RCA0tpL~~o}!K|B_I4i^f z&L5`AmG}cWHVNH)AQA4P7Uubm_4t0ZuBGZ%!xtt|OvU&iq^fJ1&0E>I(q1dk^XhKq z0c*$lF94<$PTWTpb#)Epne%crIM{Es6CDJA+Cppqm4TX*lM`#qo9X*)ZIN!FvG!rl zyYo}cdOC=x)5>G|R1NasJ-Asc%tzA6V4`(*VKK#l zL#+k(+v6bv3^5U(DBH`%0}+aZ;I2N`=AXSw3Pvg ztA_t_f@;S9WEr!K)qlLk?(}9h#pVO#9Wb%JuB_QQke6ve5r&pQ*x}*+i3FP6GJXXT z@i4X&08_L|o{T@ZY<(2Lz{G@&2DmnWXd}{hVJP^cauw3kStJ&jyvhB}GTAE8pem{R zpy)p_|A>8MYzOb+FRc0}OnuCA>JL6ntp2mjA?MXKt?_eONePTBrRtG-GtVxFiM^R+ z8byc~?24GAV|LEOBmuje#&oIi>*L=xpl9lItO1rp5 z`@7lT{e$m

  • qq@F`??|G1hetUkn9+Vplgv$wboPn)O{`6bW%_sI*8mTsh!29L3pGfgi+f~nW24g<@S)|bhI?5iu%{t4nz zCYhDRmrfSnw0Oe2l8WB0@y20i=`yZyKLj^qsaIiib+s8f;b;*$lyPe|F!>RcmVFq8 zm}@bT_g7e#{l3##JI`g9H4gkRRIkA-fIn_tV>omt2yh)hl;)ck8En?2D!B{`dxKL( zA#m`L8s1xjtpGy!;&3Sn00@}^5Ggsiayi9P_`{{e5re6FVBjy=(pD}P-8+Ua3U1Yr zEm>(lS|01Y0F|+x1H2<(V|SP$YFSE22R#HN@>wI~f*0~Yk%58_pccS9fD98%Knxiw z#0So07-98~%YF?oM>@XJDGCP^@UpV84Y9|o9Fm9iS6PlzPE9dsXEjU;=S4Gllefux#pD|NYHJ zq#$c?Y;G#8VJc-S^^hxjaV+If`EQ-KvK&X+DYnAn9ekXL*T<%tQJ3*N3w>=RxXp{Q zmNk^~DrN2WXAWM<=AU`Evjs${%x~6j=}zs6WF-lP4eJ-Ci>9oOXve&NbH$`hhWG9R zuCRaf{SS(LMjNJa40z{X${%0MRNIljE@Zo@QvWe;qZ6ff`4bXk`c+SR?EFiFN}i7Z zFb6`%ve!5G5Eq^+=i<^hPVItGZ|#{{um0>^wgFd`n@?_-q65?Q&V6jj9Ez^rhTse@2j(8;@E+&n%iQ0z2|`Thd}zGq6q6Xhe;wFlQYG?JAxYuk`=3#XuW+&NBdNHn93I?N}7Y03%g(eQ!>j6P!UAtehe>w{{C8F zKeO#{VIMUvJZT2qS|*c2;2X#31B*Ccq@|ms%IsET*SvsD!!f@Y^1-36konf&YkkP9 zOHDa$2JKuv_~5@#0S=Xz!jPt$V`0qdIZhE3tw|q}w z>?z{-rm0jaYwb3Kq3OKaM>8JLHv-@T0yIQk$9d~?X(__5$zxkFqArO*Bz*8y{vXa} z;Xk*N|3L`QpVkDD_f{o@xdwQLOGoXy&aSI&bQn}id{QeAzQr8i7hrxKTOw_kcjdZA z;a{0-*csjZ7mf8#9c*D7SbrCgl!IR_eDQn?Au*0hAt+;3+rDa{!EkCmerj=RNZVj6 zVYAY6QBODsD<|G?jCBIBPy-7iE-fHOdZ}UWX&&R%666MifQQrd9dZDf8M2r$0aRFy z-bP+1=~0K+EUt~kR|^}%F;+q%<;?|o;r#u#FaRBTpAm@#v=~Xh@~0}qHNf-K56)`* zoB)}y$yBz%#vL$AX;X)Iq}Mdr2<#`i4t#S1l0oGSZ_WfRTc!q}sn+9DX+@&go(tT0 z``1mAjt4knqHw3YunYu+5Jht(Br5PG=eS?ls*1FXW5=+b|p1bc~o%fORv_d`lzT%5lv=lTt%Jh0G>KpafJbiES=wpNhTZytk*Tgdd_ z7^=DPQ``E8zryFxUFbo>HBipGg>As{F*_QY9RX(_pXxL6{(JcG)G3Im{22_!^!%;a zTZXNS0-wLh27f+>BV9)TAzc3WGAr!=MbJC~`|1K>_z1sAYXld*0tIq^Kd;P_9Cf7S zuR-J;n$;)oi^FXcCDC6=3wvdV_MfA82h0v!qyn+e{;`G_2+Ehk29Swsxr-EwQmmT3 z;}gWVDWQGQLpKc20w@mjBF8cH6&&_vL!3OI)0oC*h;tX*N^(tCVU4(T165<7_C34x zm*rRO2v%3`7!&pQ1Ka_uh3L7#)N@xHceA9^YVNABrJdyajoNlwqtw*A-(&)1ToZ^bN;O-YZ7(0K4z(qZ9{=9!y z2W4|`r~%-~dkF&r)WaqA|1ksnjAXnS^t*$hFaEC42Xg_SGAe5P_%#*%V7u2r#xz0M zL}-+u*OX-ej!Mcrgw;>bA;7>TUr5YMHtpUzV@Hk5a~1#&)_C!|3^wig7BIRA;&*-{ zz`;G9$xFS~Jj}lmdRe?{`L24vR6?!5EbjqCir5DnbjFbZ6(&*MtvHn|A)G1cY5Yy& zdvs|p*?-mC7y2XXV`^s$g^e|exbK6lzz(zOuj2TT}T%((F0yPol^V;q~ zz}5olK)T_WjDZ(!F;wsL7GNd^gE)1s09APa5=7D|mOcC}1zC;2m1E7P^i-RV8jT|mCYuN&!B zyK)t}cD6S4;K%o(%Lx#kULqv|DisJ@D;?%AG)>)}v*ZumjTglNTywp3XoK7c&qF@{ zT%gu2<>97-2Bf$CH@XU3!`pdV6u37iu`s(^#Y8Z^LkuU0F#x?#^KhwKNLV=GE6c!3uUcjYIQKroN1(dz_0d z3v}?OY({fy0!}K+65(@<)rO5w-9&~pHzO^l-za=c_{}}z_xFJP4EyFtzg_6CH)I%? zl6Sn*oU=?bT2<2utV$M<|GSO>o_qm#8=l5(Gmu%&WJlA&3b6eRtq_JKVws(}qvM~n zqc%O%hE@GCNq-00BYtk*XG^J>n+q{(g|4|7N;c}n@w(@U;$mqXFj3?s(IddU+XE^4 z^}|d+W+^+Vahk^F?9ZbcZ}Z`w4#p@Oz5R`v65w?Oo&D!JoYLV-C;3 zq~Tj@C{bWVK6)B4F|p+ghJRp2|K{{)!*>2a0}@V^mr#<~SwY~|jQ4-un&US7P0Ypr zz>7Q{*2G|-W(oDb8Mpu0yV5qe|7H9cIcT@YW+x%TGwdeq9a>B`?ffU*4X`jQ0b_%j z6%R46)J6L@$AvbV{aa&ifI~6q8tyr9OUl1)LjONOdSDAEpo4iYz#BEOw%Y}kQ8Iro zqcHcuWBz4}w{WNiXJez$w>hZMg(4yk=!;B+6Krtd{asu*k??TbvCW@w+$cg*evn3O zzStq2(WJj!Q{7PiE%8@oY=%5jHkmyQVjNi>K*{UuJc>aMjd2We4bo^gEUbM98(*L#2 z|IOpAt%|7^Yv&SEe_H?CPVK~)jQk9lP0Ycum2kDDms=L>atvXV1C z3g!88ZyetSn(frp$;2k;L6-c>dX;~&WTMnHta-n~NLEL zM^&;0pIce4WNy*ts>nDEd`AHCWFM&FNDLrZfh`+zvIma)w0Ms_IB zkNnXK`=PTdt8o6qy(YHBMhNbh4qur`Sqr>!-f3C$V8{;@XLg#YM(m+u?&abk+vo?m z%dEG+5qkC!Hr(*HP@~2~D)HcA*9{)498G@Wk@J%hGUkz^`W6slEfu)J^HlcS1}j{3`f7(1bdWPFPw36 ze}Y<8S&{rlH7=I`>dbQkRSgKGnwuNzYF_^ll6MkU-m^i`5AAe1$?Dz^jH8M;xm5~KfT6$jp=|7$z zg1=pBG>Q`H2=5yN>%Me%cJlAGX|RbP#(rzQh0B3QAkC&LJ079DGfv>30WjJBnD#ccf;lW2`qUz(qHa;f@pzAd1DyorY9w_sr7W^{~`Z-OTB5j2b7yQ61v6n`TOW#v(MJ~Gxs3)J@w@`BX8X~N_FY)r} z0^^(C0ptC>t-XYz1U|XgWSY?Zv1Q&alP`s;5#o0%03=iHjt!iRAgLF6K|6olvF?%o zGygW^ro9?z&juiREZuF~K!0?H%j6)T_?_;bpi_b{?H|TTI7MrblOX@v#WODLjYO>Q z@oGQFq7&X|h)`dA!_+U~(qcj5e5YdFEA8Z`OHqNo%yd51{fG_bY8}oh!vzZ@(CM^@ zj7+3@Pt$&9&?>qc;u3QJUu0k@ktNHBorPPb`(&sq|_V2iVp3)_NC-Ff*GVR5H7i&OzdWb3^z8 z!3`Z99fC5p@6bebONi3Oi|huz?slxJn=HezTZHg3{U__9{3sLD%xfj0r#aLsNrstH zIuNq2H){p21vw=PXSu7Gw3)s(I|RgO4=ZD1D`*uG`$F5*JNOI#bJ8_+KV@TM15L>o ze*y&fqw^_~900HlAR4c3cFQU(`iNs=V>7dUE|rZ)@sXr3TtNS9$HKq59P|)Uc3Sz) z&7s7{CPmi8zvND~(k1(AI+CuoR)51QlP(%i*4yjs{jO%?D#N#M-#w75akQVQpro`^ ztK;{J7v0sFYLBaDTET+y0)5d!KX~7Z+ZToMK=nxNqf-O-VyX*XVLpJ6eD7a}Djtzt zR%h*LjDH^ze@Q+({M|?SGkPc{E(WT4^W!sIg$#Wa? zE9E~QbDTQZf>YhVAk3)I-E6MLfghll1A#)IhY^R*g?)dz2nE354tgOE`}Z1$xe(xG zSv572O=N#&&}>`=B0v7CLN_~uKorn<1;?3PLFwx-X?7I23F;Ik`lyUHn^tq~$k&^{ z^eKf&--e9?vpxj41!U!$>qI7*VFd%1*#SEJ#PJ)&rm`IG$Jec_T3oP8lRp&aURyHq zCu03){;RC|h$Cmvi6we+-aNHFsXYxB7j}N!H*2qOQG}KU;EmHggr`G(a4wu{_GI&* z#+_SSmAs_7++f&ZWBfTcS__-A7PK?<1tOu(B#onhsfsV?zL&H(1Ukb(Mmpnyi>kbm zj~_po$@r?XSM#q=#{RBvaPYzBR7ylIo~Dn}o;SryyUeBD@M>=9A*9*oauw)x_*zjB z6V4PMPQx1Z04~O0z^G$>wEQ!X+Xf#7Lc!++1WJ1t{z0#sfh7fqth_+U+B5 z|Mb#8fI?l`SISf94e*hF3hyNU`eC0gMTnn2Ms#+s2xg1jH6xG?{kRNP|%pXH)rCf+IxQ*oh$SsHnZ|N5gWZ z>h^os62MAL|NK3~R+CaFBnKeAW9+MKv~SCsKhyLJTE#y+%W+sc{`G@$H?!DG?2Fh< zu?Gb`D($80;?a+a8@tq~bpOxKv*F?7Kfj_BO9>_O2>0jg`cSfO<$SfxK{-aPbI%}r z(kY?zLl}-LY%0<^JdrS}k{TTJwX9X9YlJu4?_CmKs#0&Kb;6}vDrI7r)zfhagVT#x z2cuVvujS(~bLef#BBk!f?deO+?DpUZ4QWvZag?gN7_}qOBbEpG^@LmHeP8 z#EyI`rmguVLv`ADEvsn$wI|`BBiaJtIaD1S;P44~jI*1#sj1ik!<>uC+YeKxXtUjH zyb;nqlo|Hd#2uSrp&ZbbZ{41?;3@~P9lf$1Z04zwFs0qFPs zH(^6Sz#P_5`UTzfwS~&W@UTD7pm+7^cny%};iCUT-EZ1f&Vd0;?ch7D%zmFFEmQ9; zda^=#No$=epnOkX1O9GFC7><+k6cszMcdaw4`FbA^U&Mif_z}p@Ug|O@G#g#q-uyj zFCP9pO!|Xc*6zGlRa$Fk$ne=n(@11M4=B6}=THT*@LzZx&#*|B zXW}nr#`rSWu&x_q$ru@Zt!mB7}a{{0Jjc-vp(cUxgQ;59s}W8;G~)vByL5s>aTN08H0!pc1kPBz`(U3%-W zM186MLG^Y%nP}9)q?72`BN|mK82-v%8YD&Ya^7p zO^$2zBYvCYg*|4+v;AA$UmMaVeoRoeem;?MXqc$xFcHI$`31y49%ARr9eC*d+mj_6G|Wpg!A80`O*-#ZJxSaSuD?q8=do!}$YEsV^A(VZBjA zL3LI_Gcz-r(hU>77Zj8>QBv=|g`0g-HzRY>0tbs_G$BYm>DqsY-;uOxy~d}{aqRKv zK2yh62dd)xJ$M-+FZ(4XQ7GBOJ_op-RO|)V!@7hDJ>WkyT@KX|W<;d7-ogCf-7UpA z9E{bMrHc_j`N2iNd3zZiMz&B^j=+_sc>DJ4IPvJ@Zrf@Y(qpW)8J@=@n&M$fW z`EqVE1LNfw%D{Kv4BKCClO}WE=A1h;LHmw;kG;bE*3nrKMT~5^YRU#G2cS`YpGFG| zg-^G^iK0d}Jla%cP9*tunC^E3_KXoS2T{ak>Y07B1ES}BU~O+aqZr8#4zuJ(6F$@{ z?N?p8_3w%EqFl0?JgH}8l-ol|Gqdc)W)F?OAXny_-<*xSfArg1@BwL_r-?mGDU~8w zCSpFTRU&(dr>Yc7GhF<#(LeKwNRBynqNc>&ea^wdZ^?U(?O@in_!a_LT5_B_Ja`z* zba&%WMXaF>3QDf3HljBh4rkczXBWhKZTeCYU!s(&Rcz33P{7rali(#y!qn+;;-~fb z!_QkhheJKSq<(vPgboO793o zO~u?2VnEWHz*947a}zFOBDf{#X;skOHsgBKa*T4vWGb_xoLG7Ha+{<-P`j+B>LWq{ zo>Yw>rhwiInnZBw9cX<+CD8FfxZluT=HM-t_wDV-xi*F7J>st@8!THM(kW^CLL@O3ck%Prsr8kW_vjXzzsj2?^rh^h z%J*FuCAea9_XpOeX(qZAw09-K;au6*vNt|77bPSY4x33G1s<}ccwUuh?Op>>yg$iW zmtw5k?o&uOT!WG0X-D4Yd+MuIrv3o?TzU+A1#7H(tg)KldhJvFO5nC)bb94><)BnU z{zd+_g(jH+gLqlydI>_HDtK9-pDTgZRv(tIf_e7V^gSAhU}iRVPS-W`1DP_47895wszE2YC$NS01)5<+K8R&nUqsb8Ij=syESDhmoo5 zNEm#>9Z4k=BK{06D5cw|-i3~s&6p+W743+NI*q0o!tCIiZ9-;zaQVb!mZa53zRcE_ z6Ul=&w%l0=TE`T8oP*w)eDFkCyD?dGmZ7SQ7&BgVH}@oiSv{#Gx!RaO7p(v&d3fc$o|Kk3WBPM-1axPluQ{ldZ*`Z3ig{6(5G zGiF3ut)a!#Ys@rsV_{Q=c0XGXpC+yq^{&#HSlJ6+#*o*UN%)A96icX2TiFChg%`s& z?q^>Up=-G?ETM-PG_crg6i`EaC<1s4)Ix~&ge==c)-r7w(wwfxwiUNP1rxSdskemb z=I-l6tnD9$WPd%ySVfRP1A6`j_r;qsAc5w+v0QZ^5|K+$r5=mHg7g##Tm9Xs(is7Q zLa4t6Lzsjxb#88kFPC_&iNPqd8+~J*Eu9Aebqek8<1*gZ%xgt!e~B!)`M{FvY7D<& z6?ZnnH_s*VP|x7!-Vin3<{*N%@kQbDuId zq`jqUsQ8(%$>%|M)bCTt>bchQ-fMX|E8oFOxFd-QTTchni}ALh9V=qs(E9G3?S}cN z5*8wilOMw)GpKOv(36UH#>6L>7|}q(r+^31vx^HFzgg}(s7~uwwy&WKtP2Tc%Wr#f zxm$E$y5I9$^+I+a^0)*qJtKnm7XXj&xX1G zDYu*MS|DErcC{N-xi*}#yA1>R{uYxcQKZJ8y#KiV{MuN7~JwTWbEiG+vRh#v-ucY!paWY;r(I1>UgE5Eb)UAe{X(M zeIlJZfZ7-J`GZ~z9M6x8+1)Z!pru-k(W*J!(k6F`?9*LU?op2=p~I@I^J$K4H}Cb0 zO$jIVXY}-_I^LyihnGLC$IY*mbBA}%zFL@tON!i@-P#PX$1J2krOr-h}Fgh5PJ za_~-SREa7Y^%UQ;K5wq@z(D>f7cA%j82b+eQFbIR`9mFu830Tl#ThElAz-Bm1v>zk$wgdg>h&roMM z2(f6`#HfE}y*|6dc}9q}IxwkyP5Vb@vc?Dlu4^ek`?(wqswrNV-Bm+X{lS^T_AoXDf4gXzDf|sS3ln>Qib2n{nk~(U ze{)+ROZq`u2wQqrwbXT4Tp8PaiW_lbH`B=`sHcfH@K#Yn>*&NHC`5w2Kkd^ZmsMu( zknE(X*f<<$9Yy_s*-Lv1V>>XFJmWeQRnS>|q- z$45%G8(u~*W%;N#h8$(kpygOg!e9uB$Oyv#vEn|R`J68M+$XP=Z_3mIcGP>)c0XDz zK&<7pcBXG;TkJQH_IyUdPu6L2Q;kuTb>K$JmUG)C{5RbRN*K$E(RO>4t(_eG4Mc7E zpD)PJX3IY##4xLQg%h@EW0sl}gQ_ zofP<+RU}C5kA%V96>+P|O_TvT`3xG?VhZURM~_mxiyuO-okA*B|5n^Rq09Ev*ggO~ zZ9BTTi$^OIp>35j)^=l;^z+*ik_2_~Fw;o{ct6j2QHnidRt4s+l^px@V$&ZA#f-tr zo~&;_b%ai66D+$)QikE3N+39n2U~Kwz-;;O}GsUyHG+f_rPlf5%@bWN_;_;-GR0dAv<)L6#K( zn3c#?2g)4b&lJ9!lDlZNiCfWofBLBEVIpJV{=^&8G81qSjR`h#z!7QYNsu}<69tat zt*Ebnf`BGAhjGS17$+lK8i6IHj_-guGc5x(NMd`x9xLwU1k=b08P>7Zf!a#B@(CTv z8q>Un?}7RgJwMvn4ZG*eCt<^YhBCwjsx5ZUTmq^sF`4CddNgE7QgZSj zLB)ulKVKL4t6jPLl@wS0u*OR$;(26R#b_9m(na*hQc6jM-DQz0ZeYj#>vU%CD4FGR zF*%rbT&7qjcVHf)Gs_@PK#khSgQ^p<-o6y@20|vCbHb_Kq9S^QC~jqt_Wf(E{;W({ zJLt1l%G*A?BBNUQkE$6E-rwH15GLi`I&y6d`dMg^1rcP;1U4f=x`B3O$H7B>@E!}* zc(n`e6d$}1HKF$X^^UJxTwOORBjn8Lj}Snv=*#@GU&~!~ZFjKbUpfYs|k~Edlgo?vOCD*HKh1PeN1s|?^pIPA57*MPJpzjnoxU71d{4Dkv=5pe?Ss^ z57?rpjrcIB$s+iL`rzh4T-w0#9sRc*KKrlh;OJC#i%-6b8; zz3Em!xz4ydJfS3$onOca>le+n!~^+7+|v<33mP>O|#vYEgbr)EZqx z9u{GrxVKy&@eOh*TrmuR)L z*=%&?QFYJ(wg*`;t*wY}$~b4iuO1ocx#hlK|M>3Hx38S|-7}Q{m`U=u0j{1eQ7SFk zj8bR~ah~`GicWyM40xScCcQ5-=JHs61MP>-hMtKV;SBh>>hekNag%aMk;NDoPMZns zuDLja{i!V?>?1Ef8F1EPj+%!jP{Ovkk#RCnuQE&dj7Ls|#^|TZB52dg@Dk+{pazQ} z1d9QPg|vzaW^b>i@%=5Fa^yAT08U3iHKJif?jR@-4dJq@4}+=r)N|be`pzD`p%aP* zqeL6aK;eM+&AZs*G4$G8`PV>t9`%7Gi0)aSPzm9y+BsxJn&p_&i+Fz!MRXz5Kv`x# zf~#v-(mEGWx~WS97%Kw4;JH z={5&0TW9<3hDnAMFO51Jg&VNKgwY2;8xLrz|f z9{d@s#S-n4j;NjxftNCkaSK(oaG>`bTcFYpG%;+s#0H7V<*c6u=84KZb$RvTxGn@1 z^3|DSMfe*+e1CpL^2mPQ+C^4a^`a!88h9#5oMMF#e`J|GaK@+Ei>FmSxTjWZP`usm zyj#z4lvL(jV|mSpibiv{7PWzF1C)9AA0PI)H5*{tyqI<)+AAW-{HUCtjugyMSOq&K zREvbKXYX~KtTl3Hfo!p{ZaU~z`P^j|+@B^)ezGwXIs)mug+negTJY+h+E#WPK|ia1 z^?d7&U~};S6nL_kQFqI|wrSQk1$NFqonk1NM3H~3&qN($sqaXF0k8XPYpKhT)kRk` z9z=$J>)7_oK44|lN|1ot@6*e%Q1APOVWxX5xl2KFlLu_!EKIu^Z4$AD7{1}SbaJh} zJ+Zjo{;(5C&`)4M1~a*i%jR;9qiGM5+eeOB$`TPx*SI;Er#%7QR91y>nseSua&!br zy`wOWV=(eFm=C1~SvISl)ORq{e1~QKUGu})tBk8gbRNrIkTU2uj+?TFYOZy{p1|VaPbS9ioCG;^#UPS0~2-|AkYzh4Tn`*-#rL&ku!C<+tv9L$E&@~l#Hd2-A~Xx$w*~Gi&6Hc z2;iSgm5R6F3x)2_lcacW!V1}Yk)}0i#<+y;INi%o50YDT){CR^o+JkzlGz7s?$tWA zG!hr=Mk?1WzhTj9fYmu(H-rPi+TZs3B0o21?zr%ZCBk#$iO#QHJC2XgrrHz4&()?& ztm1OjzJ`^j{D$iXx@AQjz2Up%320mg&tk*6tV+`O$rE7oe%K8nXdYCCT}I=fmC{f?n9Q^+}YRuDHu{VYk|_n#NlCd z70O#XLVxzn1ehmY@a>@x1LfIsFgPeBh2$#leZ(m~QU0^Ihm;-HX!WC;(a@%UR!$jtC))&J%>^t~sk)v|V z{5ukTh&&T>K}hP7^5Us^_-Doiti^saV>J5qWdh!jLdK`Qwx^2?;diKYVOFah?e-MbeI*z8pdF786@dZ=HD4HU%qj0RY~YGs~g`!33~ zrmH08xkVfvxTcylo%RtX#TvKNJ&zbd&J3rzdj}@_n`9;mcOs9-krN^pS0R#DPgBnwb1}12a-lDv~?n0;LjK?8P_TQvu%a&}9+(=D?|$KC56C z1U!TT2#DVu%7zBVEhD2Ft$FLqs>4hq45{Y&lA5u;gqq6h3kdWoE6!ev7aYC-8)~Ee z)5?BMl*?{sxl`y*6jBsoGVNAmkOO~w4m|ju)y!GB3Ug?A$C9)kecFbFCh& zcfb)>(1Lk0=a!jcA8b8}wu`s5cQb;CD7l(LOn0fC^c8{xU^I$mb%#zx;v?w7LZNUj zmelkD@4b6 zTp(MjD1?e;SZN33^JYv=&0E9*F^uRqZp`=06H=h z2x5WrLz;GC;#XimfY+5#CSpczZo;~*Ieof z9CnU6YmBSq6LN#Rhvmb>5)6AZjY}v*R!O8 zbMILCgHP51pKgjlG3&0D>+!%EG03T@&>28fHV(ZMlpYVxs<$|}#e9X#{LkP^FkjU9 z;-u|k$?Ly-(Q*Al(0LM32?=oizfL;>Rx(re-&#vyD*pS(Jcz0qfV%{*!E^<*QG|qq zeE9Turn|#>ltaFDew|pMig&BOx8H2ZqxHef?@+(7K8+)U(!kBKKKnfk$Fh zmu`RLfAz3udBK?yYO-tcAQVX}rk|b2ti2>(V}6Ej#xZy|IfQlBD$Hm7<$KfRj@-{B z4g957|K$OXeEYXHTVem>5@hl|+|-lJU!}^|oy*Rme70PK_KDVx$Qc0EAFq}>qtA%=TM+{mfrRU z4`u4)CvGgnOzOJUtpJdC^Y0TuncIWnV1vVJQbTtkI{HV=eAGfowD`g)CPWOlwuJbI zWtz99khS`^o0W}2a`+?Pi}PN1>8K0k)A=rn{Rba<(9+x-QrU83eMS9~xJc3cYAqh? z0x!x!TQiGfNX#b~ZS&?D&1r8|^ zbn36bx^b?s=s~EIi?dbLgu}|w+{$+t;-Xio|43waj0?W0Mu}80Q7y|r?E8lya;1dZ zKaHrraPB7!-CgRj3te9#g;=4|N6W#nyyitk-q`4q#*E_UPLo%|EL}Vb-ZXVy@t~C> z2hxT|tk@S@681tD^IaJCJBZ5<iKraZR^L95P(mPEFS@s_%#t`F}+ z#Yb9Rzx90;SYH`*FbsHw?=GW!ZoLk0DR9KrlLT+qbF4%iYqB;^lHwNrduN$@*sjiUSsJ0y0|@{{)%HD zEhNCIy_Rls@MoaaJ-BNK_@Q#4#$lDA=mSVz>K`R_`$a%Lm^RX+)a2gIfqehEv5)sw zn$o>LNE?`_!F0(Ud|2&^gC2R6`!E-HAxr}82l>=;A-oXmg0JRYn;FY}cJnLERTf$W zbZCgQJm>%q!0}Xn_Hjg;P%8uCkaj42!6MGqA3SFC`U5$t2BSP2bU&m2lz;L1h!UD5ySiDw6&#K871aNJj-%O zCHg!B1*{R;y+UN5@YsqxvvX$KR)#RrL`nw|eAZBlGc8fc{ox#ErgyZI;7xDbRx33M zr-u99rY9h8FAE?0Foi)B-WLK;J#;jG+v3Gfv)~J}L`~O!q^l%9&Fd|Z!QHkiK~*_E z1yf$xNqC3g9H>dBNnttshtDcl7gVIiEmw2SVXyKDXSDyBTgc3fe*7c1KjN1MMM zb%1Pe-so|SLs;<>BN@W-cs;5(;fHmp7wG@!nCjy`a=fL9G^D#=DiRqorD{1&JH!BW zxQ`Jd>iP)ZPBf*o&*yc-`i!0y%G6vhB(sB%1Z6pJEMa7X@Ig`huLa8tH|tB=4D-Pf z6L-ShmPtM7Y9L6mQMgCiD#{}t;R{(CV?yG|Cbr_&y1f!cw_d~U^LaA8MBdbw%onpe zGr^qUB27SyIkMK zfGFRoD1H@pCR}9pU7xua;Ge<3A6!zsdOCa;%WxQ_<;4SE-k_+(?auB4*Ofc;;3c=8 znJl)KCcJA3&k64O8ch!@?++)9s$Pu%dO3{k$;xfLPIk;-5J3Ms$u=__QlgSQ&r*VP zIXNkKyVf|C8Te*CH8MNWud`GImv%b2P zI>nO*eee;%Vw6Ct*UUWXp8TixooGtybPVBGrSUK#wh~dV9_KppSL@w4T^>~=kuRO3zLGg4o_dXejSxxh&ErP&c&=2Q=6030k zqOT1-FQU+EX7Qc2UcH&#`#1y#DVF4rqH~(eYS?!haToZFUsZ;OsCH>v?S3?zmbsb| z7+L0J9PnMbg=NG!rBFOKu@J0A;HJPK$tw zp?>HTHp{Du)+LhumLf-YDRli?=B8?yCIS!Y*d+w-n!tr2l}= zXK`$bL*L|(xk|=v zKdFk$z?LryI>tJqjp07@3ejXv zP#GnpwsNEmMAzxZ6IeW~W06Rw6=T{pL`=WPoLdbn9)WRL_e9WAHWAWgEhtQmbttXG zwd0V6nfi7DY=r)%fBg&Rlv?9zOp$UpI@qOz-&p{(1}Y_vtz0?~$<;&;bSHSyx+AbJ zDF3Rs%n@ZhO(Z)@=>UjYKfEu9L#Oj79RC|Ycu0P%o_#QtqSM)Fx8)P+^ob4-{Z29lvfd|-l7)~0yCeVl&)D{*h$FwbW(0-s1!Y`|q8MJ- zjLcx(5cv&}`%N}!;vq1n_!4Q|pM;J%9p-X|?7hMPkCzGJPdoyUZ#?kXRJ?&N|QJ;dxs(E^F*~5u&nL>j16!+rpt|jSRPP!J_P__1&u9 z4I=5(Y0xD)+K64Btz*2hA~)MiZ)hNzaI@RO8N#v9wu{q93Sp)l;|tSjtMjxwZOAJ* z`QG$~>-J1hr0Z~CBd6E0vV$4f5&QUUx|*e5tAXop3H+k+A1nozXKm|H{gP6Y7||&( z06e^9B;(rtXZz^^Es%|uvo)RGM)M}?y7+&=L<0lYs0VGib}K~a@;xY-gS#AuSg3Du}?L0 zZ2e`&Zwo6mD8G>&;3SVX%N_gZcig#k^Wa8a%BcYuHkPJbbjS}k%>BkO!x%bsBkywT zvk_&UtLoSk488cAO7R7{I@XVNSnanEUiOm9GvJV*gr+_72D4}sWd5g?%g;}Exx8W4n*k4vD&@--GUxU^5JV-D=4l(EST+w2SwAX9Ccm8J-bn1D z`XzrtD}B7!oQNoGJ6s-Q7BC#?;Z0D%sLUlJl05C*w?Fl{ipr~OIBK)PJedYZsT<%pe8WB_ zIz?o%Hl^~;ot2PLv>$&Nk_3|a5YdM{_Hyb*?w7UOJkU-Z5o?dO(N}AvJ*V=LFLwLGI zJGSDMcYLK>OcY@X@Jd8@_@sR0(TwHQD?&K7JE7R(IDP#Fm z%jngFgHtN4kxlrOe?$lYp034k>LUZ2cs_S(#F+89Fsst|l!uW4aU)s8R8PGA=JTu< z%jNRz+aWxn7^#WCsg=C0D3)?_BNg0`n|aPHQVK`Wx)H(3;r1p+>&qXc46Ky@h(xvg zM0pknG0?9R@N+FL6d?cE)CFFy!CHFC2f1vgC z=~ji*#SCDuYtZZ(%-EM!`F0COa2ON`RNud)<|~y@BRwEaY6@BmCY>xqY$~& z2eLGOP>vbPv^c=u`FdW-fj{^O{YeZn!H<9xfYrP(5)8_0Tf!LMDcTwm16b2x0wrR+ zVOu!poV3NZVVe@()x>yLf{!#nj}GA<35@!sHR`8!Z~m~tB62POY<}w5XS55u`)|AN zRnSy}Hs&*3w89K!WP92^8#u03PGn-*&@N8Doz$YP$dA1X#Xg&OvlTiwr4s*hH=)F! zVUrpMiRzoG_{3af3HCwz!%rQQjZG@cN!zs@w;yAW54y@Aw>OvdSSTiWrQ|R#Uv4$K zV+L-ri~X7i-sW^mRH-20lL}ORo}|ga)aZ~|g>>O;A*KQ(?^|N~EXD2giTSIK-`&s3 z?>1fA=4ljI#|m?H+!THi?CAXb^+s+};%bIgFvgTqJ}r(4Y3`%r!VkWP0a9EKp@_6E z%g-a`Sm^t6!NtFIn6K_IGr;8fHdeoQB(TE)0-Ti59`B8QTnVt)$I9yW>nwl4JnS*Z zgI%h5_3Ku4at1u4U<{<-4{^B2x?wT}t%eZQ7wkOE?C1cC>f6hh`K2Y$f>RS}XotT@ zI*hd&9ug8#x@I9K2EbpzP2qFG@<=OfpLEmIF4lywH$~@|25MJ%QHH!r1+pC5S zcY6s_cxNK7KCbia9<3x_<>k!=#hMX=`}w=ZxLU3lua7rYLbiB;L{6xqy%lYX&qacf zJ~+%Ybm9BDWM6q1=y2w>(|V+?(?vp2*=u~`!)eMUClAbcc7+;IgjUzmj^wm+N{4;a z@@*hjbOOu(n>y%DD0=PXwFN7-eCIYfm0{X7rP89@QdAxnzMJrZKJ|oBJ*?ol<2gx_ zLlaahQlg3{_6AEU;x*h!`o!+@;&hNT?8o9kF(pmz0A)&gVRDbFvGinNbWZ%_kB!ss z7w&yrnv;EYmF%5rAuRw%WkNLq-|V(`6Q6uOP22$ zfZd@L70H=Pbo&n~I>>tir`TWGx1V|7joD*-JvnTo*~K+19BfnndI8oPZEy&qiwy|Y zW_xIKgOLwy$LsLoSY514LViOgYg=BWaw282sNX@({M+YAa@A=VI$aWI)`)!Js~Bzb@% zYRwbbun=Msb@mb%+()?X%I~x@&ItMr6d@e7!IP&qHC+Yr!*a9eUx^$W0ZK1t@F>fLmn83p;uOEGV9rN`kA3mibCya$- zA2dbDCqN(1^t^XE<5p+nK3EUz8$V=nz?8*A#9+z%ndx63iPeOsiv^!1=m#5vb5BG@hboE!%xa?Lcq85zkBY}-|0b6|- zLetiTD$I&UOF(Sz=C-DWo?B^fS?cZ;@U2hBFqHdqrs^`?>5R2xUvYG>IUs|DHs;2e zhrcmOFJ>8~bQp&xcW|P={6hYuaZ2*0VVO%ux#;rNMv}M_%9<)XP2X84nbcq;L8VS;lEIDUjpxoB}vyYPlgslF%J7o z5$bb^29opGvV={tpr4}Jk*E6Btg@DV)XolFy2(qF8Yv*q<*aK3YrwG^NaNffrCOeA+gRUn>S}hEZ{GoH z&8uMFIa|l1_k>cw;vRJLC!<+$oc#i&3k67c#N*9UKt4sD2{KY*%E3EE_MC{eV7V8 z(dzU@qvP!7$H)7wV+cQ#8P(o$r5|fo=ez-{bUv6+BF`Nq0?~Y-{5o7wR)9AS%RxG* zoME!Z1k?61NxiboE)y+m9}dP;)SCKdCMy=Zg7hSoIFp7 z^r@428Ae|)38t zxI-M5UmYyVUGiZ)q@1+jc`r=k-VCUFz7ZXN*lgl#ZHo+*xbwWWy;Q_LyecjyCF|Oc_^u%uFFKyRg;nEx-nuIU1{HabBV{=(+(XhB#Ar8Z1_z79d)Ba z7^LW%3y`6s%u{CqSZJ%j(3LW67G9SP6ktjV3Se~>77T#t3LOXd{O5J9+gK>iU~YYc z0f)`;;qIajpO0yD`y#K@7bGq&>T?P7e*OFQMK$d=4rhexeGM5R(40-t2nYeJtBD@@ z!uUcDaPw|cQu9C!*YGy#qo4uAXFyTJ4RKTDAZ3^oRNz2ts%VSm8(#B^$Kp@Feu*+d z?pkJFC}EY(XgrpfKT7!iaK;*l1iEH%4ASMp3JX%s@=9vN4G9;?7bl!+JdF$*i4e53 z5hrXc+@+56hS#zO2ivM>CAaLaUn1EzAae5jisG}G6fvxU7WekvLPRw&Ix@Mmv>w6S z`aaVx=H>c}#mfx5@|y+5@nm4w%sj&df>AJ2`LR&7ZPBF1JQa^~v;SkMeW%ww&4BNX zz%ZkYg@F02s`_W^Wjj^Kv#CvKP%5Mlo2O3~RTj#+TymDYTM8R{tSVRRDUnU)NpcgqN1)I zR8gUkDC`S0zSFv*9J-nfNS=5o`_ypLeeh>lXh29&XdXq5FzCK}EZUDa%*;Qh+~$ ztFHi-v$M=I`H(h-KijcCC_-kee&tmaqn4E~pplCf2b~z_OPw!~*+yQOTNSlhcuXf- zDe*LcniM}8RiN3WE~k|q_pv(RB(<{|urFM64(&`I)Z?U;FkW;45%PA#?Ze=ELQcm% z*4pn7aAs8%4$#muShG-4Ru*w%C@rQ7aNE{<Cr9f zV~ucSs^-%`ZEpb~{}Vz&DI=p_t{j1_A2MVSqw$(htAokoOKMTfAi(aAMa^h!rNJuY z)I`O-Q%?lhS+T6Kuzd7IA2D%>)x)}_KmeYtqH@tY22ecpX(dz4{@EY*c&6ULXm)PP_iEDZ zmg3Eq34ws``O(t+$Wv!nFI?5GjyB+|>*pq^|H@f=g2m`!!jFS`Zj>qUVxVqe=l!W9 zkoN0P$yZk{oN#(r%mP;O0nhgjzS#*-6ck^W9t%GJ6%)EhRv$jFtyzswWWV)Pd}P>T4^U zLLZ_Mk8brVqe44q2}MOBt+RXD@?r2$h5!$|O=@MzeHG?CN3GR)xZ21QdS@v_H_UCP0J$j&ttj(r^|asr#Ebu;w0 zZXH8bSj9NmBpp@&&Z$wG?av8?@QcI{v=Fbr2M##fy9xT*7;g|3sUd8cwh{=gDg z&BO2JE*&-%Gz)`H?K86>N?m*4%pXO;Q)EKXUArn8IuU-qJ>s2DR-|AsJd`x02TfN1 z#!=xHEft^)De-f%ELpS@*JQl)x_CA#lDbw_Nk>xE&gZZ&shG=$cin3b{(msX_D2d1 zEh{tf|A+{YWgZ1g9bCRxIl;_lLvK|efdh&e4VNQkP}nR#BkksaYz+=p=>PvvaqDC;ZW5wCmGvY$J}C%M%gVP z@}XBN-3&tPVRR9v2P5wPkcaR9EalS=bu>w3nCd6L*8~(S!wW z>c#}1z=H|=5q$)|turJ4^b2)R;RxLW06Fwr!;WDo>Tmzb>ix?>Q)F4C#W7ENoZ$zC z0wgu=;zs9Bg^wu)FR$*%q*Z{%*CdRQ&J~w7>XwAR>84mWiQURJGLANyZR<(I+O;og ze?r^CPx-ufVbCH@I*e5Y7e8)H>8YR(w{tfS6MXAoa@xh#HrI1bpX1`Kus=A%3*DWj zcsV^G>}p6)IkF@_fOOsjDJYS0yX2g`dxw;gR|@=H4U`?1wJ5=k8O4^?7YGcWc4o)d zRoFVM!-$mhexyrVvIZJ}NmCx`%}v#x^F9I8hHg+zET1}H)oR~@<05;O0G;r zt&B(hp;y^V^Keq+bS?v?e%xZqJwIq^Yh*FAwp2L#mFcPq==-jsVny~J;b8r{XJMZ& zZ6UT}87l=?DjAET-1=R4=b{P{YJrRN-xNVhbX6zIMXi!lRmA_2>kXDPxF6(0uAWb^@Gc2bm z2L7lx^x2_Vq?g1CfTEWV<#mNGdW8V60i44BgUcxOSbiaS7YeOZi~qV=bc++mua

    >%2u5siX?@H>=7b$bY&2ffxcPV)*lpAI|J;CLmpOwZ zF_GP}_PAx>ufpK^9|$<531_;1B4;%!K+y6g0>WCLCUJq#AQ8w|rgG>6!Hz$bN@i=B z%SnI{o2nS`3(vJOCC5vx`e6FjKIse08HzeA-ndst2n9eYRF_LyhuZptqrH7@C6_kQ zQI~XE@q#}iR~|VC54L3$cAlU~N0lD*w)OeOt>K>Z1YS;-iY1))KOOZO4 zwT)LqNx%T$m-pO%V_^VN$eKw139SM+f1h}Q0oA7dDWV6r6kqEL(<^ZaFrP0NR}`lnz1*e%6tgBh~B^0j=! zWvCO5i2{{(hs~B0cKfw!jDj^#yiKnfei4&>;zm>e6M9)h%Ly^`p6pUAj20e#$m<>R zdduD7-E8*4oIL2zIuz-xowEDc?GeSfcY1qmmvR0#YmKNqL-pliZk4m`9?@xj^*ZT{ z6~M4EklreaJ!#8FRn2%tUI4cJZPx?kl)|+dvR)zD=io<3?0Ajm9_ss}M80DkCmc+%EDUsrU;F(PhFFa+yz%S%RxVJGWEOXZ7)H(rakHv+Ie zUYvE8u)HxCK5X{!7a5dIvzW=9ws0F>81Dyn%V9Q4wXy`c5doDM_K$`Fw2Dd@Dg1Rb zuo{$t<;-!t12)TOg7}a8FHDUzEJYZlSUL2OVV*w8Y#Jql4 zHE3imv^8{gJ#Wy@NuP1ge-g{nsUVSeLa2y$4$pxdDh+hUWwJG-CC7HT|3x7fODXmt zso=P^w_X1l!{>h7$d>QKpO5tWfpEMMb9VRCR8aEp9WMg0AJDiX7np`E2b2LkokQTQ z*YD*t%YpcKIr6J8@!q`)Bbd&(EHpvSp;u;Y$RPJag)ezC`aNv6-rX=K@phvd&gi}{ zeG(dZ>~`1B&{omD#fC%AISoBqIz+QNX^GZPKHPF=wWV#ae$vl^r_T=e^k)#0dsr9K z+f$-3d~SEO7r%Zrgr^;tM|<_CrP^6ZDFty5r8+dyOYd_T7~qC)k#!`unYiq)D8dY9 zq25;!8UnXT_@B&a><_9B8FC%nIIfOEX>`LNx>}DK zS|(mKP`JB$T`|j0IuNGm?{WGEStgbOc2Gcu(h&5oAqB8f*@hPBu7HHLvVOdb7b5ipT>L__t_bKF-U z7Wr?P%UW+=&7NRH;Wzp8;Qu?>IzxGMiU9E5{#yqwn^u?|A2d8S#ZDeKF0N1P%pn9%zWf2U-cf4}A@C;B2P{KL)BO00?kD8pUg}?l zrW?Z^^`QId%JrU;PnHuBX;$|}?}#6M7hL5WH6?5hxwLIo0-D7r2-r=|677<7r^9$RI)%3Ol2}UJng9WKzF8 zDzQxjjO^&6@e+q|-$GrQ%W7r=_`1%3kD~HSPw~mO1N6q{28`I2?yz&l>%!)0fPzPr z>Jw8^^Xg9lML4ACl(AR&GXqQs9S$qQj|6nOBn+T7$m1@WT9Et`_7Jnm^*`k~;u+sc zp991X_B3CEN2>P8%HQ$`Maf5B@}&N+lKS)Q|BbkB`lmSHKR)SG5|CJCq5-mo|MxWx zF&C&Km+|56z&LW(L@;ee7{II5>)zukPi5Ik7};f6@XAOMNC6*!Y^OaycbF_aaHHMQs4io^4hRI{CL-NpHHs>F0@xQ80_%9Dh^q0^?{ z|9a_9_6T_UFI57Nl!mR7Wkp^2(V?T-h3+_Jt+mS7u>Y@Xwe;L=&aRe{nHjmX_1;si zx+(!oujHu@728AIh)#v`;pDLr4u<(V61pgk;BOTs9B4 zguTfZualX)ZghRA$zM{w|C_Z3<~jVWpz8Ri$ffzFJ7%)^W_b$>of9a@=GUeYZXhaa zoMHY7VqodHtHp-`stMmYiBy3Uf8xzo_EIEiOFYsy=cTQO=h<{?wcQumk5jd^V81_B zU6FjS<;NgSgMRG7!+N}}56QEVdUr{GbxdF>Bg3$`u~Wz5Kv^6FN<$-pHUPQ3@zo*}XIQ6V1up_4wYxw_FW4nCwm# z=M@)|zTtfo8%2`P81Rxq>&e5?=EJqGV^7H0@rcu)_cdclGAF&2JO9^5y2EcZz{3E( za;ks_t@F)2WMn_h^l(7FT|orXPLq)NJ`ASDQk;l{a&dcY;w5IgNL}fkBei{n@U45c znpsEXz?|b{U)@2f`vP<*NR}dMY+Mkb2e_uaJ89FDdx2Hs;(|oe_^S9+?b}JEn?*uA z-i_=a$GqWM@)IZ5x2zxZhe4cL7wdq6cU>32hR-Z{_8aXLwm`_b2-D4nFsVR4{WtgR zx2)%o>3rM7y99Yhk~`KY$E{w|zA*b3@?zZd?Gp}h)k;SV_)OVN zCoZE4DD?hh>K;ClZ+NUyl>CoeO`ur=XfJme4}BjYT|O(&K=6Hc@WzG(NCcRI1V}Ul z$-{|Sohfdu@<{SZA^@LP+dgVYWKZp(=<3<_^BLT7x#X?n`DvY6lK6QB-Dme5Z< z2Qq7t8mYaHN9wz2_r?INOhvV0V>3h5Uk+(=nVy~sk+Giv^_=vSRh12R_(!{H?Huu2 z)UnIM#>G1{WdvbtRQgOti=z&A0UR*~9H2EvsME2~df9Qyltf1mrhBI|xsuRr4a7iY z`eH?D{`T}m6NbS#a^KhPf#Y%Tj-+kVl@-f7O4y4Sxh!#f>3CLy5J6?zcd&R91MXLS zD^`o$35&l1Yevc2ND0r|Q)9hxOE(AcC3fphxaJc$yl{2jcSRa@T&T+OboKB8mk%~~ zzuwRWDM);ljd?gsJL+{XfCCjV>3%shHK;`Tyb>3v^-Hwq6?{+N*fE#BMdfIZkb@|?Ym)(I&IZ1NO@xW++IMV zK1`(~PBc(Voq8Z}cy35g@L^9l;?MozPP>D1|jEJ|1dqPI`{D$rwKkJ`JwAv;|7^%z`3y z0!yN&$*%86hZCoIp^bx2UQJ0zN=oWUj@G+uf%A1hJq}%;9Z&*LFB8}$hT|MD=FO-?7}F5&9rv~L+{Y3Xnu#aA5l;>@H^Zd zz0z))Mwuh`jhTJ89tuheY%S@iZ9U`J`u)4J@t~RBu>W({6VMYDhJe81umh5K?2XL^ zk2Vfe!e5SI3^uaVI*7`q>%3sW>?kM}bE)Lwn$De;U;}DM3laBLHVnO4%OcxL)wj+@ zKiIIq{b}>#58-tW984!!VcZM+P4c@Wzs){aNCQfwwU?<7jH)G<&OKm$lSuD#DyUu;2sEx7?*nnLCtCi4C}yXRy+0$^K+n1t45>f2X6J`8u5 z^OQU^9;VuJUlW|J2kl0Nu|fO4-q0(xHo@DuV^){4b|=(ETCn_zW@q<7t#&eW$0!iY z&ag1ao@*sR)-o*WvWX<`{xr2y?>H7y_5kb%YrcAXFAXo5goM`aXtum|gITy&S!T9; z@HX4^O48_;ioedv$mhug62wR%e=a0%quy(rD6R`@kr_=D;Y2P}B*mZI+V5PRl4Vv8nm0P40Ia4N5kx_F`zGe7nS0;t68y^xbqYMY9xtSn?AZ_g8&xNn)*K#v&fSWU}cOeCSkV#0x< z=&-klF%uK}fs(voj+UA1{oihcNrYeTiCh7YIXULFPV-}HD?>DJWC7P0fZoDzvTUo{ z$t5x2F~yn=KqD)P!r%I26o9dOBHC4Dh4aBBG&?-tk;8IK8v_?@z_d9p+SHxEJ`#902T42Shr|Z8|E!DQ^K%t5Xl4_Yv{U$YFs@l!_hnf|dlvd_ zBltGwXn8ze4H#WU0(1h41c)hU0$#TBk%8><;bX5BQR14$lN5m%CU|)G-z%N;!`Pl z^zZ}|Zx8XdJeYnQC0{-gFzoQ|csWHgOM%lsC-fQsbIudr|Czb-NPAAg`aY63UsW6g zcs1WL(iZnb6Qtm?fB*27(B#_&`U(YkgYnu_w}Lx9T43h`Zj#WFpZzy)Exh8-A?+=A z(^<=Ab**C?(>}n1V{zwO*Ly!UAMy{H_#mmRRT8@D*FHKtz*PHbQi6-;gXXu~!k7j__ z0ooDUUeD|Q&~}zlRd#K=UUZkBC@CO~fYRNfAkw8YN=Qq0w@8O{i*$E~bW7)=k?w{) zmp;$)zTf`d{q3=T>@^(xU%7;ZHoDv`y6lXDK3EaryrO^4;Xs}rOAySU zzgAb*5g^FOD61Jph`;9~nP-PR2TainZfbNs`HfmR&Q4)tqu%-RTJN#2Bs%jtj(XN; zDdUF#c_$ljB-^YG#K!Mnlp@!iRW{=w02#K>;xqlDapfS9Sgi$5gM;S)ev%Z}Cf(a} z&&Urey?*4wwCyC*<`KIlV0}IHA1KjQn}_W=tA4b0r`tlat$a^7GDyxAl8rvJmZHxj zv~^004D-%5O<@kg4GaDR$UF3#+Are6Qc*@D-?>Q*?naluP8g@pL~p`-^>nfn$DwaB zaetB;3NAmQh>aeMD0ckeo%b9E*cVuYlj)j__C+~8^auMvLFiK>FGd@B zClGSFep7F!y*=-CF#HX+cm%oH&O7g$@qdQyo^kT)$wM0>arE8Uzt$7V3S#oRmZ6WR z&+K>o_$jLL{iR~{yC_D{$a@S>ZRbnl#F)?sW9N4GF<08ih4aUESRxyO>yq>wPcg zy&UCaQphw_R;Ji^2MK>eOvGZhkzDveeaDU>bRo>3?3btb)>tOH?B{@2fQnakUVS}@jEoHMIi_NTs+s@j z)pp~X4P6MH%&En3pz!fNL%(y|86d=sC{JTdkz|_Uri^d^rN=@Yo<*HM#=6hduer|E zes%vnaI&Pw&$Ja<4wid!H(nAvsa^f7Ro~c(bKUx#TfF(HoL1LXuZ-Q-KNIbMfvA%E z^XCK=EA8k?s?xdMebJ3ny?_KGL7#+~hP?_t{iDWeyxeoraDh>9)G!e4mtn;1L~wW2 zO|H`&k~L|0#e2Pwaue)Q%I%Lmu{`5`r+Iy?eTTC0Vdw#LqM=%|4;IR^kVqmQVFkJ85+C+A_?CCzgop5T^ijg`Lm5RC?G zM}jm;(%L)B>nX{9jvHApz+ik~H4 z9m|FvbouV|hw7&bz*X@;&?LGLaNmK^Y=;{IkYA;cKij3^uza_|G9D?gPB}Qe;jL~{ zPoVYFzX}O@5}aZzj~429y+;P?C+J&s?4-QEW@zt^-Bu^ZS5IjzKV0C6SfIj_nqbmo zGzLkP_`XF*S6|>w2vQR8B>{5cJ4w)s#J^f1Ky77px;>@quWiC&t^^en7lpT?Bf{X@ zFJ@nHvC5Ep_JDA$TmZfowm6qs`hg zU7J~z+pE8>Vp+b**4ZjT2c=oA;fIda2b2-N_Q)ZSmDTLCRnOa7xRsUn02ib{n{!J- zLek9lr3z}vjf-j{3^j}ZX73c)ol_% zw*+T-cI0XGULlK4has|VkvoDwiuxBMB#)-mhlMV;jFaab_ti@D@cg#@4?2@2s;ycq zCA$FoZaP2{;|#+}zb3%}V=JK&hDg^BVxSXtu^ zPoy(gfG*!fTQtP8Y<H<9&XY6I~H#%$S`_}g#p7IbnkE8b{JFc<*nhUpn za$UHQM6RA}sd3b6zvMpqB)_W7m84Mu`oVwjq>s&Ceqp;^?mg-7j>(J1rKF5L>mLWv z2(#zP(HS!)x+UsYgZXJyeato9F+q6R-0BuV@BFxH<`&`zuU zM+mm*g4R9apQostLi>^~wH;pX)YYT;C288(XwMWqFy+kU$93 z^49=`;n&#ccHJh1qj!1yo@Jmj6d+r89XB80g_sD$vMe{<9V1T*2_nqBCatYwS)MF; zz|Ph5#ePA+Q}}V%i}SC%u&qHY{6<)4SfI*#GiJ~0XKSz;-zY?7?4gRf{N$?V3<`v~ zdWM5e{SiGELu(HpO3pD4--GoBCuTh(`rDM@u&M?go;^dc@uk@mPQgfK#?KG`$hgd) zhEca@g(2|%kxBu+GU_8a1CF%bWrbZKMyZ@G(Tg`xgi@X7pr9AOGJh^ywCS-xyIn-O zieKB!PK2Vw0Hc1BPlt+W);}yO(h#{VSvC@Kc{m_c@3|YiZnfF!Sif-o4iO&CrcPu3 zX6>;Higuf1=gtPd{ew9$V-|lyLCQwzx*0LF>b|0=eUm6$Eq?QhprGw0K|0mg;)Qps zSqjhZ7N2u`^c=o4-gtDv&={T@(eF9*PtVDn73U}sMo)^$|14UJu>hLN*6HN(6!4f zNfcofDZ9epSW0Jak#;+ji;tE2VQaGvC_;n_;QhQP-hcOnC_OBE!HSBBV zHxnd!@#FhHltqEchF$rl$e+BuzQ+2%{qE+j?ewZKeE(=jXj}BLC0gArlmes&NjJvP z2g9W71Zcc--!v_2W%YG*a0OFvK$|g+&z|g4sWtQyuhmjgmDQ$#u;5i3tirjvpKx~A zwzCP?$k&zis4-o=_OK>dUvWS@1-n`wI?DoVSUh>MXfOb&4>XqhJ@4g5QRj=M)~emB zf6El;E!)(D@W+jSx@FgsP)P6)(`mT$W@BTdP3Jh{BnM^9NbNQI^V~Fw#42)syVa+0 zLSo*Gs!mqw1usNoak6b~QkQYuLA=-v+;pKPTg1sM=ke%W2PBlBEa zfVPs~1z=z`NsKo?HYn2co*yMot144$tPOt#s8zV>EMhQbAoA7QO#4L8uC|*H7sRrx zBl5Wm>LizcqcSIX+U9xBR0UQ1=BYDqBn0}F0h(Ig6ft>x_c&kj`As_aP&NA5wvw9x zjr#zaw#u{49w|5=Tq9yxSx~hipTY@Muj$sJj##e)6fO?xYJ*UoHimq9I1KlK;7hWp)%B^Yiq4` zuN|xB%oBO6kzH>ZikY;0wt|CjF|oT1>!jSu$!sC%AJa@S5KbHVg=-FbZ^Et8(rOT> zO`^PJZK^H%C~$N}l>kPT_fO*rhH%8bgjK))pDYcdTO7j8DXfV>r-ZfEw7Uy6_-7X5 zEo2iD8P6THGxUZT&Ne6z#!=K#{?vH+~Pe6wjM=T59I}d z4Q?(}@k;a+@5o)!U%i1GCJ*vtIAl`X{cn8aczD#$2{56NM>lHn{0KZe3^@=Nhf4C; zE5H4(7Z;YUv%#KlIy!Vdr$??`3VB1r904(rbHxO2j{W>185tN_&8p`7Kp~&a{^tM* zCt3=r%n?tp&Plmd*4P;BH-h+$Bk0l6JXWrD?1AZ5my?J~4El+f)JqW^9Y-w>(s9ys zaGkv2L~@?#`>6_>NOt|hrlzq{H0J!o4Pcs{eFI5q-z-|> zLm!!_z!f-Ct&66;4WYY_G#Zu%kIc(A%tzo;d-eRX)OzS0D?-D?McnvQ2wYC;^ZTt1 zTLljjIk95V*QspQFrA8yDV4%PlfM$Zx3#5WJnrgg&)6yn1_-&hvJafqmGuVlbn;UHK%m zA@3^bgYXm)r?0d)JK5`A<>kSiW4e;Q<_>8DR8ike$B(ZEd;RQciE5@8G`6=T%`4H_ zvcHEXVI5;3Te(8n>+hiVFP3Pc7jAa#hqFH^KKc`!3LDgNIXXnZHw44FjFEB&zgufU zWnQ<#xp9n~^K&ZBdT#c!D{*GA2I@LzXt{a|0boCCX_(jqNIY>;t1<_DSDruGea!u; zZ3*jCM3WIGD{NzlNN{>)vOQ$+<_zh2f3}mKwFt1k*;~^Xaa4=GLLYTli$uoq@}Z2z z5Tw;@p3zlr()7*RaINL5Be+hXgB^bwEqj1xM=&(yyM$yaf*}UR!LV)Fe)w=eSs7+? zKbKf!wC_NgNRGkai$WN$+e31t+^)&7$2$Dpl-GfW`L*nFclUd={!lD8`;Gw)c7z-Iq88dW?P z3OQzd*e2o-@oQ0u`YMUq?2|f_NcairSvpU_0*l)@LfbVN6=iz4i*3K@%4!ZPNE7%n z_^23a?PPkL4(D!=6xea}4eIXF9T1|;s@JxTNvECG79Z_2dm}+*UgL($=@vey|NH1T zLJv?JJtY`kP`Ty-Z$?H=4(f*wd93cY@Ht~&n>r-t^Hbv#@V!N|qP1{@i@dWLAyyA+qhsjPPat|h z)4w0>@>d;0Au@Yg&~vJxVTzB)qyPV8`ZhK;BKpiy_qsw7-NsZXSou;3f?kPrY|u`h z<&+EQRm~)%{<6_~b(_crHb0{N=bqrKW0czGtDc|oJ9(`QiKF?Sjpa~5nve4;WZc@+ zSqth*4A)nY{AEw8Fq*W96lCl*I~SWdwsE3=pNE1k5j`t)(v+YB#t{AFF{x&_0TS_j zFQ1?4DpIjfi;_-;f+Yr!cI5s%yv0#M;|LWuTVV|KVTM{3O+qDg74iSIs>vF-QIxbwCxR>DeSM(n~UEPf_mXG%*Ef!y97 zoQdKSkjvuBjI1XPnOZtqZ>!b(Ass9C?!1$ON5OtlP=1_YTQpQ4=>@O{KCgiTj- zv~e}9&#y5S84dS$ziago%DyXxaD5aKadpL?=XE3b<`koMG(Oq;UTl~Wa|$Qpwtv}S z>)bz%eivW1vEB=*THYD2zhA}@i@7xfBU@selB188`r5qSmXo|UhQ*_}+*qwx1Ee_N zWL%tE)!XKxNQ2q`vycAD^&!aKVSM}&&4Z1 zp1y@ZSes<7VVCk^&=`lgPBvo;fr~kbKhR?oYrz*|Lq0Fu1ndy<8Fk_W-W@*8`-s!LAb6=try)e;{@EiQ)MuQpMTOW$`gyIIrXV?5}5W+8Q(12^E{VMiF@kVMp zA;Q;UgLQT`$H%Q->mIt3X}M*?+8}^uD2hIKnmNb=LB@E1MJ9FwcCrn5f-X<83FS_Cuv`i)tppvCLJK{Tten&N^-cpX#Te8IFT|7blBVox{br$q| zl7gJyi0Sev+$3eOlKZ$OJ3_eyw?Att?$;fRqmVB~Z8*9!oE=r)CBIX2ng=;XASf#R z8OMV&qZNT4YcdHd880OMyP3NHh+(8I*PcJb)H5A@%6#$&hKUid{hN?8pIRQGD z-bp1Y8nCz9hp``8$UV@m?E!(di{Hdi>tf8!@}F!1jf z>M|$NlK){e8UNG3Q}an*R@ShDK+<(|`+T+4esI|4;2M1nJg5|S^tV(;7o0IX@J-Kn z^$$zgexa+;68a~S>i+GQ!0Uc0Y?&yAVC>S2GMvKYE*FHZG z4Sw#wF2-t?=B=>$aqYJU;$KYT#+Oh*1%x^+JBzFT#x$lAJ^{@nPwc!ywwM1fjsH4w z{|#29Ru5Kr5HC`6<~*DPjK(QB=MXD%JCTTg)$@j?Q=(aBq0ys7_#mL4yg6 z{^Fj&Mh%}$*rYD3RlmC|5v2U)fX2(3sKB_u-S$v`Kdt~F|gH+NHu}RDh zFodq&>R3#GGjNE+)_WNn3z0x%I;I7BpX49P#Sff@UE1$!#bI=kXwsFVQm5_eW2e5S zM)*sun{MUxx645OuR|H~I+KsZu;cgs?`MxpVdrA-{jK#8*>*^p;lQ1`M2`3pBo^8oyx-=E~~FYL(wH^tt6=lU*3 z4ep6ao0yCY&RA5zqEHXjUx@?l>-`8Ef`4pNACpq=$w+|73Igf>41bZ6SzGHYCkH^5 zuh}WUY;|}^D)}Fgx_{w(e}mNjH4)?kJFc*xQ9FPlTW$-JSh*KEEs^Jf=MtYH@2D?Q+b)p(QHsrWy9vKF!GMT*8(^W%d&rEYoi+ z<%Y@av@9i~(xD+c|vdF!aYJ7F zaFOe>Tm8xS%)jf_#Ko6qVH}VBHXN9CRHnbF4FQKguDnSO)Qc$OE~wx;VgOS>=5|iu z0$k#U-PsR1V#lbCMzYUYJ&ZJ-3kAf$oF69{RVN~gU!$!&2mIDsm#;2|XU+tZnF0|d zLzn$jhO5`jo6$Og-EcV93)-DS1GCKv5Z?sQJWKF2BvZu3J>&N?@MbEUug8&27CwdIS+lfxc62=!!b z2j-yj5(b{-&+!%noYRRQSuX_IH*nIijAqWc6Mn`0R&5b|Tay*CHsIk!_|_QyB#!zX z|HYu}@|brK97LtCoaUP8vd?hHY5U>rnnja$Z>;a`UBF+nBItfs0|1ldp0=r^tSrv$ zLCP%}qiSK4Y{U?lfJ(N8C5J~xy-E2RpP8oQt4b^Qw*MkbKgjyyZ^=qDl}d8Jff+A? z*wS}o(LBE=E+f8yVv8R!qHZ}UT$iDET;QH|2%xt@C;a$;V9Vts+O3=)!hfVTE1Iq~ zO@Q5*9IQPreTCg}-Hbnsdz2^3k9q`k6_wk{>2Mn)bzr);5zX)0$=T&yR{XNs;TJs} zDK^A%`w~65#oH)cM)C0HRokwZ9vQ@dcg$V#r_vrQoL2sgCtLm&f|$fktVF?N2=+vi9W}u;q0o!~aszS}PsHg7D;O zqj~;@EUv$_nBC=;dZO5Lws_)4a_4@Z!W7R#gZYSWT6lAc)DDLwe2Y`sy)3hG3htMC zT)Lbrt>p3U!Gy`~oKVBNUgv}Urb1CeL)tgV{Ph2(IRj^NBv*SvH)tRcy%U`B>~~S! zJtoJ3r~xM(Fb6P_V?xfg?@S1#q@?y2+%NIpzI(fp!6vKml_uA%TPb=iz|5Um1u6FV z>Kb9wrIe6UBqF6a{`?`a&goBG3x+e(?oUj<3XAlWn4to8DA+<2dBtCRw9f)iXjDoI zp6iDBcQt&+{Q~D)yjT3_U1i|zbcEUDJ?xL9AeO|mT2kTUV$7KUo&h}iGjRN|#i9hm zi)L;5J%a(zQ;M%yp{_W@*h0+CF}%h0Li^45-Pn4EK#A)>A|0dueWTXlOaLc_nZ;9o zLbcdkn#oeeln?v(WZ9!Ny@RB}wmHTOx*Y409D7PC<&a-;LuT6iO5XPft$w`*A#^7) z86oS4JdK_Cb{bW6sAoXrBZ8q%(~qt6W}Pa)-8~APNGR$@M90? zZ@{K)@M8bcVC;+!+2?XU>d%x}qe%zqf(iEvp^lwl3 zkorp~o9O!6(;Yji9}>I~til|O${JBRwj(iu`OH>m_Vlf<@EwH5ueYQ_Z^Q}QvQppk z#7K!2mMHlbe6XDyiD$x<;C5gGj;lkcF8bAD9u(-{m$s#^l$Fa?j#-=FZoz!7+>l|w zhYe(F{AuyW&4-$kwN3Y&{mnSJlz)50uq^REEweMiGS&?wathL4gZoznqK^kKn{2TS!L?h)Kn2)faosF#ds86c9I+nA; zBCnW#__WJAv+MHx71Q2AI9&$6P)lytN#!2dF@qAf)Fr`vRbdNviJv$IE*<6K-HO~( z6QT3#9;5(4=Rj#XNBQw~4A`jXe9D(&P(0Mrrha0Eox)^)ir>FaR!faq9<>EBP)mxP z*WzC8YJ8F0``#AgDhrpsHX5nL*fv#$eNnkt^T8pT38WCK8Z?&g z$#GvZwH#)JTYs06NcaNg+~uF%s*lhyWDrxF7S&pV)F^u}|5j6jRY^^{x_gFNI<`j= z4w`L!bo2?IGX(=8-F7r>%6XAfq6pk%P?2(CF7Q||0t1zbI$Ir-wd40vaF3&dad&2* z1f#c=C5(z?{T-Rw17aL7Ov}xJx*AKdeg4H%fOQ|3pYeOiYQ?yT_-0wU_mGSgVQt^( z4UNO*&SVAR1>c(`&y7Z4s>%X`Se;uVHfbfhz3SSFU_dfYk>W?^o!+l56pH2F^ei2> zapn6NSn>E{1j|01UsN^SYlw~ZDv9`}*Wbjz@syVd_~KfhGpRP-mwfz6g7&dl&rglO zhHpO0spS^Wdab`DJgzl+3w=-GW?bD{#$VuOVL8dlq zsNqG-jrJoe>rIv&z9_qj%qIl%w}@o8Tp0D&$Z-OD&^b$G<0sdj{jy5k6cj6Mc%*=R z$`q`1#Vq}DZ(THZrhKmJJFUb_mKL6gNAdhsp@F^HkCKnlLk`XUms2QY zylAr{aoGKmhYGD)PR45f9yMKXpFvb0=zHqW_15jQ=J`BZGlFa;p&Qy@h|*U=E{Ja}B(^dL0bg+F5Nu4}tx zjTD!`RkogXnl=qx@!%MTRzo1siRP`>YR>{;P~dS=ZQg^cj($x4wvh%f^*-6`WSgph z<`j6NBpX?`UN|l^L-z-J!L=E{@Ie@+H5ZnizR?_2iik}?fjoRj5*3<`2Z&P2)Ml@_ z|L$t=fbBEE_}Cl*WT=lWEL4i&IXFpyy|QS0fLjZsSK(nIAN(;&FM|HfeJR?{A;K8%- zJ}H|MO3&a8wxlOf~RW;b}CD~PlS@f%?ha=e<+jX?{0uk2yeRe(_Df-ZJ(~hEhDz6#( z@vC+YQ!+Z|5CV#Lxc4_kigbkd)p9Mb_5Er%pR8OZn`&L~P%EsRT^+!7%Cj{S(CAui z-Ldt?fSHNHmZs~b!7kbmMfXg&yCYBk{X4-U{ro1^B$wm3o?e-!`mfh5w*Hjfs`x?K zd^p1nEnD_3|9d$~6ci;xgNr7S;(DqMOl{!37GWcLC&g=f>BI{zC0yI08)M zSedv%w?{%kzMV~XuKb5xLW>8q$zh=bahYj3D_M?2EZ%3PqPJhfpt%D|T2B~JzFM*L ztO_x{`Bo1Ip6nEK$Zty;F=PdOEsJTsVh|^9b$YIbvru>WF=~BleU20C7e|ge$A*3u z@I+4Ry7IS$vK`}fts7F%6*GD#L|qtp%B`#Mb6RnIS80Tq>a1JbYMS}dy859Ud%eun zF5Zqee^_v=C2Z7tu0py#&0i&pE;2IlO+5%(>4u{+PQi+laZC|cgwYU;otzY~-)SMQcPX86aY=z_eL=s;LgBMM=7fF`k5vrcxsj=>@Yi-yTKvDAzykLhuNO=-bcP z5(Wha9}G*9Ls8Ij`2hrx6VlufEO~nZ6WNmcYV^gzs_fVLTfszdan&OU-kJnd47Nz!!?(f;FHN@)rkd)O_tcG<~LQr z7EIP+is`hZA?>733jugD2j{Srs6@QHIWg1>#hH&>i9aqm&FNj%Lj`EScs=o3v{aUBdk*vulR5qaZGroYIysp=Hh03S`DhVS;2-rPTvH-uYlllQL%0?75wgx$-EAb!C-38W6 zX!_sf+#)qL>KnEW-d%ROw`NHvIh?2M=>cBWVaIEAkX;2jaW2d<6937EtXOg}8<29d z{mo&c1tmN-*1xmyOyGL(?m{zXtY^U<2k>RqzNUaj^c?Q;@^b&~wzp|9Vc|N)rS!W@ z3C}yw69aKU1nAI=(0XonXuXS)lAD%b46|nX*S-|uNibFtK?c}w{JW$%h#+! zK3ebZX!XS?w%Z}Po?CE5DR}y{8Z-m;2LkOM1^l+m{wvBWUhM(1MnHD90rxzQr~6fv zd#7rZg`}=7#cLY;%DWD2m}5f-_LE=_8{l~KVlUzJ_bwM7?VlFie+*YrviK7yW|Xe` zzxk2H^+AK`_tN z|0=xhFM+LYT@z>^CS%75=2PYTId0ob^go7-R1nAbj9vn|72>$L*!DinSIJNL6?6r& zeq*r#IfhUHpznNPoq`!d3D4 zSyEGhq*pWyOav;Ltgruv9FgcJUHMzZKm1gcTQQp)2Ix`>R8UXFd%q7|QEv@@L@1tl zVuF3tVi1c|Cd}P@-%RxbJ-iIytK0X`Mje8jPE9PwaYi3g8Pq71pcvKQ4H}*;`HAe{ z!ZOhbzgnNIPw98aysJ8vybBmSBM4Q)N1q0f8@$#fT#eLwMAz@rY*t`nX~e z9v^;R`g9nriqK;Mt6O~^1Ty6Li|~K`-PAOK*UbVJ{$howY)Y+v#p-}tBtd*Er1Y0q z7K22VW2EJ{YFnYK#YrS`~_Il~$M$0LP*pSVD*raWr!N{d>$Ff+-$4vuH>!tCV=YS`(Xib#FQ+12|} zs7(xMRl$|YjY*W>eN_*xc0v4VbkRt(|Jj1acy%#{AnH!BO3Tt4-J4fm@>t)Ne-^|*CsmZ~mR1|XjleT-$3g>Cqx!!4pO#AGV{Clj&1fsMHLrj=Rk%XcDC$`3nr#eLv z_zV#!=@6G&NGcnhpN-r!$`nryfY4QlrsP6&)XaRlO$a%h8QFzQ!LCOOY57;h@K$>5 z0K(Dq*!~0n`AI?7y3S4Q9AsjC#;k)dngNJ=1F#h`tLcY7nl@6b5v=C-sObs-$trf( zK**BnO)-o{_2=vb@{fgY%`C`ABBc4PuORCO*PtKhXd!A1GN7EdZ79ci@pb70>Lw{* zn^X8^NcBSr5{z>VwHi?I4YR9{Jd^l}_9wXGO zZk^cE;J1R4azg!TyNjY%d=^XDlSmIaTg(DYBXQRx+Z=(;?=8#h8whaoB|-N`Q$zi- z1OZw5yI=928F`uDFIGbQ$m{!}YD((p1<)r&eOXAQDdB%dOI(ATeDkm3K0LP1f4E zfC{xa|2wYZhBQfE#rV%*5&PS}4~Zn=1pol+zBISLA%INJOnF8T6+W$O_JLfZ=RGg1 zY+bQ!GbjU)zU&Eq{puP`lecVWQC?EtW{9zAv4%|eD2$_3HI(V}G#aq()BG1-9Fa;S zq4~RCom3aMp`QoGQA2AmJN8@1ad#p`aLgj)xE}%Hc-WgRlOfuioDlj-REqEYPt6Uu z@5M|no=UY@{JtB~1OMq3KUNwl0O>kJ(Fv8&`zpk{ip)N@`Pu3I|tesbMh1 zj)iroX{U+3O9H+$7|aisP7~%!OP$p7QvJu5rjsW#PM!~+f)zr>HeUGPONt1g$;bpq z1hE#spYx_#5z{dPL>xeft;gFF56xrHGwC4yPPe$nv0dll5$t)-M6iGeg*IQy2)>g>o zK5ytFux>IUYa+WsWR^a#!`)X7Z0lVrRWS1Z;{!X%i8^+SX9lRQJdeVHH)>i*C~JTm zX;}(_Zj3c_U1f5Fm0P3HdY?Ncv;r3xKsPJLL%-wicw6c$UD=WbEIQo|dOxzXx za7D>hnuDw96fBGhpRDc)fZX9D4hKF0N$i;{Gar>yCjjv<3T6R&3$uVt!YdjYIz@l~ z>mi8(;s=J!gg)RD3c=J5tC0a#$Ezp}uC`F4mIScijOwuvk5f zVbpgR|CY!R@`&{BM2^PnZ96_r(@75uLS`M{g2^c=g7wW;B7bk*LSV^bzhh>r$J25& z4B7%Mafj*245Z#p;SL5~e&hn?Be33@ANsk6u_)GRnSI}w+5Q8uyDzf`maRf8I?~;l z>sJ$xGDtE}`)efD3vrvmBEERjH!S`D`z)$)sm78$08@XjNPUF^?$4beoT{P>)AB-X zqOUfCl5_;XRpyslMW{(T?+eE1{BG*%=)Ce5pZl>psiVEAy7Xy#;r*GZm!<&`ag|I5 zQ9eGaeqr#Q7RJ4?pZAjJF^`^>Cu#F8C|o9e`u23zg1+zgmLG1~6YWh9{@cgTUNs|& zw!BHy!G9^NK(K;n7@6-7O}IHLG!SkxFs#>ILOSCpK#o&!z8yRe{z=QpUC{gM=F0?L ztj!k)&p%m*CnsTPehgw4dkk^c7D9G%TCB5#^Im5bo|p=xcSK%^Vit*?dZPT9#&&O5 zgNx#lZsM@ZCmqm5yQG-y5pqr9htnpsj$*Y-*Ogz@?G209owYaIeH6kk?|f|=>bs=z z;)*H!o7_`vgFHZcu>n;>tN)9)D%JFOZ)2WXam&N3e8_dB6`2 z@O#hT@|I^OXuaMS$>X)CJVkswgk#l=Vl{+veg$zCV%-pf2c|ZrcV>LdEYv$l_=b?x0O0B0jruAJN>NIx%k$J zF@IbXlWaN!Va`|WIoCY0h}*uFcj&+=h5p*o{xRT~a$}SnIB!`sz}`JnH0o?Z<(>EG zhlRG>n&}TA1>sJ2BV8}oTwdN!=fx~f^4w~Mb3lCj&6GZyMIC)PQGJLwq^oDZ4;wD? zmqJ)fL=Xfq^Me5;6&r@%R9P6;px3eEgY(O)VaLozqIZxHgE#(RO02&;8#bRDGPIr% z=7BtqTLQa1Hx!xmlVZQ={oWt5)G8edfzJrv=_+e1H+&0Sikrx(t~ASWy`V~D%n@EC z%@Ug*{qgqsx^l;yhil3Q9pr&j`xu)Pg-p<)L8r_tMQrNpTJVaq(A)i}pRM#C` zr#alZK@o6Dsi#V;@EOTy3(?e&IlW*GMfMxc-Ld_`D6_ee17EF9U+)-pV?M0Cai2LB z<6Wg`%hg^}=E1ts7r}ieN^gzTLm>z(C%3`_Fr3(xL>@Gh&Zm!Oj zCQAl~#>P0{J&kOr8GBOqjQl0}M5&a*D@rh(cDU>CNs-3oK76T}4f4XK-8P35w?IcS zOeKo1vk@74jxBja1)P0rh~+fbC8mCC+)t4@n0REsH;E}G;^~w+gKa1Ymk$MbdK(^! z$x|AQD)JxRzo@BzkiKy~zAY2YWZ+R!N*Ar;4JEvkTacl7c%tPnJ95jJ<`w0)oXtTNJSu?wFt z*3rUO&7rBO==dTT3FZg{lAed^@bUKh*&15Nw1956uC!5e7?>M zW!RKXxILS?MZ;VIZslrCj_Cmb=6Ztxb7yuBIze^(P*|4}Xm62!|`rLfU4o_6*0cy0Bv$ZOwW$77R< zTUZp?oj%iNUhwJ3>36QtwYN)6eR)Awk0{X+HoWE`Z4sUu@qSHDy4~Bp*>9SNmI<$) z>;+ppueWJM&QXl6M7Un5T0={z_=X#G8f)5MPQpJ_eokoKVB1K9}ai;k& zS-*lOW!;CGKm`{obn$Fi16;0HZSN_bnvI>4w0Gac>|}9Dr)P$5Z&9kxcdv%d&W9$( zd_9Y%S;v+=xlJB?%6=^}0X+Ec?wAMM_u&TiT#4xsyyGe_Y0lrcplSP8dJgM8k8OJk z=?JBmHOeUzt)Ou&9aBlmWjN3E?N?#EY5L^yxx5$5P6koB`cc6{b8-c0=E~fx)?BHz zxxCL2NAu4PKeg>5GIgvyJR6uiOK#t5dM?Yyd;9`XUryH9YkgtPgC=&#pN0bTDIDdq z8_+^?_3{hoJo3!B*I9bjQ9;`@XK;pjshMzn`0xXt>9;y)?PBM}u96LMDelV@cnSeR z(YKYe1I(6bWjKv+LfNYZ9|>(cj7&_#Ko$w;KB?rZc}7JMz+AYluCCLsemA}f>0l-Y z)}kr|(xf?~GpB>BUf)RCBwUHd&OHPm8i9h5jkG~vZhDG2oEYm$PwDJ4JxhGVxb&zr-f#?#ZAeQVW-N&LHWBqgup%xH1(hAlM} zb$*zs4*uX;OOQXUFzrjB(R*WugPD#}JHUxpJ19bckhVFfaZJG|faFKNnY*g-O7LO@ zAJVL>s)+;vK?8!2#mN%=+|5E8mIa!ZGHir5i2c*y;_L@5D{VWW$4eI~I|1Pbr+dzp zS9@8zWi+`}?hD>CDI0BQJE-6hME&y!GVNYp99fxNRCM*Sr4}`jlU1RBN!Ybfi(s%! z=hsi;m#<{T1_YT3Yjrw)3hLNWb5dVtI@(B>DcHxoSktZl$&^)Ps(;Lo|0F6u8sTe? zR6YlXPRgj)*s8FY?Y@TicNHorak~d2NIIz*2p|=xw$S`IE4w8&2|?R{rj)mq6#^$J zBG|_@>(P?Wq|ujxb#QEa?&OMF#x@)o8yq#joSFGeEcPp00Huq-9PTIUauZ_CvhGw; zf;DsDNa>ZWC zlu*AoT8?cG@%u%@PRyW`g3@yp!|+Fh!3I zFyildE!%NiZyJ{!&^4+lKA=NfT5I~!noErT1P)$%T#RJH_c0{>p-1l=mY52Wf=%R+ zm866OQsY60#bPf@6DC&O!4G2PHo*2)gfuU81j9+t@v6vdaNcF2dOc3vpglg&U`p}MBDw4&52I3}owhYeC(F8D98N7zaXUT3qBZUVwGM(E*N)=o z0GfdAiz38yMsWiJniwW^uXh$TNB{t6p{pg2XH!c6T&swWA9DyGINfv|XDP~22&~Mj zA+zt91gO{8e#gw_#%a4R!w!$E#$_h{wTjtbG%oOYT%RSE63(7(eQBTu$ob8U*O}!$ zOe@(*#g73Ov`r8U+e&i_{5oASMtr@^cjK%V|X> zrBHLOxJE#0CzTbBc=*!E}kdcOG zQi|2j62w&KTY_|5emG9^-P@G}6|tWrfu~1UpfHHQq_@UpeIS-tNzl3-J+$hMFZ%WY zL>Skm_(8l*1?Ji4`|CVVc7fcMfDgSf(4DFUWJvwlymPK@iRds(* z_(ejIz9>f(R1rE-Eo_HY5n8d;_1tf^w@Hs4AG~vq4VfSxZ06qycv63JMK*gI72vGg zNl$7o?4!u{?3Lgl^i<@e*^$HBfN6?deH=vNyQ(UYexrqLduIz4 z*KE>pHP?t2X;_$M*s9`3OXgs!n9Ev=&3v(!wzo$lAK%ImYoS0Isy0J*`&oK_fT+wu z37B_Yc|kU8z7J)|dNPkfG*6W_K$2vvDnxUa1l0?B-kf}Tx-RT%u9(H$;xsa~& zB_Q-Y>gQSpaZ_I&R=VH0Eq?M(hgdF6oE!g)Dt;v7cr7#Qv{f*TC(e$%Huu$!?=__$ zKX(qP1i?gLQp5R94FUhrYnsL^qR1c=@(FAzN}`k(hf~yeAcQANK=<3!vO! zB2$UW{~UM@-$$pd37+=gdrzJeiZgVgJ#CvCA}A~eyO3O`RMMi*fqVJU5g`wwg>*|M zj9*;P$ehc|LpFL_DGa;OZ67jm%^A~k`d^L_C&{(@P4lLTx_MbVXUHuCW2iJ%CXRLw z5j8#F`-iNq%S)-mD!%8S|) zpo=M5hK7tehho?r^t{>F|D8EH=dYd3=fymfSLcWx5tL?;P0ui`?n1^0bHLn=+~H}> zrK8QZa`irJ356AXdZ@It6dq|P!!$1XOhK{QR?LlA9Np~)hkn<*u~|hwWE_()AFZ8h;H2I7R4TH5}<}MUZak?(TRW&~wiJ&U^3NnLGF0S&?Cu z<=N*~-}nSUarG$E#s-;Wk`z0geWO&Zn0n)HpmSkZ?1S+OJRBfBj{_A=7EKo=eW=-b z=V5j|AkfiX*UVQTGb&NXQ(v}p_a!RYUGo#C z^~qp+{SAGX^Da)d_D%U!jGo{^VY+;?aF{(&O+UeQee2V{Bm)uwwMKHwSM2v*pkqeD z0|2wn5{G0m?Y5k}ma2*U6%8oc

    k$?JW!00t@}kQ*kZlu+ea2Cw|DS{J;?}2-Tg& z+LazsVk1`xY|Cn`wGMG zeBPT9_3H}r>OgAPw8bR(O^Uv>hCAVmFkiUJ&3wCt&BXH0eXUdv3$nrH8gvuqgRZUC zCaB4DFI(?h_CY5n(M0`-TPGf){qJzEhFKn-1O9=)4hJNKyzf-{km9xk#^ll(h|0^p zi38Dy%!IW>(tJ=u;o@B}tR!6M$gO$FwL3Rn2Q=+2s#3ClvyLiwVu+4jOjPGpk*Wik&yKQ^&#*}QmNFLW67TBU*iK1=@Ff}E6Pgo+b@=gfYM z_&6gI9V$QB3`(}};Z;QfX4XH(2RXk2>tluKn zHr}cinBYGe%DSWuT5uDeL0eRJnJ0@l`3U++(yg@ZqDcGuq@fL)j4o0CbzRn5CXNNn~2Cl{VI;PANazTa% ze>kgH&+VH5UhA3jz}ZneZ8!!3+r!>Q=zFDas2lK*KnJMXb2tOp0s;dlxiSglj`t;A zQ@6b!`QM49ru?p}>7Uc4rawvx4+AdVUQBTLdP=a`?2{S5W}5IIFr`yg`FeH*#`S^F z?7GB71}rFliH~ZRUJV?(U3+Dr;p<<B36z{!~%XOrgA5;7k=0&cFaoB30{>d5NA zBheEnUpn9^{dcPl&Kb{Dyj$r5hUt3l&phCo&f~aUv5#g{ymiQuY3#jh9$FAu)rw`c zqG${v9p+lkTt@7n(mVxo!e?y9tz3UgaB>I!`0=AY_r0G8$h#GMnwuO->EwI{0@*uM z)?_bl?{2?#f3ycWSU57C+Mv=@VgW0j!T>gqJt8i6@Sei3@CZO`xiFkS1oa-)BYMRDHoC^@kOE%#|xoLW?+wS@sBhrS-E)s2= zQl6Y#ExhIMJMxTDHejFxFMH3lx2S}9JBT9)PpgpL36N(NFK&iMMxGPadf#0SEy#$I zG{y|wex}s9+pasRSkbs#<%WvZKdT@X6f2D@?xs0H_1svSB^UI@5q7?1kXlG*UEyBx zUZlpf@ubDaz9;GBEBw(aGMz#bRBL(`8R6jUshcxdPhu z{JmE+_B>rcW3*@e9ZsiCu(@ZP6=E2dyudA02Jt+7K2h5*G6K;4K=-e*$hkbl#50#L zp;6(ADviQBRqP;$vIqiK%#v+#hvurv_Zm3V0z^sI7v)A!~uNeKH^@G>rtbUC7 z4jj%n!-y|JTWe;;Bp857Z!%bv93pF2G_EckB@whrZOfC%Z|G5|_{EbboXV)l3Oyzs zqqH34iw&CI+Uk9o%;q#<`Q{gE+o?bFo3xiiQdIt?K+H@`5)KXy_1ktR{zIBAC;enFt@maHW|Qj~ zf>As+zp)z&mB!!i-T@&q>51*Q@?Loi#4`TE{8sDj;AvkzFZ;o4J*yVEdtddya zxim000E~@%}$)F&`l;2}3d0)#DZUE;X7&D64%LA3)5}Ujb z>9pJG6p6-*r>I(l)SHo=EU{M|T9x&|CZNo_X?^%j!cV&dubo=#pS;2t!^D7go-+AWPTqF2F;VWX zjY#9eZd2!J=W>D>_y(&QE>mvR-i!m~mp4l+Zs?HTg!j8;Kvjk2!!lqH^!m#klEU0I zO-`v~O2wYqVoz%XX;_PA3P^PPeesy!p5~`(q%RD-;sfI}H-R33zX@k>*FFxcj@TlG zuPbqhX3R^>xAf_f1_{$Tu&(6}CJuu%}J>HIrg5g4dHDe%yTuzdT&bbY{YggnokRb3!G(x>7s4+6s7gxbebwt)n|=zgU=d zWISBILu4WSl#JWLT+IZDVYjKxw0>SwgRUTDA zZBUNyn8^yVcdBk8;WUETbN_+Q*6PJKo$?EaYAd-**Fhqqj6e3&S$zu5q=|1drS|Z1 zml}DHOx-2lX7Pq@_$=V92!8=id4+(pOOUmXn7{yex{ug=i_+|TIdE97Y-F)%=+#2{ z=1qG@$*vA(SD^RnnZw9HumOvBV>dVF2jd%FuP`Tj+2TbdsQ&nR$i0dgaEW#%4==cj zem=aqZao$9K|H8%`=y&TC+D}RRc_44`i2I6AV33jjp{pC$~bPf!z6kAT)ph$mox-? zQ0T6Qi|090*Bx2|c=Q_7hRHV4+6J={PSSYvzL(g{lWAR~xl%%|<_?-DmUFciI`6`T z6)Ik%xrt|e1&JcU=XcEFg4$f>eJ@8!Tu;0uGawp1;c^K&QnERARy6l^S&(0yc)lK= zt%P~NFxu9E5Fa^k=_F@{$M$b;NuTUCFvB(H-Nb@%QQcCEw`V=)-AGE-0I)!NltEn$ zWLFZQyF1E#D?L<&_f#HZ?a5-R&KHX@RrE_kHU($;Dd7Tdj&Ct3vb9zlq}K5V8eby+ zDj3uS3#Z0B&yVFm1^dttJ@D#!q+TB_jf@S0^D7B>@+clk4lDJ=k%gp)m63cH{XF#roGm<2d%4^&IMWfmvPQ&2{acIz-Bkcg}wj z{U0@SenhC_T&8vEGEiUb8xEmyMnm8sSz7xZrz5dykk=GR7M!?B5jXfSK=1`TS(^_1 zoyQ6Qh(>!XSXRJQ711AC9mNTyI`~nTY50;obR)yS_Z8=KB+#1zEPJ1t@bm<4*gAq| zl0V=x#9A_FPfL_GLXE2_fBGR37s?`8o-vfEcxK?wy5_l(TlU9nrlR|=9Cqoe51*k9 z-LU}+I-uO_p8a|ou%IhqnR2m1O%_;fwXpK-L-djs5Da(w?M%y$Li5$0QD$ zZCm~g22N5L+8pS3#g)7&{Sg;R7i<8|qBkS&<*XxE|-jnG6`E5h9(=Xh32vzknl&|5|PRJBn}V3(sr(p;LuC;0Ks94BGwS#L>vC zn6+^Y)<)$uNreK96ynXL`)l8ccVATW9ODy4gTpjcBIDzkk<0Bjy8A2lE2zm#28Nti z&y6O%lKnXO(g-^jz<|%ghr`ny<->y=ClK`ITJ$aNa|h3y>j(Tc2Yp1>O`flsxg-P% zE95PAv}<<)gB+`7W#1T4!Ma~b2EXP4kdONQpKw5RS58+V-MzmOUK4sQl=cyj=r~b7+eHoeGe^lDExTh1RM~ zgXuyrAUZ}}LYK?r@ggo+B1v52@+y93xb<2ROwr$(*QYOO%WeC5;UKg7A|JX*TqOlO zQ#CIP!Jb~nJ6+o48-9+KQ+a6&1k9IP-yNA|o}ZwM)>AH?OOG6G+k9uW;&mO+4L^!T zY=Z*d-~WOd=k&#{+`klSbIcA!C#<1bdA1lm&}M@@dpP8Y`AdioG2dAk_OR!UGLHz3 z*et3NRrEwf_2#sY+dwTU;bJQx*{bv*8p`uV8s>7?&lFr66VPwgzLvA-9C|tI(>ax= z5-^qZ%#e9UP+YlmhB-Z%^?WE3AJr z&tP)m?t7rJmcpFxhPvB_`hNR*IqU>IXx1+a#hc>maN=}1tOgym8;xt)4e7YJS0@3L zYS9|F3mneVcZq;_aYV!$eH&Ym-#k$Ig3Wu-d*)QY+atd&R?W866o_;+yP3^*LwhIAO8etz6^R4|i>(Adi-^H+j!_;Moj_cQZxth#}MW=Iy0XqrSGt@Uk9@g*{yy>At=A^>*#*}wYc5a-nnN)~ z%WN<@FH~?+^x?$Sm5mB=$1~EletQmbyj%w+^Z|jl!ImZTAb}qdrBx0R}yG%>}-YMSIVLMUJcH?Y?JtJ?XI(76jkG-DvKwVoU=no6n>0< zwacTXgba5H05+jdk73x8tBs76-RYN!>;Qm^Nt12$u)>9GUvHyx(A>DG7FFPU&ObvE zc~~Z+lV$DjX1|-C_h?#aO`@#<4+m<|tF-K^wQq)7BelUFeass#!ZmLRLt?O$VD<-hVF8T@K3SJ|d z&B|tY%2kjq&NtdXrDiOR9+I~mE`x}b?*FnUN&)aE|8#T#dYc(9OUe%68Cv!vb0iCMs1h zyU+ zo^~3RgJQ(t{L{Rl3mmP6sEjFc~gN6J1O#ms9Ck{ap-a z({;)sBgbLWI*Z$!F7#m#S!)C$17l|4$BfZ8(dPifU$aV`Fy6EL|7%O*R{;@eu)aI-Fys#yhR zKS;KERk;WlxfBF&a}*D6+CGM_n@cz4F!Ak(%|bk>C*N3qa)0~7_?774k2IoTeBy^? z=0dkEq$&=a)^GA{F?Ruq_bhE!8=xo&)zoV{SVcLDw;6=A1t^Qr3TTVpPN2Q9s1v)s zitb)Q^SX%WLS4_{fm-Uv$dwAm-ZWLJg_Oy`45p2uA;{OjIDFVzHG+Jty!(tO(&+#u zY+HEXBW{~`2qBY>fcCDY#z7yzJG%BMjAjLZH6;H9O`Ht-cU?xj_aB)}r_WysHXqul z1sP6p?@qxKdnoC)^D@ok>1#(V*B>7sGEcRPKI_j8DQ9%oLuPu5^05kj_On$k&z2RG zuQJnH#NC+K)!`Z|g!4t*CRf3$53Xj%kLxel8MF0SkULb<#n;fSNi&9*0bg?W+C0SJ zEF8~Jt;9yD4jf@$QtHM!p(3vO{xwC8%CMVRe|+QEz(%}qSVoD%@)nK@-Sz2QFse&$`&w*Q`651c z3izj0%$&ysb6fg>Q2+;?)wDlqmT}~#(7pL!)Zye`kr-}2O*w{_@?GeY-GrVFQG1KH zo?c+B{!SDzpl4m7u)?aNus?MF!Xjf(*x@z#jQ8RzP39XJkk4G%K9&>R@b@L~eLmug zaoU18%YCN?TjSk1)!R*eDB!$EG#F<9?m~`c#=k)^Ct4R^3^Z}rUxeLyJ59-pS*9?k zd~4rh%tdK#AEt88LN4RSGnMsVo9lsU21${eIu3yxGk=z7Bt%UzP)`r?hJcFVuiAJrrFL2`iK)V{zbnaW%}+s8h*?xtFZfK*j7#E zeQUPe*5T+vj)8mupS~GE7Sa&K>+uR{@a?GjjG3enLA3wD8jrP=iCCnFIM>JB7i z^X)aE)UEUaAd4C2&8{u;xv8LD{U8Jz7I=^=VVzNeA=I~Am*xF0G+muYGsg7sE3Oud z+uB?^>aiOG`ZWX=;ZXHN6-FA!swrrJJ+y5{6Y9L-)uXc&E*3&sYpvD&Dtk88^xSh* z&qwBEdMbYxChE;gbqdfZor^ch1Aci|Gy#UX94=JOyT{)N1wYIfVT;c5blFAs{SGC$ z@k@!@QB4Prx5)NX_Tig=aRei0E69qBkK zuk0sH9U*{NJv?w%fam>X2-x(0OLz$5Z(2_l4)X!|8-V>sd|z8>-}`6?FCmejBIRyK zV8pRd5<)ecQTxXXNlxafhxEyzFi~sE`5B}k4+`Hw3OMXyl&GI58LwBSU;ideT$|_QF9L`Y`RWtrfaYYzX5k{ zM|}+8^Dhi^H0!dEx>NbCZBna+kGjm=L;M;9TIG!E4ZBl}A+8nQ!N3i3b4xyC z*MWOciC(d~{(Uxw&xb?7NQG`UvIn^Jf@GMyvlVqMB)LT2Z@lU1!_J!vdJ3m*2n>7X zOSIJ}++kg)lC_W(bNX0GLdIrQR8>K);|F9@3Yj<}MdDt&GqVCQ7R2VWrVu{cMbP6} zY4gVP$+{EspIj7)UP~{0PM&q9hKka4@d)~=@bpI@4r8{)N==;$<)m_Pp(B&l*RO!* z<5smay!*MhsVLO3Lk$(@Pe!|ob+uj_D&iP7-vWfMXe-hPZvpsYKCC0?TL{k~*=8ZOsMVN_i>Xjn{OP8K|}6-Z^M zCxBK1x)LYuRD@eEgg!&8Lzve=4*xllA!WqUL>f)32~!kY{2fKZuJp%b6!Hmgs_!yB zjJ@Lac&bk})VJh2M_!%Yfr0VBTxVV_hj;WNEu*FoMh2GdGXNF`hm8B;k9c?JKXC*q z0NxRQucpT&Wn_KYrqX99Nso;a$`R5LBYgp>76B^)_IB75xe7mj=?)W^DN&uH1GW$?NG9I_?l8xC&f7h3vzL;$j5W? z8HG%)h43}tgF#X{zO*rXz(NVfsBCV=g8%$1z1z!Hi<9DmYL{l!TOyE!+oG))mVvvi ztq(HF%!v(4Fm)Z)Ue@V6Of(N(d`fYzMsV&qmZ@6cH%_e5KH=F&0rP808uWhf@`d`?m9WPC`+xw`Rz$7(|iWttP<7dsknF=ofw@Z ztSIr6bHCPrN`9>C8*%0nMh_=`96ZnCz1Fs^HYpK{NY&zI}qMglU z$H-nlOPR?{pREfXDwte-s_6UjF3AN@()*TC4wVetR%g-fFP#sriJAYr97!uZvD zFxKHC2zhx5!?q&E-@`qy?+mPe6XnuRmqSw4yrt6wj&9W@_0wd!PE@~mM~N$m%^b0q ze{M*4HCt9Rw_$eLZOio~?{WSX7mmHaE_+sX^8pKO-{rggs7$7v2VFrVi7UEXA)-3x z*Inz*dt9TRd2Vu&@roy1q#;;o_LpXy@EywN#DjyfC;@+%>NM!UdHy+qE_~+6-5Fc@ zo`HUIMiHrcS3}i|=8ZX_len3{b{#rbD{)RK2gF#T8lwikAMpH^GOOf<+S^O(<)YzH z(6M7gb$F**y<=WJPel?!0d4rXuVCv&c~AKw>lJ^fE$q$A*y)CQ-)_iab#XTmaF(wd zEH<;cPYJycATA6y5IEmA_j@;T?TGy~^J>hl3= zSEZLw6?v5ER<7^L!`-NhuUL2qLwp1ctBh=fa*S&|aPG>J4LD4rl>7xFS{PA^3{$%d|GiVi}*A#XA96&1KydfJgZ(Oe7^h9+4K1PbS1adI}C3D90n#vY`wn} zy`7ZxxqJR_mL=QB`&dz;Z211@hL8!5fbgg?2M8$YG`V6%Mn<{<-jzcW6Y!!KVo#qL zlN#9Oc)mb0hpFDU*&Z@GZEgSyn}90NzA5)>YITMPBPERFYxeMCT~jkCna^e?<1Ki< z(A9MD6^`tk=yt6oROnLUZUjou4?!88x^V zlSi2u7(`5DKhoUBbts$M^lJ1*u{+4q{Mbmsz&{l?Kqr4X+Z@9lN0kjQhEXNhKDn~J zy|nYZJ?g2qU4mxOYYIgN-(rw?onivtBZ_+4x7o&p#wk1UpUGlShJ;ZnUwaOnos#F~ zBhU+zDc{}?xu)6c4cr21oXKv~)(k-nX0wC1yRkPBp58m^g00P%q=^Rp?w2h2a76n` zr_a6`aMot)eT#567+;@SG9ErwUR~Ex#OA?w{F*TRz71Y2BfpR1U6)Xif$20ovrPh4 zJnBVYN8d7+{b>Ej^>&2}&d}G_{Xc9<5~4M*yDSbD;gM4tv2V(2NHuYC^(U9;^rA-Q zWQ%#n4>_%+h17$hD}bv)BKhoY@MYPR`iE5rmU!9@egym~H0F|t640I#V29jz^T9$> z;tmXo9~JAMoQDJ`L4hQ;a(~Leb?KuhJuTW-vOtU#krEFedN1$1b8>Udq%mWP|1X^o z^vbH2H38W&!&_`@Y`%Vek1zB*8`l7YL?qqa`9UIOli4LDsK8pn$Hx}|ezHE05(2mq zgycQrE<*<0i-^>CLf)U9UOxAJ0A!xmJz)c6m9U{iy*;M@=eV+&p;2etmZ*>Tn?$~$ zAPG@lI>aG3Uu;ncEiJ+k2m2U4FG7y>pZ;vdGNx~{J$#N97thm7**iTzWPLzHFy^>R4(6z=%qknuuxg2uj%OPTQ(F^|nwzgJ)wftz&VK90<|!-X!@0@~x2a za>bgaPH|+u&`nh|#!&5PjJ~L5ZH3HN0?}Tq>1F7E-llGzd-J#4a0JPx03t|@y*b}b zz_|vL`@=lgbh#8Oi)I#xI*&Ezi ze5QaH6)Qq~Z--8H-48di<^7;^IB<<9BG`@?p2Ci#ci8Cw$s{o;s`~5bCu>e}DjvM8 z>FJ@|yjL&bpaGoqqjy^iG9H`jKD1+6T4Jn;i2T;`oFqA4;z}BCA0>U2ci)ss*J7SY z3PsLRF@E!(wAsHzR`|?U7E5=ri+@42SD_T{tPn2gRu(SklI%ci1gJvU6ki0Nw-o12 zKS&Ik9o|Y$b1SSk@0!;I2Nzwa#rN`?z5%*E7`pQ8Ewl=TeLC4Dzf#-B%tk+@#|MAT zA6zW1BT}iX0;U3*ypIzh3=B*np99V9y(lot-$-FK;WYy@(3gT0-9x`|=BvT>7=2(}%nfw>QiwK#y32Y%+8 zlRUQ9rIA4@e$B(ZQkoL~Zo1OAS3p1HI!_dvB`JVuZs&;^G%2d?9vL;M=y35j&%0?3A^C%8m=JG*@HZfLg_Y5jCxT-O z-Yj8dx%r7ZQ&@s5dWHOBnxYNEp%HY!HMgAjnEbRS1-UHW&$fmc>k~<+>_MG+T0L8T z50jpqA$HrXTff&}tXcae8u{#OX)m%Ln29csB}*{J2d3|84y#n=K!iS6_O8RlriUkC z%g+5*zHd`&RGl-#Yud%GLuaqDd!nt);QImK2HBU24h4cGfu9*{b6NxmLVr@J#U4#y z3bGqy+KiNXZ)_qS0#bIOe%xBrZ^bw#33=f?ZrdQIdmc)F)_WhM$X{*9|#5 zG#frjfsY3(M-bGhOU=siRoT$OmLDGvRztgxjtj3);+CTTAL86K3oo$JdTSmF>Z-w}aq z4f1b$w$8Y1gvH4mWr19+Sn?rb;_+r{gp$UpKwJS;Mr(fX7D*W(%2{<6dY<7&=j#sh z#69btbAF;c(%)225~7K=wIx;Y0*tJNShvK9*^fWPLxvkn&@B(hL?(kA>Rs=Ng%>Wk zoAg*4cAe`Vj^XEQn!;God9qgC5H+yqv>5TA+2mxM0rc8#NYx-7h-ciidK=AoaaLHwT8t?!~!ZYl4n<$Ej-EP z-?e<@^L0n-G7%6`W@0kR?s6257Y#lmUrkUjaD1FB*pHU%myMZqr<`Mb&y*&mDdQJ^ z$9^pok-fP-Fa<=$#DwEKjF`hXUjgq@TKUwrN8-n~D>yc}6u-fJy`Rb2zVz-?{2n*9 z6-9W>ciySr7Teo9$g^A9%vH+y5A0HaLK^A}AoY?4RK>SaKUb{Ed*#Asc;$_M(N`?H?5|DVM6Dnu& zE8sNY;z)Ybvmzwe#p9?)aHVAPz?g9m;PjtoHjg5Ho(>4ONh=ThZU|Yzy!B4C;77ST zwqO&W#cOUBcHD97-QN;b_Yjy_cmUxoc#&O`l3h16upO!q<+%%Dm<)&ktc^|g10mO) zg{~`f;kK)08!BT1j8XLk*o83GrJc>8QtL-Y>Vc5u9t=|AxfUD&!f}mM;52mgwm7W8 zL%Y%2dib)k5KgMjH$M}G8)qmUCo(o#uUj!!vSd2}lw-8(Rx)pm!Z8NiS&8Zp^!C`8 zZ}fohqC#*v;YG#4>#$gFol3#=XjQ><=QaanFBVtAi>xk#F8gf5%=kMDEyeI08=pNr z$8|ysn_xVw{0JOS#b(FNU2(s}^?USwdP5=cm zq)-Y#3Ih-pfQ7RN#Jk&L^e8AOZ98Yn02@rR!I8f7+d3gI4 z{GehuDsS(stq`C}!U9O~bwZFaMx{_vI0b#V+f#H)R==fu6U3kwpcag~JJW#k%ccZD zy~MA=jx05PoT{qTQ4-nF1wdP{4Wz;?Y>i?7n>xo7dKx*omjOm^pQL#>fCWvH3!z9C zKu{W^pcW!AOLsf8_yUhoTcF`bgOMg5vb=0qtX+quq3eVLD~hNVaej6t ziUAA6*noY&qqIi-`HTg-*R`Xgi%WKXKJD0QseHn1?t&IsapDZZ9QHxh#Z>rA&c3Zv zZRWG0T#WZ8AL!#El-}X?1>#)vLj90y^ENh~X2bc-#A`a@wu{4znLsqeRLAT77o) z!uUP#ihy_4hr)S?QY1Fx9oqcg!KHM1SX%lqR9YAx6-S%&)Ueh@qAgL1f-f<{00#Vs z8su@oVlfA+^?B(fX)Mz`xuul?Gxxgz8wgZcRmDzCi$FlI)tknTOxsX(qO|@Y3=KUXc_3tmclKv$H3*|5G}7Ea|Lnb0Mc@yRw)bkL2c2 zSctMWY|o3IkL30?8VThsIATRG#i*@^57t+h2`BGE&5leqjht$yL zl;OQ;V6v}4aGNvwA*u<;(`H+}DZ((p7Nt__$2f`Vs<1}ZERU3Y(R-brY3x`I$m@pA z_d1CtgMs&j)NEQMy{Q~&mTB@q^qGL7^Jmj*PQLCh7q7s_Q#jQ4l2GdO zh0Nk*ifwtj(V7i-5@q}(tU1DAB!lvqFQ=F;)CKhqVjrTMQL1z9rNnzEWvV)qrXPC= zFx-|C+)maZ**GE=UUWHg<0JGBCA%r(FdCu*sO7nhZFx;4V+ z->o@0dX0rPMZ9^F!H(+o_HCk&2lt18bkwTph-rs)gTdnIL@PG(8-Ij`mnQ6+{6P*G zK7Q@fRf?6{Qt$I}%_liMfgXa5nud+E;y>)br+QtQ>2xk)>rWc|#qWyD4tUJ0aH-C& z1|iusASD}xgn(uxCmZJ`wdjdkH#%kRBNERN29UjMHf;Rs@&mQs9zu~fLn8!&q(|4# z3#tJI^ldzG;GX===^8e>A@wh{?+4J4XbMWt<)|+5$~(Uf3-j zz25%8HlB3_$u=?&xd;X<3fd+6Y+O)LYqw3`)AGrQH>}a}DFwiBD7wnZ%1?c<1=cf- z&oSwF0DRR4(2RMGg6XJKC;%sV9pVEZLjgaK#~skSl`JVK3GjgF?duC83}#5l3@^je z_i{&RneNA680$+9cpH$h{M)5fY`zjghu+BbH{n#5PZ2`U*lHECvLcBh7LHgELaq>1 zsxe|<32Ze(HwW`aP=zQ^+I)d*OE)&{^3}`uK%JdAm80V>7xKMruPH$NHfY@Iu-jRB z-N9>r$tJ&EqO2Nh{BH31V{RL8-4SB9>WYqQjR^nj?IGWJrh588@6u-s*@HKQWR1=} z@2ZWNM=Tp3lUlz6BA0hTO$Eh#RUJKR?@86YF5rJE{bY{^(i^P51*T0{C}3m3j!8=S zn7T|Esxq*-zbzJW@`As$JiC8gq;3V)U7mM%kJoRImAKw@7r%)cVQ%ABwsgLDLoUY4 z;(mi_-OaAZ9uT-)h zr^A8p_LFz<;dNulrZg$i+KqVQ3Y$CxqdzO+n~r<~U2iZNko*Bd7mW4-58b+d(QVE|*ZJXBS49jmR*g2Y zdxi+-01PmMbZO1)u_-(XxfYdh6|h%gc$jKGiq9h(rkh;_&Q4us#DSNDv3z9`FO~p- zq84h0$nI+%#X|&5$SpX)52Oe7B-|eqp3~vRa)_Khyn%5&>cXq8iV82?*V8d=P3%PP zc#0HX$zs61;aaCK`LTI-n)(Ra1tfn>Ii904FMmWt1BqZVMesdt0V#CAOLIxyn1}0r}=~4Tw?~_nx$(O*6)vl z2Yc0Ou(Pg~Ld=CBj2ax1ro}!m^c~Vl+fvvi>DHQDqg>0#1vu0)o%25y9oIVNK!oDhb2DEaS{Gj#7X)C zgZH`ZAOm)<$HyiT?wv`31m}Jz#u7TL)M^(1YNrtf8pjLBA@;9UoX6^bLc^6QAlJDY zGBolQ#Mprf2^+8qQE_8V0nVC*XZame(KZq)7EtPv&m^FLW{`(Gdwjw=Wc*#i0}4C@ zWFQtpjhD7}Z2wnS+4SdA(--or7xr^|&~=ISQPVBq-n|et(5L`Xp2@mw$Bs>&VOfdn z{>Qq9Px`hN3($thA4Q86B+c#5*53iTjsrEBuk3!Yn?T{fEq>;qQ%Ayo_VSq z1Et4;r_SndpsM4^2f_NcSA=^a*r4!=4?ia)B@(nfJZMp9qEC$wuWB?{VC4c=N)|n7 z6+3U>{{r9sMcvZ{Ph4ZsA>CgZiqkip&Dsr>q%kxcM)RzG z7I+Y<{J&wo0pvU&bN+va(2i}j1}cCxq$MC3xKBxih8;v2qXT#90IB% zU;(22>RIhPk%<%3GQz26md{!!fe&#u=+g9x2Rc=G8bwXA@7=hJFJ zk=&Bue2!jix_apOBpcqh^0b)!hF)dY%@s#Q!%L?f(E-f3|}E z0nz_+H(p2n9rr&I6o4I?|A%sYx;|6o|4q?5S@G>#dUFH@xc{dnldbU6yHmnjNB%lU$5EpAh1Z;OY@G3S$z#xNPe%^D}hmw!~nhs4e zoa5{7&w{Myu0P?`39oj=tOU#qGnlZz+U|(&)t_ZK@A3`dk)Fe#Ti^L1fN$lbO=k`) z&3c%@hl~0E|B}h?X}cWx4-MIXqIc^+W_=S$w+q0Dh5p3L>|!KVhH?zSyb+k3IwrM8+e9(q@J5joPxq4Dtp!Tyhr1B^3R zkc1Ls@LGxCgFFs|JL{%-wqxKY!ws3xv72jhIF1>}_hfGg#L?@3iP>(-G-JSdecYMY zz6spJpkE4wMLJ}+ZXpc#a*2@W;UV%p5a{Zq3ecjQ@%hySLL);46s*8;V((Sb(du*( z2ne4DEgGfRMdQ~Fdm_|I*c9QE|79L`9gI}E*FBn$>l=jsjn0%X=d>ave%3#AH%Y_E z1*gA}RfpR_oZ6}Wu`t;MdnIMaQ4igsf-|Twi;(r;-oiB1svJXh{R5-M^E};nL%!M> zhOwsXw{@|C2X4(cT^~UE@T#p%fKa5hhKh=-C$wda8ZVuBeqB~=A^bt7X1ckL)nh!4 z_Xx;4HVrm(cO#1K{s)m~u2l1@L^I*%Z{O{NXi6&ApVd8d{!KRFE2Q-I_tIEy#N!8y z;~dqq#0jW1Y6ukFsS|*tSL@<$73EY!T`8j{|YYVdCROM~kF0P2y&*YGg z#nCQ~=c8WQ)V+tCMUa(po862k`&r=TweKTk9u=J0Y;>I{+YNl@bUX{alx@b=ljqvB zJ>lW_-T^C0cs_tKcU8i4iW2y`^tvK+-8Fvi8;H^J_sNT045w#?#S; zh7HJews3V_lhRyN8YEb@E|60DtW=YVlr3FD+C2X;4}Lt^_>llx4FiRpDfUg5sDH7f zNKCCnP9Q7!kpZbz@KG}dpkF#2##^Z}l@VsiRgOdQrZKckg0cv>*e8v}t>j*!;Cz`< zC8ZJrw1{QWX*^LFeI?E*aGOczX$G!7e{R)4)4Y%YisojF8p~FIt^zce(YGE@UjowyAG4XjacoW!kf@Vqg zJ6o;Lc?dk#{Z+s46JI= z2&CisY69Y!Wdi6GK;(;QQuGFD+zE|QYERMpi+>K|7mRO};Ju_hB1~2KP^0na=#;y) zKg1h)Ykql{%;W$&TtzqK00K%j1Gff0SKVWByl#yh;`$wyD8NrQ9UXvS8rEzw% z7Dy$5D~A_<^GNh0v7N~cnkHu1>{kzjZjQw<9+fa zUx8v*iwp2o;ncT;uwByYZ;btw%BH1LU|5<--Q_gR9qK9PJ2(ZUg)cfr>4W0Z(J<>C z#CfbALac9h7re4)EWgNYGTac|U7m#Ie@`9A5?jZ6 zkWN(ZD>lNa1KcE3SF8U&<6Py}h|mhNt( z5lIE4ySr2x>6Y$J>5`Hz3F+?U%+2$>@qO=!Kh8N^VgQ$W?KRh&bBr^6rUy&{`|2w z&dy-cD}BNAlZ%|a-{kyiCok*wz9~^(bx*d(d=aR9iEYLEEwm_d-7mnuQ{#IVnchCi zhi>8XcT0mN#|Jkn!5l^tIeE{MKN8-G%irHdSg*{uqF)>=7<}iN|JF>p7xjRHH$7=d z_^Xdt_AwL~fPgdp8R8Z3{+Ehsx|9d}TL*g01}x(R?(tHMfj{4}*4`K7E09#cjrx7E zfYAop%Xu_YB|p7jCW7&2lNv|ts+s7xhmRDwoP67G*gAwO-G`HW0ef9#oHbLJD{4UH z|t(sPH|1o6i^!!}nSqcQ^nkY*F=S?2Pud!##d2=Uwr;~o) zX89%=RBaPags7>Zw-S_^x$*hdzX-|Nrl4;ZN4-*Y?AA_M&E{xt+mW{N`!+-WP2lyd z^Up-Wk7BjELbc9IX+*J-vzJ@^dZuJn24i*5Jw6L`D?h~1#ioFZIb4mQL6VIjBb%DB zw5AIiVrQtpBCe> zWIJKM#N+_{g&0tIj$pd!sbrLY!tUd%$`gj4h@Da(LbhLNQD2Vo=`a5>^US!j1f0hN z5_=>9=P*{SDjKw*6pSCbGR3L|C)b zvss;Y_X-$AKp=E9v2l)y9Um~H-9sjJ;;y#C{v1c$DMU4-rbb`O3}OqVZ)MlNH_*yU zSV(l|pSuE%yTp&J#uBaa3WTgQx?VjruKzQMP_OhsrfHq|gMpF;f#|wQiU_JeNt4Pz zQCbLRK}%a!HV|6BmA)4Dr~>&>qD2P0(F+YM^E-QB$>B1?lg5!)=^Mx>2Ye?2KdB;Y zQ*CmhVqGQ3BD8J?I~Ow8lSyUyKAx30@h5P+4_p=###Sh+hO5^4o;nWNwpG+1_QElE z-OJVONGM<3-ijda#{I&noLoWR-Ca6R#){3qlFXJqauDXk(b0NR?52Xu9)kj5yyMbN z{*J0B>jE=LhdOlMdWA|yje7rK6y-wClaYglh~++v3l^hrNQHhVDYw1lMnA-ykbc}r zu+`@WPUA^G@1N()9Si8$3Ci|PrpgWjchYh6Qtdx}959atWI>-05$Gu+fgnNblE^pXmvq^uvyol<5H$(jf{EMqWiVV}_cHRsc*D#@2?P$h%eRdd^Yv zO=2-dYs5$DTlD6lWzQ>P_qMrto`^DiN@TFk}dP_v3I1o&AxdUt{o&dTHbcLST8qlD@_aBv6{fW9)$M zv|Xn0ZU6`R3HInwWq|=?w%qI1E9;m)@}xZ-L@oVo&`-}h>344~PcSMDyY@dle5T%i z^#u`%-<^kk6Aor^0|Od#9pXq)MVIa-8rnMSs&L^g<)53|8Hvs}8(m`_f363K4o_Rov1-1{5+I`}={^ zA((J58Potg1IEcXHc5t_^smh$|$=zg7`}4dquyVE|p* z4D{))9DF;;9#FR;Cdn*u_7HY#wMy%?xjm?aYbEud zh)o04w3*)$Osi6AqvBQXDfR_AF;c@tr6Ud`S=_Bb}BFtA%>1+%DrS_+NoT<(vU`uZ% z2f({|2*&`EAYWsbSzDLvA4Ok=sF6_aKd-mELi&Jg7GM}R0#P%xw~W~d$`r@f&B_M= z8x%&^HoUSC5V(mr{M&oKR{bTJRq*bMr;UnL{hc2LB(pCp6zfJ{O~MVyvL0bimuy={ z7rsg0PY4-%b|ydr;t);)O%e}*=t4Bc2Ix!2cQc@WdsK`sXlEI`6NeDy@b{;!C{J-nWcjtb?o0% zf=?}CyHJQ)${TVopco9wc$_*E81+(q8E8KaF5Mo(!9u*C?8=c0(VqUOD=Q?m&ria$ zmKr_HPEgm~z>h!n`4y_{DR9+dE-XK*dBM$K2y8$oU@_rgGRWWHL6qRI%*@OrhI&QU zPRx4ZSx|o9eBZ1dX&I^=QPA;yFWiWD@CBqp08ieDO4HS_l%$?POHx9V*qAl+!(lrc zZZU2V6s&}AFId2dH|FEt{&>2>AYu7A!LD&+Vum<|Uw5CY>(n^f;$NZ{8{z4~B+i2b zjpk)Bp%k!(I(319oxVO85{3cl`?c$NYqCinBQ-S08`Hw*!=JPEd z$XylQj>D}eTyyt*bq6|QsWZ1ALr6xN@9*RE9 z)D69`>mGkD)x+p#gJk~%y-sz|1B(x1U*(KZ0k@oBaPp)y+YaD_G=|#iCF+YU69R8S z=;px61%NTzf2Zl$`ip)vG)Ev{4H;f!WTQ#=k}?;G2y*l%Dc!pcnLq}XoSb~IQ!(`0 zniJ|pn3bDL$;O6D74_?KD4Irjcyba5$RdFs%+)`6Q}zL{_AGN zVAlx^gDS0bfqV2VbhHfXUTxG<&h~kQ@Hj`$h|nJ2&U{mcelV`{CZ*OZ=TKJ-pl~%f z_ud^p_Old z#>+XhJdaDtcWQv=Gv^i$lD!6-_e)}KR=206Ptli$_a1F9X#3PndtFCmVwN-@ZkN>j zFdtvJ;jxFRTLWhD3Ek|fF$h@jjC!@55y8`E^VD$Vd}74~`r>5%)cYkx)d;)&&4H@6 zRsDo-d!cjkg)M&;vf}?6VXMR|{L|J2yC=>e7C+6ae&h@I&o?XzjydxcriW4!*~V$$ zdcN$^w)9uEDcRz4$LVeqqeDllNI&}%XU~j1L?%5(f}cE z2)B5^7N3!;6^BdQJj*+3K%f^I6gL@(V^%)YCAhMEzGo7*OTH89x_a*N3?XtN{d)tG z-Qwh4=n+egk(JQf*ku-q=SM6v<~lxgU3D5y>QjDZ_F~`gmi6@qB{7x_ok2}u2%8Aj zhjXSJ%%aySrj68#)SW-fBCs7tlrCv=fF92?ZMtCBa5+>Xn{b3wqe8tFT^{p)x_mq| z_GCPV;*y{|AwfF_hvkl7Y*R~1zu8?eHMOSzClU%CWpbdQTOUdlmy<(>6KoA5U}5?& z!wLi@3k$l${BHRB&DRV+lejWNl14ehbxFqbiLlFTG^4a!_g4N$Qk^j zhGWNR;P}W34Ly$3nAV4l`h|vKPGCRQ)-)}&xWvua$BwQ#|N0j<%xv5HG=Q;R>zQ-l z{R#pM1DZ@|Bvgg-@F{;tGwD4NRv^2sCSI>fyD+FLFI=J-dUk)8PyZT_0LHcDHKZKF#R= z7B<7jg zXO!Kb*u`D@wQz@Y63h@Y_OuKo*?iqZ^G~jOn+jAcOZ0fI6f3M~*-;Y%fym?d8 zPw8nCE-&i+0&@I6Oe+Anq_!o%8#DTim#np9WaWN8%A~?SR7&M`m4^?Q8tY-uZW5S)Bo*L-u zlm7yynIWL%3-oP3bw=cmH}>|>*`36^6N9HAKrJLNs#2* zaqb2=QSE$uqnu>yAEW=l_=G=w0JH;7lU6$7>%VRoDIG%USCBsm4j{j{<(#y`zxp$& z?;ywE;_ALJvH5v^%(w8&p|a&3hN1bI|AdeK#NOWEcLBT1sT29nME@kPJfAMO9!#`^ z9+SCw9lI`y^|g}c6g49?W9$8x#42k0X~6VfZ9)9Y{<|&6yYc_91xbRE%YiKj>S*El zrxAomN@?Un=@?T++dEPJs z8yBD0*r(8zB2JGRPX3GEkKB$VQNVy60-YDX{t7^tvZbrP~z zpJCG~HkmqX*U3Y;f$aq4;8;YP7o>%pTsT+QLY3GAO zh~h1$Wr~9xzRUr&?-stdol5o0uv05Vfh-~d`n+C&p2BA#Fi;fL?k?#- z3Lg;-4L9hap#Z>WkRbtqQCp#A#qi={V4I)-oZyur4K$R*`tk&tM*XLf+4nYZ%Z~fP zjUQ?Q1C1|TnrfX6DS-WQh(&Q70#Ge&?CkgrtrMwb=M^wqe0Cr!3KO35EpHN&FsFxN>>3mL>Y-NMz1#G-?M zPz0s*jW{B3|FqMY-;kE|W#mC@9*}uwZ)X63_49Fyx2lEl)zqww7a&^R96LC@B7bj^ z@sbgbCRs;9Qa+G@+6z{wPBu~TOsmWrnh^(H?8Oi8-baZT>if zIQX7PRIi$uby3VH>V5N*!Xl=$IUFduU_dg~{F2E`1f4 z9i-M9%&`tOwL3k>FkEP)7)WFzn$*3vkB-p^pO{dSN%-m;L)*`6)FtE8q)VsUhz}{% zZxhmXwV^V!S!P265g#94I+de+{VLL=s~z zDqkdoqEXI1s%GnM&yXpef~>s1Ev&$7H6rT2Sb_Y17SNtKRr&tl1(Z@&)kG$Df>*$( zYh3hi0qwAM=HrC?{IpkZ=xLMy`m<>IS3l(;a-+h9nj%DfK3nbimI3NQ(rKUhfGJFQ ztf8*|Ux_+#G>6Q*%%|vMs;GQC+;s#9D3K^aR10b(=~%FWJssd<^miYh6%pKo6$2gA zh^4#TA^$8kH~-ov4HWG>=`C9)C)`01J7X=-jYRhp1sMg!fC(y&Ew$TJ(x7_^#sUl` z3J763Ky0qhN@!4~0d0i?ZuN=^pIb4qAIgRsAz%Nm#Lw&o?N$u(G&8=g-$(mQzmn-Y zR<>v2Z&&k-U}3#URBZkZ3lBUWz65CGPWy4PnJIN9<`Bq#YlnBQ%)O)>gj#aQz6F*X zx6=v#KP@>Pxk%gmfRTSK1IoqZc~n|c%3dJ~RVmB3`8g_Q;&k&UUBb8&%cu6l(!kE_ zIk9yAcY1+|~*VrCBP1HNZ)4OOyk34+3I5zlX?+3rNH zE#*%xfa?%{pvCSCGxJoJxN?^WD>E2^pbY#|_{&8x;aiS}@U=5?GHdP3n!YW-wHs?ByIe#(rS5R`2DhuTA*mH zXIa&UOau(bwJCAdKnjeg(qjB(cn_Qed5xiS zSX$Ro6kswEUFxc4?naKzd(Gf;>?-83b?_t73dF=@=U->l;XhR^T@w>lKG5atXsp&6 zznVw89-jMhW23q_DXu#=^yL|U19+dd6sJoBGxz;_O8m3ZrPUdb;RX5hK6QFQRMmdJ{bh^E-TkeymNd};PVNu zpbxp9$8AzvTwq291;~IiLAQ*irY3NU6EZh{1^Pe16#N_$!#05U=ppZQt0-Cu9GJFc zwm6{P+L9Brk|n>`{wr-QN@90qh~1DkINx&|{`Jexs0pP^abz{Mt`^fb(81_j@7wS% zkOJbyJjOLMi;LsKlRjBLl$+-%MSE)4JGb*&>sNqwF0P9!n)!m6kg_ti+?p!&tM+nc z$6#oN+{Gg+Ysx(l>QCew!!o^5wcqv8xj82%3bUV`YMkR+_kv$_VQ1n8$INsW4!6bH zmn!K|e2!`twMhfQo#$!>#fA}Ob~K=2(^)bVLl7c@l~7mLL&M<1IUcrG%wWeUpK*-B zQ*ViG$0L`v?uR`efxU6_!#lJ)qRqm#)%}jw#g04cEi!X^J!+2GSimJMEyj-QOPJ8* zJJ|2jKNH_$858ZlG28h1c~4X~(=9nZ9KX^%Z0$iBi#Pq*r={gr-EbhU#_F{%xX`H5 z)>kEI=O>E9$Ao1XDc#!IL4vd57aJw(f36byXm-(Mq*hL$uJ_@?Z$+dan1!RS7#W!dQR$YIK-canWjkdLp%($3BorqgG@= z99-y!9xdV<9!|3|^XV_=y+U?md0+PDyN4STY#76MN{9l%-PQZE%je*L@aoBi@|cm; zk99p_l->2R3Koj}(3zny5$7FK^M2$ebuSTq@ntuMx|sD<{GUG+_B>acS=re9`Ns?+ zg;z}~)hciC&rDpSFUgbN-d<8AHR3m){VvPgJZ7|(DI4s5-R#}x`cb7NS4{9|5)CUn zyR25scZeCPp9OT+|7_r_0@5jh8rg(5a-=3?z0o(k0N{Fv0vw9bPiTdZTJ}N|iM6Z4X*LCm zb#z~^o|TvEHPB?>q;Hspkd{W!rKo2>(ZPA1X^Lru2QiWYKA!~!PmM#ib#GTtoAR?C z4`K+Y9AoL!L5abCQ-2a42*6OCACs<-Vn$iV`ToU^<7Xpk0TC&tF$I*7>oL^My*eC; z7SrGwKp{GW%yAmnx2%Vgn&$6wDLoF+&ja;*`iVZ6?WsAIAS$2L;*pKN6=AY+|0tgR zgUuU9yYB`nw(giYvP&VuWu`yb--W$WDrr2HvfKPx4@#SP#b$x3HuSUR1;g)D0SQv@tSVHNc)sCz*#1pN`z7S*jAYgtPOUd8 zA3?v?CBPzsfVTzGm=`TwRG3v@bdgo(;jPUijlB%S8fd4e%X&GaZsA{g7G%aVzs*hm};oUoj@HP^DRn z2NT}wNg+vvJ=VydHM4!Mw$(2lsLxu=DY1v*EvwotiK&;}eIG6~Xrufel0_Wff}h?Q zzatshW82=Uha=QDkF@#N4tjRDe;BV@+ zAoO@XPOLzJ7@7QR5RfI)^g z?Jn9dNPpblOb?|^cAFt2fmbs9dezy&8?2sRV}U3hW75-JFkYg+HwXF!Sbd;47Ye9! z_OA)a%yroKLOZ?vsKe5mj<7T&14tt(~Bp%&>^Y~K(wE%S3oDHKr<1(=?{oT5^?=EPak09gxC@Y&#{E7)uL_r3{zO>+i9In? z5ESV(Z#zqtE4-eLqK*lS=D*~e*mZ^#fI=*9j;ang=NvgEmhdAYI%LCwy8K%_F0klg zg&Otl*>$hlQJD33^yVX4t_5gEMn=4ix+Bc+grojVF^VKnGP&|SH?=E0r(Hr)5(dIb z!tb-ldx~@7(&TW2B$7Yn2Jw7+8nd+x#qQ!Lhv{EPiKr*O(6F>wuApuqF?+zOx)Qgb zW@m}8j_3fa63W`pBzlDT9jsYB3TdPRj_i|v8|c!`P`vj2^G6Wq93$a7tW+_|J$~AF zG2@=!1}Kh%d#Y&9C}ScEA8lhTk7wzIoBZ5<*_ps z!YJze`&6obgM(tfdHa^A+4bI0$kX%uZa=N4NR|!lYy3wU%LZZdGc_!3@FW=tm-4j4 zI~a-oGRt~38Y9mGv#zX>@TIsIf8HUmzIQ%vJZtoI^jPOiiavI8Sr_)mh5FU%x|2=1 zTT73G_*z7#)31y~NcU>U$!=|^tUWfCtl_`jUsoBx3-AIfQjJE_XAV14ScJ_+-RN|> zm6-AZw<@Mn3S(&K=m7zd$@5OXKk5TxXI6gmwiLu=KlE&Q!|TkaJI>@Jq1C38gJ5WD zD^WE_g^j>W>(0J|ysf5tv-YU_U_($essSbShm>k-85+^+*p*HHkQ`^dM$xK(H1M1r zw5Gg0Fw_%pD62!II&g10pLyc8R;hpZWLM>rSN%s04=kJgXA~K|UjG!ak8qyO zF5X$uX)}=t%$LJM4*FlFil{qc)YrR0{|e_d%=yQ&JMrUThX2Lw{yiV-?NsUS5fUY9 zBuKVAe}p|Vt>BAnc@Ol(wr;Q7I7${uEzbNZv`B&7j(R)+^;3AKeG5;8q5|W7>?tE> z)bPGF=6zRsiWAG}atLiI0x4e)m1{6n@&}&M?sBa2(nW;~Ng7I)M-V1!O^?T7D6@J_kKq@a9?ucWN}B{4BXoXj27{&e4PZ>}zVGcfVzpHEAkH!A}9 z6U+ZF#B-S^1tn0a{Tn2Tv%G7D$=Ic72 z$n()Pf=ypf1)yQj?<5YEUEkhTA7K8ZRZZ6l1@=;N zn1z0DBtM4v-N|p<`G?)I=Ys#h@b%zm{(7*6Jd}EUNZ^s96}bv1*@vN>fz~^{O5>j5 z=56wL4Bca;t;=?X21>KyA}bTsJfAOH_l8rqRVJ(LtfsLEEtW7Sf~dURuNT|y92dG; zcn@u(bt{NDN}7>cZWrY(UWO`MPw3u6ihKIq-=0{No~^OXjMyQ)9>wm*kGlNGM+_#3 zSZlUl#{V2u`rn%t?jCwi2yuIPYwMyFPU7VG36R-+W72cwl3^h??E<_$i?@3TwPWzU zqx#47*o-(au>Hx7Qr_=7Tnrg(gP2rB%OYL~2(LYAU|WJ7-pjJ~t7(UV#b@b{Kyw}m z?o#&s6(jGZ=RKk7{eH{R)pqe%M2<8x?qyH?M^g~%Prj=Sql=v>8z|15(|!v_E}7dO zq{qOE_WI(~$^+Z6zG1(as5^qJJ2R3$M{BJ%`@_#Ckm_4hd7gGzEwHD+aSF8OrX%gO zV@GNM5Z^Kv2g`Cg3+6I$Juerwrd-=%O0%6o-SOkSw`DS5WVoOab&d?&QW;Hr^69n zj|#ho$MRot5t6~D=whYp!`#5|tEz6ePmP~L0lV(w<&@VHF+L+*;`CF;Z@6E_JOk`r zELnVktEKza0RonTd$n7{=JVDyu-z{T+{PI;5vZv@73+vhtlvr3j;Y6B;dHCt#K zkZkHm&(dXll9O)mKfOLqq(1PUR~U6O1E13cvsLf{e~0B1A=^3M)E+@%wX5(W`L3uz9452^ z4aTN2BPn=jiCN#q>G+cIooUQ%P88O0u|n^)X*o6=jK9BLdmk>XVY8HU+-uAx*nex` z$X#$c1~Y$|44jtQ@t)6BfDl5`bZ+#8^ue6%kl{?_CTMjO@XK*Mn_lcp-eW9jAtihu z)7WK$tmhvQRm8mOqC0fE=e;=)_}!Q>U2_ahEz<)@yIzV%E-zf~Njq^v-$Vv2zytjK zZZd4-z(&m>&*z`hF3x1!hqJo6`deYlfcNxdYa1S0nsM!A1Wbts>tpC#8KazHA7D#jklIy0d32x6+h z&|oRD=Jy?%#;jp}Uf%W{9)YQJg^9$g55-I0-W3hO&;F!S5jL^}npfW*-n@0#4XP!! z`p|g{NWCKwe|H)}?^+17TEM}D^uJnzflLVy6aeH5m)_L$yw>LCBA4@4m1uN~g~?=3 zTLYP%DPbVp%xB4zi4N@u5jMZY==cG*w+VQ4t@(o%3R%QBaU`xaDQ~_wkY4LPUFxH&tNUy%ljuW08#a=) zIk5@i_Oyhy;zf?^caMnv9A_!5k0|Ke~H*Z{!U`JVAe=%Spw>Xo@`kC~M9)%+7#S2@{;Kq;70j$pW zGDTklu%FR&oP<9CPT=W+l4Y&Q3z;@o|FI`mM2{DgwT2UjQa(0HfUfHhcSZDmbyAi~ zPKvYUuEx~-y;OyH;h6J+v;)4^3r)%_RvlbH$C{YC$C70wBQ=|H_}?m1&B}x9rTeXM zzSlVB-F}JCGxf#okFKtPVxjr;B;bG+md3$ z%gX)K;AeH)R5KnH&1526XMHOf-0Mgwai*!)GarJr<&w@*04UJvb>2ezC|lZXapqH- zWD#vd#f6&ky#3UrxwjM|mkW9IHQ&#B$7)FcwK=#+em;DvjI5TXi#@-~VlOv+Wfvek zbmTNxudz;#jf3_r%l7etI2W<@1DzJlC>JV5_|+LxSBn+lFMCB>1%k%tQ(I>z0tV)Y zH|%JbR@XCI8i<;9cO_C^!`GkK+39jdo(tS-H$*EgS$^<+;Th{-tpdbk|HLLH?Dq%D z@%*&`{&_4qlyZyQEpUyB$HS98)Gr*u01t#1fdZIb&xX95kJk)-Ce`%}gf-uE2#59r z8q9otmU7TeI@nG)_~^y1@AK}rZxthdKN8M2plN!?I`ihsR$5<-F^1hLAwSJ#E=IFA|A2`;!u+Rdg#!|_+%t& z6js7m&NDt&|`bpB(5Ll&rctnD=0AtirihQHR($_+c^0R}Op>VIRTuphSYf^~G@fI$I&utyN#`GCf6r>MeO2$i=MBUMeU zQkUdJw7Hd4&CjYB|0daauHuH(iJjdPM~m~1nV+<$efvW?;)@E~UUP~)ckp>GMh??< zHXz~j&Koj_LfG^yJZC?0FJW_U(>Y44{Bv{aD^;2E6P9`TmVv1C$(HrQOGWcCNfHMt zeCgW*=gt-TG{MY@FVyY^f&fO>ep~#JlhIyZqD0)e3eET_N(dT4G$UJPR^H?GnrkdV zbRm4wuHmA$@wKja*usMG6KaOzvE8LE=W;lFmvFE(AKR|?oMmKX@>*#Y@due?ZwAQB~Y zxN~ytTW&(4U!?{Mlgc`0!`%We)`KA46Jc7qMDQ!$vr&mSa&}kHYBIm*K>vgE23pQ$+N1gCfL;GrMLJ1BsgCM;E_Q zAQnYOQKnJ^nBdSz-nl8a_6$ec#3p|>C;-k|0CG^38j2DG>t(hLvr_v^`WhQo9IpFyUrW$8*yQeE(lsVd#NWUxW*F9+B)qLfPG(!OHL$&U#PgS^T0CHJ%O)Q1?5 zU~cS-bK(ez>d=Q-Oz4~HLzG?kV%3T}hYy%uZJCc}KlCJzP;{qJj|gu7X!*fq;OD3) zUsuQdjC(Z!g#CG8YtzS<&hQ%Mx&h*3^N?iSNcn5t+QZp`gKOia=e8Y{rx4xYozKT@ z^F%846f^qac6)U$!|LYVsuLq0%C%UzV|6$SnB5YpaTaNA9SgA)c9O#E#LVo?HH%^% zpVfE#boG40rERQbIb|_(7M<~|%KMF7;w|B{BHD{Yi1L9eUux-=;6lv!_$% z(=b_VuzW_3!>fkUrh#ye*doZ8l#R!ffU%79HpIhi-X29&hwhO4ZY*W1YJBh$?sVahr?Zd+_FD zB}()thDAEtnkicOCb{EU!TRUfQW_eA$s%t z^RhR$*s6zk3Jg0(p*)-ZE~_4^!p*{$FfnVo?;S1I-;2*zCsV>|NCafLT*Qv9wHgLv zQchCo51-T!$ujlrQKk+tBHU=3jD%?DGZAbn2P(DPEN=T~QqiYBAG8krqu|969~;1MH<98Jae$cd!o|gAclT)+ zstYsk>#*-Wu&agI!N9XLXz}Li5h|*6yw*dgsbr`Sz3~hOIgpu~Jp?i8nV*nBSVY9~ zSu2D$MV@J+De%h(mXo_K&g%No7jq&@Rn<{z<>}wT-3{|zJA-FK0b~)_MQ?l^x=-yi zQn~#QDy0NJ!wJ8l!rtlnE`j+%5R>XdwT>xuWb`C5>yA&^EwKwd56kRJ3bY>^_^^AV zDsG1;)TGFUm3jD4+0qKJae?I{%wZ?)A(C+@RLP`mdmm-y>ix@0A@e!mOl#{a-UWy& z9Q+*@gWvFPcLS;8k&P1EQ4aKDhP8 z^F;KvS$)pCj#yb<;`zYs5?@+1?ua67D-WfylUI}EU|atz)@^jn$BT{5G|8$h8KjC9 zCQKI^oqXj9BYHEI@`z*JM4Cz_Z}Ay_py$bq1?RX$TSO6m(g%1#C3xj8-?*2+?;n~jX z>Xmt26bDOqZaI;k{$kaHiiB{_!fuj?SO2UTtxnLdA_QWhqc62ZdzJDd`g1uC|JlG| zU=Wm3WIky#2*bsps5z$+szJbnWm2n$>rAIvC6fB0u157VDb5#hnovl+FJ7)^7F}GA z#{5q^RbtID##i)kY9xou1`MR~EbZD~;kBQPGz+MH&5loNZW%BNSd_n6YG{ps(~Ru1 zWTGKY(|o!4#j!Q_8{4*pfHzrPLB>!$31^&#^;jdWC#L%z=@Y%@iXV8A-4n6L27V~R zt<9-AJp+1IgxO+I4xEqmO4YVf#*F&Z<$Rsb0`xe4K`K4ECN(j=x}=GwORGVBbHtUQ zO`~?&qZ*QbecP&bv52LIUs3*#^#0^xG5!zU&7!%P&K z4#A~nWNhEUrDbO0FJ|z0$R?k1A&3T(3ISrFp3^dt+irngC-&PKgXvM@$Nob2Bt+dJ z)NskV7*S=!{c()l8@`C~@ku^r0a3-G-0f%Mu=D#l(*}HKe{!Ddybs~x2`?qK^_P!0B1`{?(WZ>-#x9UpRePLg7Kk~B>P0{4y(zDM=@ENJrLRa$RKNh#>F z8>|}goP1-?I4B#WE}f*bT0scg^0sCQIy9zb`dCH2SdQ+bJi z^rIxRSfF?st)`F9oVJV;zo`BvplLC&qOeP4l+;ZW@cM1X^G(`fMB!~nvsySFN+UlU zrpWns2``Zw<#!_AU;DkEIOHRGHDbN-`N9XG{_taloZYe76eY~-@!`+RRQLd2{X$9W zI*d;LD}{#oM<1FeUa{~|vVd>>w9ol)`FVWH^p%S6O_EE(&X|np-BS^2md?Ii#L|+9 z$cat3p$u=X@O0~@-HY!#iLxiNrtXbTH~8^9cVDhxkjJMj;DsdA*mk7boR43PB!1Kv zAo;$fL4njh?If4aYd@AD?4u-ur zd70lG6NTEQ^#!iQye=|kTpAM@=cN2~t6nv^h`00Vik7bp{09TR2r~X~;p++vVA}YUSyF+0Ze@G%S1stT zed5JqSSc`A%F4badkf(tdY8zgWz(Ni<06BDB~jtUf0H3o&~22y-_=@OTgwlPe_Gbg zE&0+_tAnc+mfxA6yk>_jVDq@n6)SApjy?U(Yl=Ck@fhQK3k!TyFFr?D?(8nsdZpBJ zRq^-r?`+>+-j;J^4NyfhCN81Ue6xd~&TcVt5&K!UBN=rP($y5UABkHilpDh56sl6+ z-mGJdZepIeD5{hZUVVL{zp1nlM=xrlirc5APJWI>i#%B@crar%Vp~O&Q*=r_Fr@A| zUwL`kW@bm7+g*F=g@41DjfEeMfUD{`Vn7&UTT?f$+2fOltMt<4D#=SFsWKfs@50>Rklp}?RwYL z)!`^R$+OFo;}{O%(K>HZ%!1x^IOM_R8gXWhvA@D$ zhgvk)SGszJ0PW{FH^CRZl$GH%z#_~mz2JCm$OgOdvk{TE=Fq-5w! z(iF=q#2y>>ZMKBhH5=(29PAt=(QAt?L#^>VBt`JFA&nw)55r|+%PX~N3&HI_l(1(b z)odY+?UUlwQuamLp3KatC+z?6M$!N)^&`ny#j>GTSxPV>LswlD9?8#42>srRTy)-9bJz95gz{$NAWnp zuRuHomk`N```zjKk7>2bq|8y~SeN1Xq8nWs-H`O$4 z1T9ozWDAzy;myuO-P!9l`;?V2pXOA0{h8W5+y9Q&hXh1`m>{{x)D;!^3Z^~eji5)0 zi>eYfc2rNlG^4LFBfQ}FYMUa2nwq+G6oeNp_VBTEni*GiGONem!EJLd~c;<<(BNpHfi7xqOgS(jpmGl-7U-E@s}4%j*iO? zis9yq?i-wk>|Loh=Xr4yX~2kk6re@jBmcE26n>0fmdNqOl4c|jYS z*{bCqOw1R6xM$cg?yDGwlG((;ympDR;+|?au+k>6{}TUhD)^er1Jx=Ov2BSQt^%uT zMpnbDNXX+ODfwd{XdvL#bF+3_fSc$|VT8=>HwGxr8~oaHB_s-^lu>kfpWG|&1VQ*9srNmpdH zQ*hJyJ?x%+Mgz~0)t8c6x?)@{MXc%6Wr{Fe$5sJubQ2HUW{Q~94+%-?Z&ohxoj+<@ zb^3ces-6l_89Jd*!9ia>ioU^zUY(fYpxCC9Z0W~opYpq!k1!^xKmCS$ z<^t`XkEYGaKL{pV%O-v8yFK_R)oDw=Y304|a^mb!SAosZPlz-9CHS01$UVuNu*H)m z0+EV#!kFc!i5mTXn3<)Q&74NHX{0O`r*~v9o3WjAEd0wMDn(gyc$+`a|(H)yVbS5 z(Nc*z5px&1I^_=C9#?H0g)%KH27eQdnJO1v=%W9zamsK~F7i}nx_zY`+G$>iG^$wne8ys zCO4tSCEr88;d-YV;P*?7hgN*NKHI%Gt7!?3)AJy}10Dr6&8PII;?OYfajWO;f@gbb z^Mwhg^Oj!J-R((u)P>|RlG}&#kI^v%zdDCa^s8ql>bttSviRbbtnrnVm3#X8>86A$ zl0S_OoQ1(rQY0e=%lNl%iHZ;qkdVkLS{>ivS{*VT=QE(-&(yCU8|LHYbvJIv?B3+ld@Dijstta~?`r5%f+ zAZfL?1*ji`-N3w~a-l!ML+>!27u-zEu9`Bz_^m=aOg>1q>9NjMNuicfatkMSs-+?r z+T#(Op|-{8(2|)bu40th5%x-?CIJmR#uQHuo6{?uXAj4eVWv!Me;R~Dg}btjqiBG) z27cY&tdJF`4~8r>&z2SrE;MchTP`+}6crVXc;@CKLJwa$H)c*3m(S1KNqCx%_78Tg zNM&Z^JzVu6i?@u6?PT|gly|F<_YzHs{EsT;tKTa`Q=_a=P;={b!UO8&Q;m4r1&5mx z6%GpKuhijQT}km)*HNO=8^akpOP8N(e=ducr)^k{qL;o008Yg0ae47N6)sTRw`0>4v5(bUr&EgpHsMMvj7K>f887ChGJ z?p9KpgFG)9S~@42>)$qU|7=a>(I|6s9{o)-m^}UQEeo|&G<+x*wN$7&J9j0us}sM- z*1+&|W=vh8J79k%thfuawivIF8Y|dckvPcnUp|L6P@Ni5Wccr2=x(5=#NL%5cKg*Z zarhQuk7)B8JD}XH3fyY4Qgd^129e#2>#g`M-XNUsq2&vZs;a2?&BziRCJVS?ozX{r zS05uz*sZpAS+Rj40S0M71&|Y^#!d1Xsq!o)8*vb%#oAo}v~+IL&$xo8)-5e6cWv5V2TW2(njxgbvV$RNgHVOJMHwbQyexuI^+HMy|?G>WeW_X zdO{%OV5s~f$;=GTfzXO)Yfn%-oG1zgi)e7US3*W5zVQmZXJ1OE6aRAHeoAP1!^%2Y zvTP_&kqzSP6J=b|6P;7Dh<3`1sGO3Y7wFw0>)jp2l{p{3*KT&xY;tj+E-x1W-o352 zQptwX19nS6_AC)+J#mAqk7VeM!%IwD^@2AlM(sO71}F6b4%AkAt%+Uj84cQTIh?*> z)AMf0jC60cKq{vF9N$LoKB4!#-dbECyE_+1zr4TIvn=w|Zc1EhwX7*hco3aofS4rk z;K#Ge#T`T%7$S$kX-DWGrEy^YA6STrx;l9DVVTF295Femf;2Uk7ny$%&!g&8msdpW z`^&vVU^H5MX6&_TH|46`1cOB{r*qLu#5Z+Zc%vG;ez225+ISdM$QvGHn$qBT&p+XL zcf8e^I8lNpz_D?fuRa3Xmi8B_3uxG2*X)4!mwk3eo@Lm6m4JA6q;J9v-3m$F8ejZy zAS^J4FQN%i-r{}AMALGBwIzle*&IrjD5yd_hWJ@)G)cUD_dEhsY&9(q#rH22B?wPY zrsj-8NV^>)&-90w?ccCwpqDf@BJzp15TR+1E*AKH+_$kKDHF;all1I;l&B-F`(rb| z-HBzSHg3qBEU-XsC0pX4YWr~^H*Ey50Bk}1O>xib!yy+Di-qx(Dcb8W?pd}^sNLsc zeeq_)anQx{{iA<>@g(CA2c1qd6@zxFQ{)6$A_ae<+E8d$`2K+~K~G zT`f&6O^A8ZesIqeA@)-$k507X5IJ3~PhR|%74*XFHQeQf-CoPg<9bTuasFo;QPnn@ zv|HDP?)QdC#5i&1`%|XYT#SrMO`9fe*O;KS+(g+%_28hVL?By-UK98reO*@A_sdhg zSQ`eyd(`tks=Mm9sJeCyNC`+vrzl7a-AJbh2uMi{ATWS*hcw90h!RSN5<~aU;1GgR z(#+63fS^d%+4%as-?`3zaQ3x-+Sk5j)>`|?weIJB?xSBoi{v_F-SIo6RAxCm@kz|L9TsS1Q+EjbQO+$6Le_16Q5P@2`gTlG z0Nc33QFy;hGH%bIsE>Tq_DO)+a^$jR+=`t{)-nz;tG^xPT`DXLcEx*#T&({c4OO$( z_M~M`3?;g!RxSkxHt9tvHvaW3B=Ds!B(%51-z@3J?QWYY?i! zxNZ$*Br2Glc_xHLt@nB?$PzIG;#QN@n*$%Ma)rLtKAP&|pjSO`Jb#iCe9jftmFq9U z<4zRwhgbvk9^mPPNnrt(x z<|T_fx%*#IGhOp0 z9PM;{wO8WN5-TNaBJg{=Rd`2#({JVB?F48P6Wwqd<*SlVOr3n3y%MuW`(mos1b%*g z99&$VbEitLq6%A%e_&z&$@X}uU8u!hA}0V`kxfrS(|Ir~%Y51BKR==rd;{USI=wml z&*gAw7;pQl~*Lobr-q|Cz3G#gk{>EV}?HPsS2QP!Y)p;a7@NDhLeozLm&9` zWcL2vYQ}X;@Js(YO-)U{b?nZ#p2jS|p5b5cLiz?c;HNSG2i9m4{}dg4`vw>c^s34C zp8%C0xScT#i5EKMl|znLTtTt4#=~tm^5T){1sRm`i-Rr!jE2~lE^LWWG1;#O!|s~K zJ1$)804nu1uZypjR;?!p1NXn<@M9{^U!AD#`CxnL|aZX&-v2@Z;KVYo2(+#!1% z+o8nb${c)39h_kEH5C?{hodkxJU9lrkCm5z~dvqL_)r9JpKLH+KW}?!@cU>k(q@J+1B9o4krJiv=Iif7j5g?885k zBb@u!RoyJiKNlh0f6eTlCv~|3{{nvgf4-7lQC+R0&6i9FMZ8Z>R{(>v{VB=R09nHb z`OemZ)>p%UstV0V+O;qKU9Ar}hJ3T>TKNu-&x-Ph&vWK*J;Dwnn=gI6O&pyf8p~-n zs&wmzqEibG_8(uvQ1el96EzdYnLKuq%rgofPoBEar)zmz7P~*9(|_%UOn3Y4LY?N2 zd>__*)H_#fuxoPRrYb)AeKoS)P3*-&AxsD(1k>x>2WtZ;OD)~5TKLhYHW(N)9rI=)F)Cz2DfkPZ5h zap7BkEYfajt4=Y5w~F~i=`agzT9Pn|j9h=$HY)kMp}x}w$+KJ9EHi%o2@LdnC#-tZ zFh<&83=_Ip*)vPS@jT-oe_@)kO!>q|DoO^RQ3V^6$$E=jf0M52rUgnnOrjXc76*<8Dni6l5BNOLQ7olPI=gU5RskJk>>NCV33= zaZz1+!@Qi$RTv@ zHfaBGTB#^7JB9`S=LhE-b@pZ?f0a?GHbVXeH<$l9wui3(Lj3V6Pt-orGo8;5_oefWaJC;DVEXG#s>|yqs0P_yO{@P zq)}J*)dGve4Z((dkzD05E0qoG!~y<+n7OFr#gmn7^?tnTH<-PT?~ZRkC-MKRQ~gm0;xh)Ia3Ou{Ul9!_NH#2TrUp;c>v-|DJn{4pr%HOg2jC#%)I`!3(GUg;<0n5sWxX?{MC?m%21_CiS5}S z++~T%5za+BIrOS^Fvho(ep)ng)Sejl;=|o8BnpLicC-RNumzQ-qlpbHoTuiN?Tr<6 zgHk|5v5eQ)O?YwNTpnR7&R~5HlCVHkUbg*e2E@6*RLAs24o1#oY-4Gx<3Jt_xmy7k zUT)`Q_2z)0H(AC{s)LHN1*1xhif*I1dk)|1OAd_G{h((}7Xn-u&OLiE+|Nt=zzq(* z^g4tY0Y}`C^4FKi=gNP?H+suc5+sspsiv0XuRqCullKzEe1FmXciMt7mFbwU?(Mp8 zKRWqlapO>tJLtviTAUXQ8nbxufiVGv6}%z5hwW_m%e|vqVoSd~6WHY6XyuzFZY6Wa zl)A)U>IFcX!4o!iWr?HHd_BkZWm+l+nGcHj4ueW6p`iYg_IvpfDZqY%{=QqqU#Irl zb@8ulh^Q@4_pmdPW5}KaZ*`q+Y8TCVXci)n-o$3bih%&$cCXjFN5<}r%oy8Onz;RD ze*rz`7{cEYCdQ=Pqp=MhIX$Q>qhz$H{!{^=a@4e}(|~#C!-yROF?ArqpR^dr>1DjA z(6v?l?y>FU5L@b?;WIz$S@EwNgZitHy9>H}$pB9GPYt>1O)LcL-(rM>U3?RSJ!EJ9 z*C&1348X_AWvUE*N#M&59Kzn(WM>c2er(EHkB5yR`51}y6RB%p?GFy*#gjQZ!DS$Z zF7IV`5ogfyBPZ{9ZV?S#%wj@U*aygow9pynknekUE{6`)H)yV%xD-yCOzJ2PE(dAZk*z#>X4U;!uM_7vm12Ho zKlQYG3(ph6zCT-~rdG`1mNxussUiKob9IxW7Y~oD`4N5~f7II=cTmY(lvFLJTeFJ7 z_rP*+nP0HYLyjA3)envpd`#CwedmDBH+{>GEnj0VLwHsq=IF`l{c78!nn2Qpppj+Z zMTs4~KwhIqN>&wyTQjd8EELT*!mYwR1B^XJVCxND4Z=&Us#fRtCD~jQ*15OP%^J@P z#vL1Sga=a9#my^@L}Qv$gR}yGPe5|GmwJN4)0bvjIJTaO)aczcnK+bH?Fj#XDqxfb zn_f*5p5JG8ED>Bb{vcktOjoVmFeTi1yr^&vZRgqLLidbYi_3eMgTD4np)Qw-wU%gRZ%L`nEZpG$EqelJbZ)N*ql) zlBGXnk_ag3CH5n4?YCab1V~z_&9Q?P;J15Y^!aJxIkH@Eh+{&)6D84 z-W5U`W-QaBOMA~MmsC1A=-bDlQ&*_n8iCk&V@W!#-;a$|2Xd@Qx66=2NW37qbG<%x z@@!RtO*-~Qp@gnJj(b-joXw$0LClk7YQM|e^FM7p;GOpi2}>Ec_wHSz;y6MecDUm6 zZv4rm@$SPkAmFf-0f+9!<5h8=1$Zs3_8%uB6di~hh`LF{c0D8(DX>vYNweGp;JU1q zs7EBpPTXs%ZyPViA+?tu%^Kbwq}jT@nxL-Mmz=aliUTn)#3FEqE-9fOgbFX99-?x;0!P+M2%|Qa1SAE+0MJ(!Ik!D7H-bHz01MGmk%$ zyd~va^vh~qR2(a%SZ_xU=2Tj3aZWomqU-u|w3A6bL&Z$)&Yk(1szoSEkrppkJbgE9B;`KGJ?j zH_Do58HKlzGpW)Gr<>Z-qP==tws+*H$DO!8Y0L)I&ICO%ZOEi>)?(ZFKEyuP`zO3d z)(e6(RcQ43Ha%YfJRu<=S_X;Br;T>F_s3dA3&+~a=gZ-du2?qvVB4AJiCLw{KKBj?N`Y;9n{CvqtPlk62bK46dj&{obpKMG z#WDbK2}$1L+_AZpu(7%D{(e$m1A~BopvrxX3qW2W);yPIC%ECkvbg}w@%u*USe0^O zR^KHw<1;T-1B9_e1XzFgePg+i)pRv>rn4^*RgcL5BtvUrD8yH-{!G^5)( zQj#&O9n4qefg$JAK{$v_aV8=Xt6!5&pu&QJ5Fr2;+L<#A!!-Xwi7a;G5~Kw^auZGyI36 zUDh0qn4Ts!?lLqFG&=Y^hIAs=qqeOF;%JfHllNS~MDWa=dW#KFX5*n-NZV!)CC&&{ z6&8)#{N<*ve_jP`5)dX)q=$fu6tArDpFfL1F)+GgU^8Zs0{_jjne;9vQ7VTyuZmb# zl9AxI|0*?AZgCmIDGtsT5gLAf7wt>0F^C{c$UZs$;I*h|eswij{CT`<@y4Zk=cjZB zJ>GP(yF7-ih9;TS#Liw1+sAe>tr<6!epfvi8KOmhR*R=*gZb>Knk}~eT8lQi>l(!u z%SITbBKZ8PX0(h|m=0NStSmrn!!E46v70PpnPHY<&t>z3YdNbH!aJ)4u9J|0VK~2# zxh5UZl&P~bWe%YgjRgsfZ7cABsy_6DxUMqz_E1nAze=vysdMRB5q(|+S6C>bN{-3oc&^6d+#-~*M8Qso?7qcS$tAck;8pN@dyP41y?~{Mgs)}9Tf%T zp*J{R4?*scL0Va-`r*EUhYvtkd{Y0X5e4Ochamz@^9N0gBP5Su;sl7x=;Z(fX+e{ZWU;mv z3)*fAji7Gj@tXm>L88B`)?RyrvAKNBFuRq6hU6JOymV;3B*yi)D?*3_k*Powtd+R9 z=-Sj~(IM0?W zu4m)PV``pxwpV_C=;NZa;o_oV+;x#CjMgOdleS) z`4Lex&Smk|>3yQh3S3QcEUWE>d0ILXf0%(g$-UHysQ|8*XhF!uQUB3iJUy=QeF4G{ zKm3AyQ2+VOf(Xc6^*y^bKKUO~Ww|>AP+|MYVlZ3YYRH}cZp&@#s;l?m;|8WzZ#N=Z z#}S^yo$%#{>|+Wr(`#1Ws(S-)f>?0HX50OXsYA1^sz!P6<`S}+Dl(|gHmtfzKd>rL z^XzbjIXy6>m7<4XWs}HB=OWazcB>Mr!RS@MT6rY|(FD%_;IQ|4@X$#tzx;adcYg`1 zUxH`yI$?W!+d{+!CeZe_gpRj)`!Vy0aqea7$+tbQb@**EV#$Yx&-m?JM(91Gf2H97 zm*U|yA~>(RlD2>E`i*Vt{s+oL&Et1Gwb3k{bW4K#GjI#vsw^B3p^_J}!)*a^177C5 z#`L`Vwp9@i(9LmO&$GG2++Vdy3DLOUTTY-KHoViecnC4Qs|o~Nv^Na6bxKPw-j{^1 z_Aw}2w3H>(ZHLubvGXuew|>oaC`vr=Gd0@@g7bYS^PlH&PwY5etR3|)OGsr>IEC}u z72o6s1cGvRHd`-0AjQVKWKw+#fbZMFtM0UxMvexP;>yZDTr%@|CpzkX=zZS<!R$v0L&(En4LzKS>`w;fGrv&zsQ4ck;u1x?d18zVE+a6iIklwiAabEd z>9hI$#|dk5`M!fa)OMC4%atvINSO;??+*_{zzITIc(YqqbBIr zA9*C?e4pSr8~GY@A*n%rw(>H)@KH9Yp>?HOvSae1Z+3zZCm#oIlT6HfW54(jd*SuB z+RduuK;%4~O3m7ZL{eaPNA9zH`hIa!a`%N*$R8uiwbM(Cqs4V={pi?o<}9IUeQm&F zf#ea9zCTe69#-0Y3>E34!(n4`EVS?qVqMAyBEQLWYCYM#*ML<8o5D;G?d^r&AdRV2C?Z zSE%xyWbU;K41dG7#sKIn3S;gbMAy>+&R;NWdg;*Z*KZxad{bCydX)iu+5_&`!TI~Q z-pq6&YAhV#QRSgykcgXfy52Wf7^n2JwJx7%p7)F2H!1JPnvK@jx|=;pZ_m8X%_1g$ z+ikfaP>AMoSsVWq0><|%ke!eEkG?Z5H;08hLc82tIDJ4|DN-5QG-aovu5D{HTHx|i z@Yvey+xCiv{DSN16OCocWo_LxIS;sFgJY`ifIy;K8#0}<-+!%~zF%;rGAlALyo%J%N@xyFf&;2fS}Ktiv^K{xDNTwkipy^mX?&=UB@Kz z39EW9{12&t$N0xiXeqX@@D((mq5iKm;U>Z_Ayv9Trd936Os{ulA45MNsg>I42!9Yg ziL%VU>NwbSx@KMUxvrzwN5t))4WMR%XXuX-#{{B%L^ci(Qs3Lb32_G+;dwJxJ+QnG z!7Q#q+TE$Q$9mQynwuG2d>THB($u?ze+&HMD_c>3!=v4J$o z{ezE(G`O1Ay z2XFsKO^Pxh76!$G9HbzmC}uK!`sCKy6Ny-BMec^Y{Ulk|EG4nmd<>C$5vr+^$Hw`( zedpVb{@EdPp&(m87%z^G=c+K^t_q`+2s6~%i_Qmj*&DyxcI$cF(Y@O%Fbf!=1HURa z(qOjwp_S%iiD6>vHK+J)80G$#oC8n#?%e;jI4P4t1JQF{;}^w zdT0*KzTY0%)+8TXk~^I$XvmJ3TWzMy_eT;5>JhIkcQ>Ls38W)T?&XaAeUmF8r*ClK zCLg(D`L?fHDm&T@1=GCjw&yrsuhl(1q=yzX9|yI44w(@MLy1|Ay6S=2r(zyQ@Dul21*por@QxW^1iXkG=NR|IQEn+GC8~ z*t74JT4MaxZp}f4gEs?Z%chr%~urj3JJ^#7)$X6C2qa$2x_7Q_>l@=ulN-~G|%Ux_h zIbTmwmaN{V;V#?apzi_BAVKq(Mgbf+q9H^gMwG>LEMa=j(C^)IMd#j0)fA*m9#Y!d zIAmnS-Yhr!IC!4Sg@o=|O2=`~M)MLa%Y*Gb|2N3hz1)+y>4d+^n)*9JcL7liew#q8 z9W`dSE&wP3333Ea3M-)Xee>r(ijly*wKB-8G9BQWOFbK`8Zix$2Pb&n^gWbfwrf5j z_T{+M_n}eHcVA3{oN}UOnx&8r9@^g;D`<2ZBAF9{?xrEQ=-Zo17dHdU0g(0NfWYC_ zivgMqqT5Cw0y-H3)At`;I#?b@OHTg-!4S#TF`f5LG`)!J{*hLcWcoY4m{^(4{+T4C zd#1CmBP)Xs>Gc4w@7+f`w<}NgT60YOceXY z$-s2^KC910t%AuWkPW$Zn0jrsy$+7J=;geQsI*;as2Y@b{WrKYV~MJ=%qdu((Zi?| zFUwLgO%84rQS)<_M5Vr07384C0}*P6bIO*~=HxC}8wb|Nq8dvi1!E>nAY&<73HE(owWA$1Ov)ODcIU@Q;a+BF9{qq! z0vsVbyYcf}o0bF2cdl%Ep#YIwJH??;k(6fDx4aXtdo97V``6O2U}ngXfvxFn=N?5T zQVDJ>PDG5wmok4DDR8_QPtl6Vo{-P^o*k^#BS^u2yy*?Fj#D4eR*xMpK(yz1{m$NA9pfLCqcG<+H|u3)Ww>eQ()U{FBJjs_L7>Q+AaS4XY$h*@=B($Pt?v$OB+?t&TT z(%-)5z>H-WU;5zEvO!{HZM_SJnKs3I-f5h7jvw8cOn2$Dqh1}g16#FWxIwi|-@!3p1yxJuyvyVRE-(ChBVhA&<`G&H2P)1|;p-fY(WP+{URXM0X~cz8-rBxffX_kj<< z8g(Zpr`EfRc~79TvWg1!Rmo?6`r(>~!{Ix(*Jt2-&pl{Kaj~s=cUNxibA<_@jX^ERJore*pCwl|%~s{3*l^AEMkA#rg89aq01g?&%gzlVmHROy01AYh7u;R2fI7$?5aPKf`O%VpdRo~`nF5EDya$K; zxtF&R?67?H=lWf0q}kug|3_cXnR*R^W&w)>u~dkDvWo@Ai@SFOLKfh!qt{t)zx zpWxr-3ABH0!ZXl+nSlRqjWY|*P0MMo(tiCicX;}Dg z|NOof8mh0vuzN51VTWg8=n3&|k!or~I`M7v^EKE#&Y5z_kwk8FRR*uKA45*ifOKf0p5T4Z3{sZ`0@|#Z* zN;7%$rCIH17a$0H!N^=LlQ1lep?WNWDUoT};_2eVST)D>=_p`z*gqCW41 zsl9M%g@5duyXe`yO)({$+;(f8#Y?ljj%CE9<;R9>@RWx~*;B~(q0wbV>cv)F>`~!J z`sC38ZFk#r%<7;K~yVUmK z2X$hqA3kJr{v&wl-EFym$z(xp(faAye?SRiQ548xR_zn9nRIG{q@BF7-X@Er)NaMh=hdmMMsgns&Q1Z)SCCc^0o1+ z&AS?4w7cNjMX@a3!k?C#57LJV0XgL7;4>;g4lVLgvQv@73Yi|?hfAs_M4!t}VcQpYuCm0D)Cqum2jJ){gmzRTplJ$cb zpz6KOmdSs9n1OQUGC3wL&wx*_XUml82@3W2 zsi~28f#zaHaD=z&uQ%{9PNEQgw`RTW0%ToOt$i-rmZ=j-Tz;PqI9XZK6P~BS4Vt>s zNP=fpgMV#FT;AVqNgN0JM#eR63`!jTz5|*tO)p%qRhrhY>Dak$R|XBu3;%xciJH6b z!zOpt*U%q#Y*qio;@NG7k83!A~@I|(kANITlsH^dH|*f@!aiO7M0 zf#P$^h)-EfKRwQB=6~Iv;w$&9Z>e5+qZKvLaGo_6Uq^X}hKiPyY9}?pX|*{x#P~S}}1Cr2fE8n^~G3%UddG*G8^~vRd2+FMJ49tAh7C~3{RnS0@FPSlo2!IBG4`o8S{tf`?I|-q4lm ze|j+PnZ!>%r5yFpBE}+ar>CcpO&teL>T984o?<8AmZt``AB77Kw{L!q(w(W^-ZX7A znM5sray`p}cRt}g`hh$k7lObuS$oB!S}SFaa@Q!W-LoE{!mbg9qQ147XK`Tn!g6CJq^!=N`R=1=>N#;-l(LRppeX~=y|(Pd%9Jxs4#Obx;1_5{o!?Z&kX zzk+BogV!SAY#)PSl8e6~+CLUpMyi82XD&>=!?J`6UyXL^!DU3s}J*+h8KWmvWT8sUM?l_+NZ|G{hA8l#yjlF&3RAY2Q7;GJLgd{WGV=yHa>CJNC)Ald-b+_K#+nWTU=yD)( zv`5}v=bnokHcMY$UkiI5W?*1oyx43hF;8S+nSE*u65B;OU02xj+kD#Sa257qJWl5~ z{h$;-gIUMi5}^{Eno{%{<};bv+<CPCQ%JhGdDZ~?jq{I9Aaa{^cN$|6L4@zO8=Uq3lT0+77@tQ$SKIYAzM`%=f%0iH7$X zs2ne(mc>!=J3m$L?p(PBHO`TmX}JrM9&pa`bY29QZ+V{)ai>|n)Te}VMGN$H%+Lpz zb}%QJezA`^z+KiY=)!M5LHkblbG~r**{Z@*ef3|XCoAx{w+Bgud8?)7d1Abtdh^nK z%+=Jrv7~g*2oMJZDZQ=0Ja5|WaUZF?4cPY9$t6ivD)oDL{MF2v<@?N*S{q_ZINV+XtIuFekG;!k3hp0A? zK8`NO;zUD{y+`Y24VNF=$(y~_hU2*=k&FSc>DG&ji}p@V(?CEXZTFajO-)Hj>073d za(Zvi9F4HqKr zCz@)s+Ngl1LBYdEuLxW@w3}bC3OvoQuU~tlV%ZD^#|4%dekXDeYs)xWI=D^`g{&ggB&^1 zCqRKZ#NQ$xuYq4tBX8~@>*t^p)D!gJt_Ye=g{F>F`5^pF%`-7Jf=^3y!*R_>4n?tRz3wuY8yh$uQuYz+ zUL$VJCJQMXy9F_QeTa?i0?gQ*zl;3^_m2D1xk9tfrdt6!(Q>og+A%SaYpk1cVo{xO zS|_^TzBJG5d;M)B0V300F|xf#d6Sp7<;G$Nk#C)Jv{i-ZMW{I*$jf>|vop(HtEA_MgwpO}=FN;Uj zCrVM=K8A0X$;UT#`73SGJ^{x|Ff#vev}Hj)1z+yez)$xJDl>fRE}hz^9NI%7YyL#9{e9~`xvM{2W*fpULD4zlsF&O zK+=)7Uw0^U{a5e3~DbY1yE=0^W=Vra05e zuVUvNc~ahY8)_Crz+9yseQh)E)5tWf{6jqEEaUrAmggia7;RQm49-O(!|j)7N4(Ho zdu{(;w=vOlw<7!jsx=h%yu2qj7V^H)G%vX~K$>A!pFa9$<0i&nW6+;zt5ZunOD#@M z#k3ABjbKS|@vD?cI;ITUK^hX@$gQHCnow*^+752!;1k=PmB6gZsW6* z542;s8qS`cbG5y-*r?}Vt9CXoDG;OYd&PNej-ZyjD@CuTJb!!-GL%(si)cU%@}u5&3{zM_4DNh<8L*x_*6Vs zEvJO2?UQ8aJWlD-o~vsbI4wNO z$GbZiQI%~mM>!7d-)^PEBRi9=FCpYZkVeb^E03vj?fNz;Ol4B}gj~`l*h1PDJ@|g~sXy|I5P$gdrC71#VtfU~uThMjJ(?226FP@%9 zJ!ztu_(uBK7+>Xq0yp7O-|=IxkdyhArDOm4<<8r>Be964zNMWTP4N5;MP%$@3(<*?IlCM7oM#*hiwgj1S?ELQwo;H zFL)3fJ?B1EQ;v>kSiI%hbsihHJj>cK7O?}#(J2Bk5`GPof7RbMU?bOS6_<5cTXmXssw9t$({URWoIllIiMmf#$Ow!r8lArmtiAh!xoBme-%Ise| zpg1X(1fl&+P#6Wpd{zJ9 ziuKA;SpNtrfO+`s6eI&+Y0_IRM$d$@%`YtjR@IqafjQWfW zDgX!h3vhQSk1gh)5^g(Ub)Bb9*nh)|kOokA4OP`x3{1>;=a~uXI%WVq0RZGyw~fz0 z{8t_y#hiNZW2oB~l@T9CI6>@7I~fvy!Fno#AS+Yc@?kLe71=Iu^QDN(xUk-GrK{^* zrBTaQ0JJA2BKo=E#=uWRMD&uC)nOq-@;?Yo;p^HD#!tD42W56sKA%baKBrHZ`@zI+zBk-N0T4^Uqgrg%Y>Tb=M;(HPJV3pM}P6YcSKyl$N+Y|>UZy+F@FCaQ%_t! zfUJ%4LUS&F95M6qP6|`V|7;Eo`A-Ifd~n09VCv#q*Z-Z7XoX?RM@&@(sS6868|&-a z2>2caIk~#5Z20DAc2#$`6fi)2CR)-{E&G~TM`-?g0-Wzr-~Y#6KKHDSEws2Z5ur%h zpWfU7eT+9a!1#E0UZf8*0$?bRTLCDSBqt|dkL23`l1KCNWg#IC_KMa2Cmp`7rqAhH zi~9|d_Od0##pMEU>UDs4bX1g{T&xgHogsjzW~dYii-^QO!kP^ElSJap7`CQ+k`fNM zAwE%2D#0;9sLznIcs6IrGqWfEvXOk?h_>VPmfqR}*1s92AvH8V6#5sb{^X5B6xB~3p8Bx2iAUPCjelYZHtxHXIsET zMLYbS`F*c8&l;3>%v{7FT{$I20>8!X88?6-*3Tcf31WVPj*XA+4*M45Ys@ zRG9t)Vw$yTA8I%`RdDZ@*2grw)Py7NN;&EZDF;d~%e;acenkP9fJsZmun@r9?e6T1 zcXdf>7*kSUuab(|-{N8*Lu zpkNc7io1peznN*~SSun8IoU#EuRbHI4GuN0rEdvjwQi(84^zsblpiIbyqg6;)VjJl z{#UPTK`L`AD>(od4vhUBGmuA=rgaOwSMjJG!AFr7v)a>DD$3I7px-Hv$#6_+;|t=e zuAM5-RHf9Ed*v@9(&RKbQnYjROna8v-71^cl>CBfmWQVz&xXxVwvcCEsCG1!v(2Is zfMoM407En|bv7=e+{=T4(qA|02nc5FtmD8yEfb$*%H{)<{7Um=&CG*B^Pq~%)8@~= zw9YEDO7=ok43*GdY*-Da7UB5E@C$8N&bTM=+hhT0rHP3IOw z9Tn0}E*_-^!(`IW7Df1|xR0Wq*q^Zk8S0?CJ7FzbdI|e5`GVwC+YCVO;7~1N5u2ek z2?N@LcV;=-sil{g6!Lg@+!R6_WlOX|paYH{rCbEu##3%A4TJSjJ_l7=ho8AQ#tt8G zHcEZUZ2I)L%I04A)pqWR?EbAFoz@{w=3}~1xec2ky>9zXK)G6H5aF$@RsAA-`N$9{ z_{Bw8QPc8OuqwoPVO!JX{#|ROiRNH|U_#tKXsApEwQX+68*?#FHnNl1<}{Y+;~I0#^M%_10MUvv>7! zTwLLsYxDI^>D*LD3psMioPmjL_VAzKBa+esA*;>xvxo`37FP4twM@!$dD~DP?W1Kj zSV>s#Ev9OJ!|drpavy@leSre>Nm~7i$C#*l;yzMkwB&t*Cv1FkzUeqt)A$b3Tdq#? zjUW*hMC_vC!6S6RixQK>IsUb-wu)H1n$?!sKyGDJ@T*7?hmN&u;eKi= zi++s^18dUHz`g^6I{Q?eDmEy~<+OT<>cm>lO*a^w zwna&84WHD#k=41CG~39#FP+4dz{ZvEIhRtvx4+k1t)Em4R8P#U51vMXHhm$vqrG}D z+^V-bQE>UW^EY=nt4s)JQJA5nzPDMYkL4np@%Ej%(QNb5g-ts_}MF4$^+J=9%EAX_L z!OsXX>UN*WW8;Ykl^dDfqeBf(EN~m7i|z9mO?p^ho^h)72Cs|F?cyBWuBTA)ZK3is z<)XbfX&`CLyepPQ8oNdLggXe~_2bUqK9iBy@z(6s)x~MNfvGD5Dsi4%Xmjy;v1ub# zI{3{awxVAO9a?XzE^f1ZCYjyDp8w|az4Yad{y|0avYz)3Cio?^U%7Wl5G7?13nQkW zT)whPqT)d(7JO@piiKIDM59TLbm)ilNEQ@5*03P4`<=-;Y!cxsvF$1dwqrm2JKZw1zHfAYF zA4dbJ5X83wS~^;I&FWop5r^wGP%+%lPeh43z-j z3SSDsa>2w(_14oo8zcR3i&-U5*pk*{S=CNKp%RcPPZHyue2M#Ngv^Y7Ela5NXS?|@ zKA@V~ZL{p?RmpcE^%lVuG_xxS8Gv3oWw1cNBaPm&i70HWZVJOpp0%2Bmy5M(9CY{?Wl|Am%~rw6XZlBi>sBb5hx-I#t^-yJ5)QQEyN@v~5{`@3zRcQd z_~Rb7mR4%hawo1wZtNkp;<OH@F`LfjzX1jTsQd{CdqLuf0i)rg=?yF=^!lOKvbw zfJNa78H=D37TV!}*1CpetUZCj^p2~2sfC-3s_B=$4(=Dlb#`IAZZA?s(zWzU-!>es z4ZC4L-pZl9MLqk0bCoq6mnjRE87&FR73c#zo?&Set?pL1+>0>d!|4e^*Ewd^GHB1{ zb!_(I7&SOj?zJ{J+BI|TNjaVgM0Fl73oJL>+aBDaE7C-*TPG^pu$n370j+fb+|nSk z`_ANxme6VPLFl08b2Y2Ld8y1(J;gL(!JnQZGckei5R@hBGwy?_@CXY`O<61Bk#5ah zK3Usj?r$DOv@ux6&4S6hM#Xc*yzNNtm>v7GpjLrCM|`}R8F~mP2(sR}CNS)}ZfpCq z2nw5n@BR=N?(f%8RfU+mx~Ig&y|JvbvR!Bh3mc&sCoB?mbD=4S9;vlIsN&~udD5!$ zEo1``*y~xf0W zy3TGpmT%J=si&Az(?4UqbLsouQ%$%sEfGfTcS>Qor`F^CuQoq|Q@<#&6= zf^xq+51x_0soi~ogDCIOH;-7xn+uL$zK(f8T&!6o=2YoLRhfi?@==zH3*&P0?Wf3L z;Yugooi}^HJ8;_fDdzP`RUC|e@ev=jztLhXmngDsvE&QZtSVAfpcMGPIP!{(Zd)x?&Pzp~+TSk5rU-vd6BLdojJ{ zEMi)tT6k@iZjQ9l+gU4`Pp(0%$g=X9keI6?*r14LF=%f4p?368-_bq+HMWe)BEcTt zNPLT8p>HRmNVT6(ok0}IjVtIFq$8&yAeY4&HNXi0>Z#5R3?oL`XUglg(ma7oM{Qm0 zdU8Udm9DA_1cAUvNae=v?pk@g-K{whF2`1|g(Ew5@3TH=cPCEm0;SKK_aoNP~^LV=usd{Nd) z0Y%ra=f%$vvI2B&$}715D1D?EeCY;W(+BGBw*MAfHO>Kd>1+4_L8ZNJ1;AA}rTl)j; zK?+9MCya>U!|$WoX=gXll4gJ&jTqaGe+-s^IiK74*y>4#bnj7599NGLp=G?c&3U-x zk*@BhMM=Z0oz8!1Ufx)?JIb#**TSES!e$6D7*WG~E}Jvf%owfmrhJ}f)6=SDi?l5R z>|eJtSBlGrZKhpfoW6LP;rF8Zh8PGo&th>5;~BU25HsFsT58o}!Y@{0;j7V)r{U&3 z#nXZJ$k?nYCG^MIPn3Py)j6Z*82_p7Uj}?WI~r>Ilkv)IZL5-n+~n_M+TnwMN1rTy zO~PuXrN2vKBgvUM;b>P}Zg4}(tqT*W{5T>HauU)>>UAa(X(Zcv^>RF?QaJ=KPsyIn zXL`<#d544qlIB;hmQz=&Rr$EcQwJ^#+t;zPsxb;_FP7{wx3FnW+vxtyQK|lqT@GgQ zm0FUwYu->jsi{*!j$FzkfRpdjFiTmY2aYZWIe|?cz}gCsWZ378Cc7WC^Yw1mPOTQR zzdru+9Ya zR075Z>y37cDCISn|HfA;5nG5fvRtCcChMyzH<(TgS&8(|IJl1XQXYm;JvFbJwLH6F zm`#Y!tboGi`MFl6bG+qIm!9LMVE|E8SeSIH$2G`m%d+3P4yZPXg$S;uM7i51^zuHO ztSLp+O=^vQJP^y$JhEGi&-owM*kX__kg9}(q4b1tImz^8vn};MB>U6i{Z^Z8KqtLka(TnSj+?Kg$> zDGz>HYOIc1m5RQ4Nsjfbg8)ZaJsgg6!qz#Qux^qo>ixJ+DTdz15kkp47PGlK?UpKx#Vwl&1d^K0 z-j<)bi>;Ei_g3|$-?K-peC4+_E-~(oG62@g>FiEU59Nit+KkV(Mw16O%;iJ=0TQ3J z^9Rt$6oGI|zl}>={dmo!Wx@Q_5EBO;lzeKS0#>CIPZvN9g+=7{HkgMt+)98txo^|o z9R<>X%GReQRjGp;6tIBimcq++ZF}7VSx-i)FX$RdJTT3k;LJyNB6_u)SNBmk>Em_B zWPtvD-NY^R=?nj8x5ff2{E9D5)AGW8sZah$VVrVr5E2`6Xqw#qxwc}f-5a)N8-u*k zXeonYi5nc!%KEL~k1|t3stwY0O|dG9+;lTyh172djT-IzE6g29asGpVfctHL@u}F9 zKPKnR1R#>*x8?=?;C{lAZvY@QzK}kZz-q6#2Bh^i_9JUADmfs(t zv80+k80G>Bj7O+ziOS-1WGQoC zq0vt&kLk@VEoHz!(fvm|SqxMc0h->DPe5T_mSttp{S^|wuw0BawlD7za?}B}G#j9g zzYIB1WXx6vz4BBCkqJ(oW1_M)lzG*K4$~U)Gfmq4;$tpbs*)RuX1$4+TK3ep$-46v zyS^ixw#f1skZC#*6&)*C&bX4J7Dd)RwHG~rdYAakW7az>WbIFxNrxJ7Bm*!jSPL`e z9H>vk5(>C-^%b=^e<_AX6Dt>iFX0Trcvn9GgV}&ye_mNwwN_{>spxl=8l8rfb#|J- zM;nS&HB1NHdzayGzr#>ZL^a^xt7nY>3_4fIqOU1&zlsy{>{2i0=Z#3{8@~V;9t>Dz{{N!KyLV`wQ&A9lO2ramL1={4%qCNri!*^5sLc-I7D{8G>e~Z^fP) z$6az$|3M3RhQFKT>`@yw9C!;9&un}#4#G7KRA2VrFGGw|uI4N}mgp#FIBGT=iR^1| zTIPgT?m8j5S{VlF@XNMN-TmyY#4AjlANegJIJ8~LCJbG&i`Z~?dL3~6ekpm{vvEUR zoWC>b@Ndj?ODYUD?N)g&7x_Yvh2l3?!O^t`A37p0=$IA3@ERD!JJQ>&Rkp|FXs4U9xQ9iOk{nu}GYh)p^6fSX?)YQUPGeiV z5kA?@^E)>jm2cA7t(#|U;8_brZq&%Zqirf*9v!kH&Y_7={trTe+i`OS(?M3rOPc55 zL8rkEs3DR&(1B5V{|!YeqbpLei*3R4p+wQej*ZE=Rvy1QObCp~;NIBRW!FYENILdz zE!I=L$)QJ1qDX>`x5E8;vGooXTr}!9UqT1Uqf(t@OUZoN;qq_AFSgK4#eKn@s=&69 zQe;-}X>-s)oMYvS#P@|{6G{@dn3;!h`TTx1`f-k8(TKz3EUliFEjX~rTU(;T(O~87 zXndX&Z||Gt4SfBKUHEdX58jg;zTWJfc}Uw_3QaP>RhUq#GB7YW??v-N{RBBcZJnF@ zYGUzb*U3(OkW$RxY{`Ga%V@mr{>Jt0%IG%%^TN~4n(DJ64ZW?$Icn)4Oy}PkUMybr z-xqK?x+xgsT`uhg|

    &B(AfQLd#H%1L(bhUi`bnN z7@M{OgF;6uP3dsE)`x5GQhT}S`(E$TV6O9s0TR-ILbeLzvD7paTH4sC18HJZs+~ z94Ed|eXV0yzKA8;p)umMnS_J)GLwaCO>*PZE1y;>ai0m+#a3sQgO>`et|0c1V3nPd z@8$pgmyD=kxKtpL_h@qQVtL!YA-IY&_=MJDz#{YKKFGIH$&HxVsLZqAbSt9h)jae$ z1j7TlOf#Jqn-<~1oJ!HHPW1yJxna0*ZVKh>4ECa$=eXM(&{lBSZjnxM61fuN*Jq-c zbOGoRqW(NHDw()K#^LFq)cQtgsDq$t2o|9EZqj}rhRK@v-|WY;PmMSH2PEujSs-vb z#s1**FU+N~rYM8fN_9w3gPdEZv7v-+!Dmn6Qp5u7F7<~(1r^@Ja?5YI_Ibyt zRz*x_+)U$56miLVATcnYHVBnJIq0Bx1#OsM2wBd7rLW)oU_$y){z0m|b+b zd>2ZCJn&?xD4y6t-gFqOy8zqaDT=(exMP{D+hh)D|CXe8&5YbjGMO~9ECxZuuWhoS zH>YXm17rnzK_|miWt}C4XV7+2+A8F|me(4l-=?-g5F`LRbzR@-S8P&+!!aI6d!ONT zge-6DTrAkroqMQs^(n~XlpoICtVw$nc4=$1V8Z3raGRM}T3$YNbL7gpHf*DP32Qqq zKuAI$*p4@~g^Ii?kKqdHQ z`e-k)o58Q|C`cpw<|@p9`}A|?{WL^-krnz0wO2Ijoh49bZV`b40t(G56#ip~&8T`= zeh^Y+1Npa+5jBf|lED*>K0N&h{JqDUr9O{m+1;N-L;5!_Z-5+NgX3)N6b^>-T&38c@cF`y z>Gp6&gC8smQnB31FPD73OcQuwn=?i8&J_p_TYXNx^6)&Zx=p`I_z!6){msHJ`!Xrv zajJ*VEpepy;=#W9Rbm6)CFLe2jiD0}nUuc_KDS?ep$d&eBFyoA{s`8%hL#;9362jnkc zwN`^uv$J-YXp(7v2Mz@Kz@Mjwassdm_V1Hht#8~Am3i5cu=t$RC*Q0Qz`tOy4uXTaZRW2G~a5M zz_LnKUOP*ek2X7(s^F8bcr}@d{>r0@UW){Gg%TF_RjsY}-|4>%B9u$^0U|0rBcqC{s_F(Rr#4V9 z?%cWa8>9GbH2{Yk&4Z8M=rm(doxQ)j=F*Q%>Fbjq`)hY&WG_fp%9CwIGIHAPGpyC9 zt0M$Y6;{6*cf3O#p$HBbPL7}8Yq!2mH^VZS^ii=9xoN9m-cly@z)FSrQ+m1(ct{pZ z8{)-i#Rr8#fHDH}vLOk_^Df-`AAu)=b*_<0k2UTV(razzeB+8KP-~Gh`NBM4Kc);g zfH~4I^^D?1v4E{5RpVq!*eRuACpOaOxW{XSSp$!%8^$yCK6l!}&Q(k;zqwpnaEhOg zDyNRc9s=sH*RdaxI%X&%M$DNUCiIk9RxoXUt@++_-CjSRf*fFJyKR|?5`e#(6f;R2 z{E=$#o^gkRLSMls=@{!$QyOG9i1g zI+!QShV&F4UwCY!c)A{rAMU7Z5~&Giy(9D0(Z&e)U@dY=NH z`&-nUj5xztV^gpek7e$rO8c#`itGXrjUOh+x)ZdM0_MC9} zw}W_3=VA`sqn*9|Ut$E4EI+AjE7#zZwF;|B=Vh`sCYJ0uEq@#u+LcosP0f;o?df{lS*9&p0woTX2=i(Q6%i z)#k7x9ep@CtB-<9gl&E~p+KmEMWZ@^{5%E&h55NJ#NCp!g_V`f;aaRz+sX?5eoaMd ze{*bj_>-8}m6?@`3@GgOt`kL0@)@ve7A`g}ms0W9f60Bkq}m?#aZkP<^)`cyNJ6kn zx0Ufwg5YWS5_tO?k`fahfg_$7RlT+%o1YgQmETvtY%GW~6yNnb@S)43wJ$P7%C724 zONpl?#hBGWZs8je`T4L!T_Yd0S$c>!@w7~Gh+}gG@67xf6nZ}$_60__K**QF zIxs=@-T!a7GGi+vSZJ|CGvprLRG{5EsjZDc)o%`uFVmHudYisQ_$uw}Nf7EbxYkO0 zABm@S6U{t!WjLBHlC;h00p<2~ij6I7)LRJ;`TmPiwZd?g!f$aVQgiAl=qfCN!%rbQ zpHL1Eu#-CPL(K^Vj#vxyJ6+)^rcu5*^?tqkBT4RkXlV)%)1kPB93&jEv`nQV8N5pN zI3NsZdjt!z6KG+Vxs~xMg_-N#Gy7;<|EplMS2NZQ-_>#i;ta_)oS&9Y1%Vl0TG0g7 z>#i)5JA(9-fGj_P{gIiJR?60vqshQIvd?8G0ZBl=O5!QK`REU*7Gx3@ksx{4c?i8e z>M0zB9pc}5DFH;pl7}ASg!Hq@84dSJwh~Jd{UWlG$H6`JNCa39q8PqKJ=Abe*2wZY z>Awpxr@_0c%lqHg)JDzF;w^&IT#FCB&j*fZXuHO6fbA-$&$j&+&W};V#~I^ z_lECsa7m5ir={%26$!YgSLZaY-HLVK+6bg6JNWKM!XbVc_n20P1jB2AH@AuHSPgA) zjkQLV#C8Y+F=I*|pP4MbwOmMDtbBdz`GrZloWsSL)bXg3^z#E1kB)qpIo34v=5>Iq zHarE}Q-SVtfx?!~ekE0+!`5c0Kw$}Ff8>Twy2t5Jfl!L;uBm<1vQ3o%k`TME4@&~y z19Y_8MDU4>FOEv&^pLlnHN1>!V*_3IWQCYI zb9<-GNUL$SWT%M!{JEjw6nt!^w7L0~p^>y6^YFA!AdN2GNJD*9&2x$1yN(2eGraVF zwd0?yN|9`-WQ5K%;dtLe+vtT3C0!-JSI9*jpO&A9WH`Qq-6DEEpwF=UH8D3|H?2-} zl>~1jHmrex?^7kS&Yb?q2EkoBs~`<1A=1M!U}6m&^-aKZZx{Yw*R>Mf1v*|A!6snY zd~Za_#bUo9=Hmrt7EAWb;7BGnbE!=24KYZS%JVo!v|GBgKd!}|e#*3ErG z&UL}g&t8<#x_E+R>ipFh2{JM-f#fkqPZ!EK@Z;N5YEo#oZk`4_D8t}*`hvb^zO z%dHo*IBnXicvyj?_!X)JBEWC$nB{6C-iZard4z)W=7)dNL^k?Gz2GVELOi0c48QwB z-@|$N6}0Iqvl(=u-fL?$Af74ABEg$}YZ(ti zkd}{N-(G*37S6&-Gg0h`v++CqR*i55yTUigq>bAua}1Sw{S z?E3LR(Q}A!H9&9=A3iP1{+`c!^i9rQmq83Wmns?-OkLw4?Q<&&aX+lktS>Uh0d!gH zdX>Owe3w;h2pQ?M@%)XpxuTvg{2jRPmp@uI6Z7@le73qU$wo4xy$a9vZZe>^Lxg60 zb6Z}j9As-_l$;HL_#L8f<5^%Is6c6Jr6ieYfS?VQj$qjnsc2+pP0V{m?81HI{rV=V z(TJeVZnf-UbKxAkUQZ+E{rq~XYMJX6pCM890i9*-OsbrQnopy+w8mVwweYX~52%g8 zgzT8w;1jd}ht0#}-oc(Ipd>8przOq5qktXszM#RcNcxnc6bTcUR@5s_O)d>4$xRLH zGgsEa(Hc1Ynn)E}R2+$OkGQ+3X6qRwftLgT4u17g)gp0Sh0|FK&*w5od9q;aXw{bV z-Kl2sPR*Ns(SSQO6YW>8qRz|$Say+rK;t1+2UZdgW936h-MsQsu?MPH>aoOkKlP=q8$MBXgmK5k8UZ6NQ}d6vV1%5qm7BJ!1_SQwW4lrFFV*0WR(pm3|8f<|v%D|8O7ka9g*oNUXV=NaG3+>q2!FS=>V< z5oi(9nD{v9vl{@~urqTln{bqG{ZzK|Lp7-NXthRu?k-QiCHk z5b^Ms{>{^Xb{uF#NB`2Pq6EyM2|V*vun4nHzZRgg@q#IWy>$VV94&CBIU zeXoiCz44;jy>_K%j5nX2xYI8-=7L$L$%u%nc+nrZXdOa>jp_)6hMgaBKL-4+udnaB zN%Oe=Q@ypt-|o;J;`{gGcJAH0q-ZxfrswyMjEu~8@ry!79i$gymS58)H){MN5>xK*Kl`fqh9yE4Ap>G`EvHz&eKQUl>$1@p&jR;lIfq#i;q1 z(IQ}G#hrH=XsY*u7Sb6dnBvkbDllQIRFq%&O6p>8<2-It+uqk|sjTfs*iS;qd1qfA zC3P8R8yk5Z9v%Rt1COtXjmOqny%J1?E&0Ssx_W9mbh!bv`^v zF_jk<)-~BvvPy-1E>Kcd&w%#jS-n?ka@VZ~X#Dr-DszCn6FG6*1*TxIS!`_N*J^Ma z;3Y(2?({v|TU5;zK|5+JCI8IBn z8ghR*j^9x>G$j!HxzWq33Am>ei<4~fEkBD)V|0Z6+KppHU{LI}g2xOURu}pI)*M@8G--?5>DZiA#7m)U9wFS9Sh(4|I!=Y4u+ z2IKc2b~_YScWui^5FvLngVN+ezrQtNO9Keaqw0 zV)@Sc)pC{G0gYx^^LzCURPyhCNY4=0NrliW(LDMZ{;p#X+Mi0qpl3Ys2L|N z3U<$x@z_%6JHj+O#cwP1_s73ghd(oH!=oC~<=vDqpvDg2h{9;F9{t`h3FDbZ>GA zK5|)-iUq~wU1i<18X4_WoXHVl9)He(R;bF=7hUm2N}nW&g}_JXsQltd>0^%Mw;aF> zjU=??45}p362m184H^*wr+5f0G!_hGnOc1T>6a}Fa?zqfnbSiAKFuY!i;J0SO5^iB z`x3h_2Jp3QnAXupjOFAfsA^|m*zwmB2d|yvua=9;sz&0x&|Hein^OK-yj~W|I)N=HZJYLDK%{!H{N=GpnLm3~>oh{CA$Bz=PXO&o4 z^^+|0lIQ(B!Ro>>iU9&S{SZ+`9<&*Up2{LAOU1vAQJ)RSxNv++W`I{eLH!Tv6Bziw z2(LS9X{LVxZY^NB-T=b_{fx56b_HFRodzPqEm<2gUFT@d)c%)`S(UvEM(~cVXd}aut`WTE#6sD$dao2^iMKYYsaHl|CtlEhbwlH z*B$~sX63>c0fFk4Oj2ZEVpIVOX>iCBvsPuTiEYzpt`=o;N#ErV2>(K1A4!wqJUJc{zM@;QILNv& zJ)&)K2$Ou(M?2xZZwNgm?Axqnf+vlxcGYT>LznH6`Lzpb7D_q+4eeqZxicr0q-Nc{ z`o;2#v&;bUy(-;&Ez49=7xyE`5+iyMn@%%n8gadqMV20YO9O?SMsNs3(?HcJS)7IF z$;QC&Ra9rv*lD>ox}|36#coKIouLf@0pWM<7>@B0&WK4n3s?9z4om$TOs&SK;`eH8 zmOBvfnmIdCJ+gb!#fS+eCOH|%%F)U_La;vsM8G!sW^iM~rjVc?p3CiM8h9Z(@}?PY z=`$EQ^6#Q-;J*yc(bKg2og(KQgkFu#owUdfyy|1qs8bHb_Y%T#j|f4g5~6~ftuS++ zJ%UJ;*{0sngjISSy>;aqSX%%2WpQ!nxbdYmKnb&QmEn+undQ$iU1uj+j(R1AeqZr_ z98B{Lj6{$)1284Zr)+F&M#e&H=zmim|JRFq+pxLfI&u>y@j30~H$~nK9N0fAtf^52 znOzeKN_zZF=(zuqk)hJd1yVzHILJXO_&e7p8(k7r?|%%JkR#kUYKU5}^cQ86+s}J8 z9bma@V-p}g9z@u%Cm-sj&sj}^RH#+Ex-O3Xw3j*{psW53QtP9HU?JUMWkw>zFMdb> zfW-8!BTtH~OOy7$kHi64O|p5>-cP|VG0)LD6;xMG;5$OpyVYX~Tz`5(;?>454dIuN zh8A^OF=QlfQ`Q_y)Isnn+NDmP=V;6*8?l7R&~ zS$v|pr9_q3h#fjvG-zxHpZ*yrMP0M2)YPlo^b@B})@rQTb^F~d;M~%1m7OWV{iDsV z8TG&ms2xd1roPY^#j2%H-}Zk(KiOJLv@)Pm5Xr-MZmFc+Mfr^LXCUhZU+mm@_8j>J#AUj`}lYLpOyC>4Pi6 zD=#a+KvC(0uyyun5w_0x(4zkzQIHcaWSm> zJ}@~&URW2(pVhyF3~en`$lgY}n{dc?X3%(7_P=6LSl$1bMHyNn_ZqG`lq>vMjbVNm zI_{f*RXB*>fDZH#9p6)W8E+PCz!TeST z(;Sa8=lz30iFd86e7K2@gt3tQNs5x_5x9ddxFsC*jgMJA7sY_Qkzy+1`&&RvD4emU zAYKW2PY?6WcqWc)iw<6Q zI3KCe240ZxO3nksrZnJ0x-iystOLd>Eocx8%ybLX}M&dX`w)OW0SH3r#(!Hw?dJP180YJT91 z!vGvo;wsy|Jn6=+Wnr!a`Lj9G10`xtkl2%Vj*J?0X$})&A?A}8W7AG677jN3b~j4} z;N&WD^cCapF3*afAis?RCkYD`weTDawx+Az=a`r7y~%vy6cnCdi;bf1b$A(O%ErnD zM3nsgQ0Zbunu+h9HW~g^)5W8n<+!iwV-cz`ru7_a>YF~6hF^fq!Kw%j3t?eSMAiI zktj`hOD7Hde3Z0hxZ&`9z7nH6sZLhU1o5V)__)7`6n{7ILV9Q)u9?0l?3ZIs5hAHL zxozaDuHe+!SnCDR*KTyow3bW!MTfYNkpExp#S^Pv?Q6U~Gq)QJN z4f^8iAgv2IB(zqGrN~+K+^aMY* zTd-}IC{oXb(}h&^Hi^*1El@24GU?6tD3yA2C+93Su|N1Rzr&jY5>v_tx4xJ#_(~J-_<+vXDaVV-zPpaqXF^*`!fTl3X~>Vm>z7 zZNqEJ^a|dG_fcq1?O#0N=btB*l~(LHV(~BQqG+mgbS2-9?quZQo5?zI`3(pCObvu)LeD=gkPknHnU3z-SHb zGjzm1altwGi0$=d=2HRd_kM0ttzHLuaH0iL%&Ky`U9jN$Gml$3oHC_{x)ZtxBP#!J zMy(#q-~YPMbRZ1{kdYCl^^K&tVhkM`DcpZV}C=)I(+mY5awqZiCxt$jhOIFAF<$IAizRb~z|^sRh&>oPs>R^Lr*$AbQf}0r9ALJUu7#KK}LC+74jFtcws<0=`5yoGvZ6r0Mn z#y7t+u{NzPP(*#Z&oqwhSYLqO!^B0fmb0tYikT?vq%qKQa1t>KoUOe}B^U{94PO7eX~WzAtm()@ z838999mrlR@6sa5!Z=7x*M2cVIS2--n8Pzq#8`?KO9G9;o@$@1Enq(>Pn4_vxavux zdS#IiSsW#UYUl3gR2utMX%SoK>cY(NF=m0qs@-X!=so}hiV!_ zR}3myL~c8V^Mx`|c{w}r{ach-hC=^c zL`Tsa4Gk;^KaHe%in()OdUn=Wa}=aOYMGy;w^jLM+7c^xJ=$u-^V!i(NPYAYfG z2OlFKh*tXzbO8$*0YOiF0kUqwh+{_pakN?wTC(t=0lVf4(K)$g1OaR8;^wnyF*5hu z?9wiXvp_1svto{yH~lp>W8Xw~SDyb%u={4~jd8szY18-`3>x?Ar& zkc5hakJ;9WpA>1wJZ&6%UT}LGIqT$Qj8mgEaNnCPdop>8y7hG?)mR@8jtnj4PC0l_Pa_lzphtR zDWw|tKE+Te4eh+^jDj2yn}c5I_P%mCUMDe;z_qwo*jU?QV#Y%TsIvTgKKXhO#<94{=E6?+ z{oL=iRFL1dr0U)@f-U8BmW(@nPFL0E{&IoLO6lv1Yh#CL7WLuXoyZj4`H#*$<2Gy$ zt6){`{lVAn((e4sNx+ca^@1UAiYm)%r@HhN#6=9}Q=El=hg`t@j!CJEBirxyYFP2tKfh&d2#8ih~`SUUWWgkAM%&l?k)n`n^ zC#E{ub}5rOINjLUyys(y?GOxxbi#kFIw-O;lY1L)o^xehw;B+TDfXvCDqBrIAc^rZ z@cXzXP|Lx7ig zb>u`(H1eZwoh7D`*-n$7dfWEyd3GkTGm#q;j9&+>I(RXs$l%CVEqmSvg;J%%(GBO#GD zNMV(6OzLeRuOH5=^QOW&^r6VH4ZoON{I6wQgXqjUhE99={579vi;kxRXEI_!ETV5v zp>L6)i<`@h1=qk^8na*lv6!_p^@y# z^mTb(QlOSz!*u}H?8*1lJzdB*N65bE=osy=K28%l5l}h?OzW>5DRyrx1g_;?s-A2v z2AV7{fO#$jKr98G3!Eg4pLoYd-YKLg@mgJD=(Nb831c#9%q;Q%SR$g(zMaA+inhpkMtbUS{ib7GufG(5@Gq`hsL#woaRxBG7glG;%R0$n>K0T;B58swOIg zOia_L=1->=0H9)Xf*%K;YMe{@=+5T1#qv;?MOLgx0f1Walp3AMJN}3A$Q6)B@F!&| z-0TfFq-o@1ohn;H51xs(nY+Xcz8)myDKNTo`#RyI%X2UuJkzdi%=>MpP0&PWBzM=^ z@-dv94>#RdG#HT9Oyww{|KvpSE--AF$mA*IdJ~PTemwsM;{3B|B%hNQfBtYlRk?|} zTzt{%W^JhIhn%lZqocmNi1p{La*8qfvG;2cmV?`vjkRunlqcsDyHklU zXY$G!(Jj#mu#*k^;l>`@P(-GNI6=1pZ%%gRfev+smOXha)V zzGg%f(wD}f(r@4jY3b6vKv6$i1|ZBlyye>{m(CHz*b}I<0Mhcl#?jfy+fmt zKd+G~7%ku-ws7Y|KeZ%LZ{I>l2tBQflS7CgUM#Gxt6mmDpu&KFnbp-*(A{RxqS`Al zx%lt8z6x%tMa=yU2gyG$1#r?$P-cHH7_`qEyRA|-pGZS+SC^fw#9;CJ_fH`18e9?( zc>XlLFLqoW1fTEh?AW5+zJ;ihAR)bzF=dwb@m>VE;qa*`o|12%wt)hUD9M?h)O<8M zvDXk;h&FvHdAzd@8L6KNSn*Jhvcua0$kL+H5dh4$_5ye^8Ip80BES~$uCb7qlci0Q zeb{bUI%ZS-bA^}<XG)c&p!B zU)7WE>+^mX(iKf@73mMv)y;8)TgA;J5f8h&C!fMKl&nk2x2|0c{MbG&l7RV233${aN@~Tj3{MQ_B zf1Qa3Hvg*_$NK2C6JFuZUc3{YeZ|fh`mA`b*Vw9YFMf6rc$}5BDDI*I(?#pb-#r3u zC&6v5YQxE1mMn+u9!efoa}j!hFZ_+RkClq$Yi8?(!dbGOXjgHeR$m5{Zieu+NeVba7bedd)}PJ!Jnve6%Xp_+;6> zxSlti@)Re5SQ)qLU!>ho=@}{Ga?&6w0|2?jGF!*VDlh!c@Qt>u`qBRmzcF95JOe^4 zqO3gPVKtD=;+i3)IDd!bDpY}k9A1t%{B14>Qn*?%XYITaniK7(ME_NdlgWntu|^#) zr8JML7O|;Q5Uk-PvId&)2$oo0ZmqtlQj2iEx;6LB?u#IQ`e1zOC`fdoXnLD8Zn4_# zmBlnWR^SCY4?aF`zi5gr-AFTQ&iomZ-KzzgvncVND_RB*(kyF&gz%u3H?1UgJUfJ> z8{<-P9uOT4tV&yL?H>hYku!! z-q%fw$LO{`uH}Tek>+GIR_$@3UUxEfvEe_nYR!}3<-QZ>IbJ5|#KgrgtWdHw=iDHRt(7qz*rqsCRf3A$XDBd=hFpUskC(hAC0!axX`r zrb%Lf??=8YKHX>#U^=oET*d0E6w~Ik3t|bL95Y1-z^wW0MO~b%NAhY)DobbT_2n6AR~><-5Z{ORs(`UF>hA`blq)+mH}R)0r_${i7+i09mM^Nr z%j<%bA13L&X1e}P=1?ylHL;OmC|Z8PzSW@Ps))IsI(gP|3b{TmH}yGd5x3UiF1jbT zI~hGxvoRY%Hi@l67_~eIt@m04E(%u;N(td6GgH$MBHRs3%A0EJ4Kwo)*D$<-njBFE z>tmAvxBb`|ThXDL{cdnaBM!iNTe(3-)Np^CaQpM~O-pNtM5<1_wxm__g8w z{Zf~W9I`F4P-INX_qtDi%@VI)&uftl=Q(;Qppm*sqqP_nsMASo!B6BZ*K%n4h>kFmu2H~=lh;b2L0%A#7q&j-x^ zzx!$E^Zi6lasCE#xV*ktN%K(O?=v5zBi$B>{NJKRYV#h3Xfk*i=g`v8o!q$1_JYzk z{Q88E;z52#^)>ZN-h#=C#~Xv#S3dIv=(Wm!6g(ZGX zUzDaG9PM{D;pp)2hx+<@fMX<%55wU(AhVxAy)w`nG0!p2!A|o_N(S*ymDPYWR=76& z3?8E~mID*;F&u}R_IHAg5HyI^4Tv5~|LEP2pO47nC&b796fOx;^W;@j;(&ppIIAn> zZzs{;iX-!Xf=KMM0C5cBrd)FxTCGm?0>B6)@2NwN0}Tgdf&B5cqC8f>xP*0gs<+Zu zO?>Ee^S5W`{!NFcXJ*b{%t=x}ho@!e9LUxO9rd<$b}D6WKOOk(a#BEKIVBJ9^5)Vo z5F|uLX90!G+-?+PGsZ?o>;LKk!z>E=0#I=93red{z z2_m13Z;f_nvz!W9NImKB*AnDCRSc}Qc&R@VGxdC4o7Np284jfiSk}x`ki8c1v0W$gMsYhy9kj=IXd>^vmdtR;lAJ)4EVng{iX>fOH&>A>OpS$$ z@lj?+ZK@(uBpm{d7<>wp+ShbS(>|{OtCP)Pvjw)H+NEl&Gv+8J^?|=94 z@biiX@u_tq%P;}hjACYPRxWBR0*?s+Le*};*kck*_I!&XW8kHp_N-+Y{%{Cjflpc) z3-Sn8UDm5}#T7f`KG$>#=6(9uahDM270gW8e$(d1{u^-f?)iid*QI>QChQ0wG?$Pt z(^8_#RQUdgQ{$8(F1sX;fby`JM-b8aLx14Br(rNsQITVxqN;z*9hm-J!+9Ux3=rh` zeW=}3T;!6ga-h88D>jo$nMfsAw@!b=tZ^u^cXd_U*4iun6XM3nc>j71dT4zzKR0@l zcN4Hjcb7`AunC*PWEqj!g$Gigysn?^y7O{d=QV2`NHm$Lg|iF+2YqGu7m$&5C65S6 zTO8Vl$L`OTMhGxUV2hP#AacS$$k(^$;@=ToIoBEv7qNOZl0a@^tbr6hu5W{Pk=}t= zLlA=}Tgx^lGEj>pV&tdq76GGak(V;O8Vq_oa=Lr+Hrw8WOZ-{n)7BDBQuksPEKRf4zTyMh70aso zYI}Y4&+GahTtpmKllx;%L|#RgHygtBpnX`0c1y|pjVDy6As6RoAowb`+2K{*}h?9mAcg2szgPON{}M%dg~xL}Dsznr0=Amc>-+Ro(0h&)_0O?TYYA z(rxa(V|`_*@S+>bVhoBN`e4;Jn1z4#KarxzP~+HzeyY=dRCsgBAkQlRw=4zFri;YK`|VKlYjq!bHx zj)F`zSFSr;b&$N(vJXCm|II{%sxyq_oG(F%A5J*`2qeU)!9N=yF?YCW9VnghE|W1U zZPQW(;aL#Zwd zfL|G;s8S)n_8wZ7s(m*<@QT^yJ_H+ra@$Gl0i$P7<8QP?(fnfk#nk5zlh*(`csZRB zOj3r-mI3oe@E#Mzyu-sdq=`BiXbv6tPU(NmJ=Y-j69w*SpYv+cU3pQc%{iDcL+{g{ zdGk)-!|S^#lw(;c!`@Fnoc~~3Lbe?6|2-TUv=*Hg?I#DtAforJi!qiy^GkxQnex;YprM9 z8mceMEz1zUuybf=SETW5Myp0mmFqnr)cI0{#AG9`o+z|2=D3b_B(BOhlpi!r`0VhK zrG#Ox9m%M)t9?fJtnrP^c+4dK(-i#e8?)Kyu+@&s#jtUu%m~gakvy*!5hjmr<%iaA zafkYE)V!Aeg6SYD#<0jsy_v4qQa>TxZE25j7mvgkFPOXy`5?yy{sz$v#e65&t78aSQ{73aU{TBdpJA@ltJeza=@h-_1-rHSOV#Sfr zQcvb4iRlwn5X5R70V7p>FWn8A1+?cL$cVQ;zY{KygKDpP^;KJm##f(LpSLUOe4*Q6 zC!tG_6zBFBDMvgrcWxeGJw$JQDscJ9@+>Fm1de^mRldHbv>e9^&DaH3ccaL+VJ2U= zid=*V?0#g2N+%;=$!&s|nqAnHmcXIY{D)n$QvXuTG5H4Z_T5R2AO7O=Tmrotd(mey z5&qL*EdiyP(fhs7b3QkAyH$S>Tu+A{Ly3-M>-$+Li?4iIBlJ>&xh44s6)8I!TqgaP z#~l`nM5N_ZYAA(gs586w?yBJ4WR)gA%(<9*IVyGM%xp{xrw51D+Fn9y*A>o7zOmUd zKE}i}?tvYrE>`Ps2}<>60hKqUX^?osBKTJXjR1Oo<0rk!@u^O_?Gt9U9e7_)L>>0| z$_lDko|_!T(wxO`zWBMUiPy}^nt6agr&Q*7I{<=O8icb*PQQjmrGqvy(msJCurFM` znyX?gBP&Cy(o&EFGJ6XK`o3!^(VnQ?@cSoY~fPy6bs+`qMrWKWm5QJXD)es z%1PL-`5ETiMto_GQhTWmhkswnVUs6>K-KC+#j?M}?j-x6YrK0Y)HEAh2+O%H_EKoi zPk(U=%elkqa0*<`M9FWWv(b6N0p#U9qpwyADdn{W-F28{kda#HzY(1R4EXO(n)- zH&53;zgJ&$patva>R?Kt3y3qSv&mTFO99_BYaTO|j!r8D-!#ARy+ixLK}|K@)fW=Z zAY25qM?%VGwe~9IpkV=NeV7Y@R+sw+USn(uou{|qVMKzNqHXiO;&>(+!^dacv>-*U z?d0aXDZ{M&AQX|$7xxrDAynTD3ZDJ=igrgq@36VJR~*FXDnu6J-*9C>CmpLShS^iy zPxYqnVHB`(bzb72LP?IeL7eJrw+IV}8-2DrL*6Q_ou+OHc3mS9P@i0`} zWQ=BRho>kgHPZ}9!eBuaO*lo*&qD2Sug*xvT|lw^}+j%{C`1rQ7(E2zprvd*Ck9Ho~F5csyYWZ(^MLCDZz_X2IaDv`u#>Pv!J_Gr5lu zpq`Ok3m^}|Q>-`9N)w-)gghq2f8t>xZMOa+YyKbT5ZD#3oKaT=zxX%R33MSu;Pc6W zw7UgvLL?F>2`mjcTPKgU>bSHGY5;@wN}k)g4iesGpV^dQYaZEg|DNo5hUiorM$qxQ3FBmmR`g`D zvqU*UK>H_pCf5KYj4|&1Drd1m9m6M<4_81`#aK0?E@#r9IcN~Dxzrf~62Z}bRws<= z{v*qvtW*MQ|JBsg%&e_z!U>gFXF?MFjyQ2pka2?kIG{gB3-%2TswgNZe1193!Up`q zAohTo_<=N)T=ql2fS0fLLvjT)0NA>{LD0j+Pr2|(b^d0&7!fk|S_U|l2WoW@2?Zc= zVSH>1?6ljmrS48!Z~{K(1!!oaTB1pyD$nxgjNbM23GDcjpz)e24dlurdSimlmfoNP z0qDQ_CR$&TN)Ac?8UEeu+|5S+Uz!{zG8!tX!)h-cXvR_iVg~@^RgeKbg15Ddg>rjy zGvQQy<`Zag%asD!XHq>Awb?^Ls^|eh?Ra=#=YwSG8JRDG<7v2CBxqPpK;ap{~??Fwkt@* zw;O2{O%be^OX|a-e`nVG1 zwolY}R(Q!@t1E*XG7k#Atd8r>v4#t9ai;bl&M<$bhhsX=BuQ?tB_POa(zc;CMGIBm#SzPqO$9H2O>XO*~_(C z@o-RsBdn|Ija0I-FYN%Qo?6uHf?8l@MgXmF!F)7lKsP?-f*dU|SV^GU{-Jl9;l{fJ>p0sLGaZKmt7xi&@mlSf7M zM4Ib~)qfpzJQmp6j^`hk@W4>L6Fy#ouqcveiDcxlDUWa|zvt%m5;5(hJjN$_R3#vW zr}s4UkFJxDkU1(u(<<+)DO=D|N-Zy=qTc9QS9IrA*0DprR7e%CawoT5w!++m7Ga6@ z#~RJPtS!QBJ(T^AQqnW>mCD~fdx_}|fBnVlj7XwN?xv)Eu_O?7%L8Cm0q~!_Dr?Pu z81gr$b2~VyY`<_I=LrJTsb^Tf6)0x?`Cp0N$`bGA-^G{Ezz=mJYCG?7JlOj3>dOl`ntThbdi(^e5LE&FJ7saTADde>d5+Dent_51E_jrl=u ztU76)>cV_@U*yb(gQO(1$7XGau`6)+W38}*WQTzJH+Dn1RlsF-K1UKcqqmFx6~-le zB=y)_cBaqud8KXBRt?icZ)}^Pfl2GKyvnD5n+kKyN>Ykri`;@n-F3;Mq*}Z(_Jv}9RrQH zrOj>L*8c-oMaVs)`E5c+wYGPV^UMRN+8t7nq)Gq1&EWSR#wqjlYpVp=lrkFg7|u8+^4bjtOkihl~2tx%6B|nP)iHFbl+Tic=D_nZK$t*!dRQC%4gOv=Umz1 zTWHR#VYD~-YyRiL{B^ge?ZP>-*T5kW&J#5u1%+tLhY}ORCX%ln9<@v9HK4N>Y+~zq z?MCJ*Pn*m3aZK_xpSqedR8Kw{x>>BPHr`|^Eygd&Eig5INceEFK(g_NZ9<2@dQA#XPk`o5d z_to01Vt{wvAu;w@mwEB?`+G=>w*9EQo_QSj_#`BlP1+IQY2iLL_9cJW9de0>OG`^1 zVq#E|2RJjlpL&HFQ}1zQ7U1?C#5k674|dL{A(3%>ep9o61o|{ zyk_&1j}gb%b!pgPjd&4hubB!j>g}TxWXGaD$u1)66N;@SXWLkjF{+q)Id%p6`qV`F ze0sJ;`5vtCb`&W?g8KoIi(I58jN;HemQwGG9t+g1?UCE91_dIC-#$$8+xL7d!G(?7 zp<}7!COeJUUVP0g6j$Q8uN1Z8Z8aSHb>8WLR|(FD2X%*<(H&Iepcl%x=%}*WYJC5P zuD^_mt82DEVF=Jj8VKIF1_{=VH$1@CN5CEE@6w zh!}>?SUN0bazlLpW{TC&uGtfEJQoRR-|Sp3WVzBNkT~sxS%)A{;kUu{Kp+HgM4gi= zDJ=Y~)D9#yW1xrQXDDD?j-$ThWsrDXbM_ovB3|%iSFVAgbdXz+(f+EjohzV zz~GplgHiJvO9HL~GP1 z?prQ?%*iH=c1&T~xG+JC-*nz5wO=1x9ELJPNqk5|JFVXu%| z1mR3eZ<;X^6KN}XEd__(F;+Ms0ev=fQC^}_oRXNBQ-DTWRw3C`{~E`!X~4^Q&MUF$ zGqg+j+lqMd-*>-bgmk}GujRp`e*Lbr%~n?+mCFO9K#|r&G<%3zZ`nc12bv|}`}|Nh zVbIG z4T&zOrtPI5fV)xZjopXxGf_*I6EYAYO_N)*YyAY9*L80TE4Q0X2Ikkl<=+ z*(_2%%_425d~>cv2-ULoi=E+etibRi;W-MTD*{9G#Y*W(<-cv2@RXly2|F@0);AS` zLYH8-JZ?`T65NdhCmKWjg(*-7iB$=~_~}1BCBu4HrrdJGxKmz~5A>tLzY>-mC1IyP z+%!+>UY^+Ws+Kl-oAo$GyzkU@amEaDrcc7#ap^NthP5{?JbJ_DCI6U0!!f+rP7oV0 z?Bh_l`*bq@MZwgKN&1c3V|W+^dZ7PS$(mBAOPhz7Ig?cGq!fMU12OG4%iG2#wmkv^ zN9RWH45?YrXbDL0!%a<)^VXA|tfS z>(*_`zL858qEEG*(xGE;0{DwSAFy#4XDz4Y7>l$$q1 zcbWEqDLM~5C1;xF>|{|SD*7kVnf^QJ>jkBGH16?2i`NOFVwB%|FIhDeu}Xp?2ofEC zZPydo1j{l1%1HlW32((oc*S$XAK+T#%rmjP;%$^R{Mz7ZHodM8v^+yr#70u`r()YE z{|x5aM9IAl83hU)W2lz@pXfuLd7!OX?qnyTqiy?3+2|%f#^_Aw2EBvG|hW3}JC-=`gKl#p@3ZL$t6PU>_f2PD~*b{ZA z7Sj#;Ag8TO)}HV=O42<#3QgIL^gE(A(}V{s`cULack8daeZYs7ykNt5ksQY6t~yhi zOI9c?8^Q|@8`LgE4RVxneL2ojP&kUMYq90jvZyMjvP)0>S%ZH+C&t~Wy6MM*C#gm0 zr58B2l}bHfQS&jcc_r^gYs)J7;AEhvxtSmd_cRhOp>T?$t+`oyI(;(`POAa%Xdk#b&AXD!wXi4vaX%Dhmx1Cf(Yt@&=HB zHhyfMtl{LcKtMwbDut;o#mR`K-z~GIA0KX^J`ZLb*4H3MQ>inXfj1syXihf^)ld%5 zBnxIpNU=Wq1{%E;R5*Mit(rwI_C^fLJls+=GghEb;~f)PdzADTlPilza(Cq{1a zYHnxW!0{&9q(;AOGNfPNxjvr+k-$0~QF3!_2(^A~4UZzPw6GB5Nr3v-VmUkGJ7|`+ zws1pS*W+->8b+Q7b&+Pm(dB7>^I+Brr6*kOqh5aTX+m7{osPM}`R0ZVQ-z5j>z^#d zwXxRA6}7i0Pt*ubt^yS6b*)%Qcn<^N+Q2!Xzlp*%J)2eicO?wBZ z$=amT1B*;@&$Xr+L%{7};JIR!)$S!iU7LF`(D%oZ|NW)?3opzOW)+f4h5++erDF0i zGjZcoKTWc_oC_~lyC(5e?c$nkuDd4t+5)YvXFn#yZF(<%Y zpz!n8*tr1q`F+rUf|Ntyg~gO-TM1qF0oUjJ%M&W{Pu#e&xX72K8N=;AP2*VL=y752 zJP>=4nYyfm+*u)Duk*fnD!q*;pwDYzkzL8E5Oh>sUzC5<=ua%`qq=c%k6po(FK3MG z427k%?mJj2xkRniPBH{uhWrY(*D9xD^s9y4JUkSI)WJ5%Kq^1wrz8_tm0C#1r`0fy zsi&Rpz}u8B8Pp*>>*{};4#+SU==WRuF#toc#D0rb%6Eq!@IdT*l4JRVHZLsj>tKXE zY18O!6t^E+W{N=rde@Q=4BdNCO%Jf7l(F_cLDygySOer_N5;g9!ZN88_DN5PWztT# zJ5@~5sw{}AEeL%z6SjrlFWJ$D^Zn`tB&q;q?ppMrr5+*2oY>*& zm9-ZXnaT={Cix{N+aer*_%cSpN^VPUlVy*KTYxN?K}Tq9DvD^IU{UciYT zH+lr_mQ6ZqUFy;~i2@MWs_ol}efbXQ6-!dTAIDOumL@T`-=%NUXRtsZuVQ_k#CNqJ zI+;Hok-Ago$fYU^zTBhera4AG!?7{FH@z`D!rifb@g5mykJYUeghF@Y|z61 z)XY^lnTnfC473hIHq2@~*vQHrQLThu12-Yl`G<-){!Q?PzmmQ4)+N$9av;3>6)EIh zAy97viW!URrvZwE6-{)MK$}ZTWTNCBn-{SPm2povTNkm;J;E8J0Twdz`5r-E9$BB^ z)<6d3vu^04TJI}Us|p|3wG-ze6xS~0$q+c{K34%rELHC5pgI%v=8tqOe7J}{=kFLo zGqGCbyZ~2fml^~orqluV*RKr^#7iAk(lMKGBB?C;h}#V3bkdFpJ3}f=c~QNHKRR(! ziK{5!g4C7vUGl5P52BxRp8==ERH9wYZ*Va-tLT(RNfxgRYS^|Ly&JtG_^4^uh?6e( zT$Icj@Xh6;k_j1X$H-2)&m*tC^DglmsaT7yO7Z${EJnr9U$C`AlBM-A@)4JAC6a|z z{Ekg8Wc4?xEE+?rkM)JGH=d$QT-c2JyKPc7AaKT^QM8#sR|SB*6AGwi!DnH?G&H0V zKcLzt6N#siK8y{gI>-qOG9zA(n@IsLND)EslUVG`Q9y4dEqJ0-zt&d{|2(Q%f)N8T zG)dmVklR(#n{G+Q;sy?}n~1x;EVHEf%ZG)9RkZK7V@Y!_li`-iufyumwT^SrnfDwX z6_Iwp$p-I*b#^?TmkxSO;SU}u7kNfemoY5=_>ek&?X!kC#!1$!z=pztfdS0a?+?Up zODsn1Z=+SqVQu}jx-!RzZkPP=ettV#np^oTXA1D;C1NIs#}^`)BfGWRBmG6Nl( zw}>}8J19_e%%*tox_IpS0eU6x)feX{i*H@^yl)kY7(ChRXoa)=iB%!mmljgjm(N6i zdtQ<*Ei2gB67#(h+4nc#5@Xa?0xr@~c~*Y0$JM;KnRt@NNUam>eTBCc(#*MA8WXxL zE1Bshe%t|?o;k{`(+_EoxoGnDh|=-!I*CCgw8-&PMpnk~H(xNKqTanU#4fP#vcAfs zBG;sWjmwP$NlFr@X1|FJLQvW~q?Y+seB3WeO8EgefnAYWxgh)scG7z*oE=D137Zeh zhFMVC~v^i_BE(zc>kikr>)9$Z#)1>EZm_Pck!24h{|+n{6;Adm&&D zkZlT9am!SG$v3iy1CpAN0d8510pg17m8CbgwlD|@BV|*V!V~&A=6$2~z7MY2j?H|2 z=>p{`20QS#WlltXn(w2uaU)6)}#gyhEE@U?h6Rc~J(IUOBc0jYku^c_o9B!y`QU6+ux zSe|fsOc*sq;?_3=0rgsLf>Jz_b%7)3MWtMS?hRU0^kJ2k2E!GdQdlsW7$s{nGy2xh z4oh$U{+q9424>PBMj!eQ5?sKjgVG~iLd?s5D;*a%lT2F?Z?+WlpU(XZh4fOSONcIxca6zX8A9X2L~)Y4 zI!mL4`hQ^E5>Cz_@3=KT8%>5qz)AM^!z}s(BO87`$$fu9rfb<6^+g1c3^tBRIN3lu z$#0SzA5IKyBr>v}zbz=}UMWmrqD$}{CAFsVXJ?p9n%~mAKlRB*Gya{n%Ht4l#_Iq5 z-9G&s^gk?FnT=~4t92BsQ2dvN{oALZ16UI8 z=DgF9%S@>ZGjo3Gr$aG#vTt#0tO`T7I#b<1R86xwy}V`k6Y zQ#&ua3)sBqjhs*sG8V=^*JRn`eLty^o?h(3gGa44jNfZBrI(7AEy8{5HR!0S%^%G6 z^ETgsV!2K1u3%i}7WB>Q7z2hz12_h~do?d!X5EbGh9tuCLR&BN7r~Q=up*NGw!!I> z`qwNe9UWqzeuCX5CX9AB^7U!+-dCuKHF@T)>F4gaH+()-+f&HSExy6&L%x#tw}kdA z?@${AFOVv*_O4BQs98~w!-!oa#8qPdzdD2EaViM4vAhu;eb=<>4Jqm%Wux1b>)pxi zbC@H{<`0t2t?Wm#3a(yCf_wSt?V!Un!~vwB(da6o&djGP7|8g6{i*B-ZcoS)KBFVc#BzqB;%$+nzV&+eW7 zQELa%8N)2wFiF+zMNFvIp>i-r+7}nXOK>sw{ekFjU*NOMPHok!7rXcTG~n|HbA<-7=}nHnaXWp<>d^|EUx&-SL$c9aC{4K=qqXeUJ}lRkgxA6?>#1c_j4C7CLxSs^k-}#zGh)}g-xxyzWSHWYzR7)5EukU zgoX&!g;6A=&5(vx<>!krplSWE_LS-ROMAHSD-{^77N>Q3NK(upr@tQ)&S4lGo&WOStG;bncYV5&m&ZVg z-SU3q-JH;A7avSj4MflPkg502wUFZT)|RO7xZ`z%exN@|LXb6HM=350;rR}!KopMc z3xR^qW9*Qt(|AhNqtX1+g8Bc`(23fH1WdbhT->bFhq0g}+ z(dQ{6-mWK9FtoV69&7E%2B%#w8U41gljiKJz_nRRE0U}Cjpg0g3GrRG&cPB_EVJNi zSLU*p3#HJjafQd5y=gdq4?NvLVXEmxQfiKoN&Zu3XH+pG7s;xHr=iNG|aPA3BB zn}45_);J`zBZ%2+T~fT`mhYp`C9&7BRCJYj5qg_W=+K2Sf74cqS$jqRA?Y)fp#H=N zG)7DC=`HqJ6ZRAH6L|d30N1&~_3_Up>6R4n0F8eXjrs6Zue&REqJfw(b3fTXcdO%ip`tk3hv4NB&;E1XPXl1L z`S%h{ZYM*=gjon>iAxPfMPDf}$2aSysrQB@Rd2yGHv+0Jv3~cqR8-!hH)x&Q5Fxt; zd2QBP_G$2gIcoF7lJ#4C2^nrH`j$Ky7e4DExPI-}y3;z67>u0X{DN2^^$w;$H`Y_o zhtz@j-Ou5CG(|axk z5&Zkk5%GLiLjPbjyH8E<1(vF=E#Dm94d1&N2P*W8o#k<8zfvI-+n@b}m!Wfyur=<> zA2j_W(|Df$;>V2l)$XP|VUr=NtfSBOsSKl7itWqG%Fo<}JHaiS*0OB78Deo>)I--CWtcV2a9UyYb0caLYM^MUiPxgga@hSg{yOEST)QA^u>c~5SPuigkn z(0jf}=_|zicS{C;z0ueA^5O^dxN%8I9Jy+ek|4k%?(4(Em}Ec0NBU^wKjdgGgM495 zJqSZo!HOT3fkibK50C5z{&`yS@7gol{a^`&0?atzaRd1+L=+Uz%Tz6;D}kI5QBhH3 z0s@(^A{2RPMW6>`4G`7a#^U&eVR&NAB{$Yu)sTGzzHw#Q*qY^>CW z4`3iZ65ys$Og!nl>^d;yG8JQrU4OYF0ssOG6|D%rjKj5B{&ApavdI-{w4oh#*sM${ z9(u2oL`zXDH&IwJ)m{J@Y~x9@)x1;Q0q(!lxz6~-`)W%|0yJFP0m1EDr+L)^Vut=3 z@6D+1c_=d#=91M=F} zASL8Y{xqG4L|u3;1LAED;NoqNpU%w+_xR8nv{3&RTnPEi@w|MEQ!XRc<8w-;mq367 z?^mQ2lh4J7Ww<4RvRb%&A~uc~$x>y3+KyS72JP;=c_3Muayc9GOMkvmCa8L7}TI#2wl@ps!mSRqL+QxXMlX z(!_(+@g&M?qsd@opbU1I&F+h|brGAQ^9ElupG9Snovh2d1EfVG!O9)% zT+tt3-zOHlPi_kI-zO@TrD#UKysN}+;lGKzb;Zk|`1oPdbCiB{$H;d)3izgo(+M$2 z#Jhllu#C^?Q&KtLP=ZEFZg+g4CoQfkWMuW!R3u`*bTyANw_|f60Z06JhK-p%^2DcG zWH0AanH3*zOoEOkl(j$7tg8FYZY`E?-dFm^vp!2B1$?IzjPX3byW}^05Hj@~=bCgx z!cZ#s*;8KHVn1OUSBc!xfDL5sfpAp0Wfs%9Q68iLC%Z^+nP%XZs}BIfzyI9`IuTmm zHq`gt-k#;g1y8?pH=wX24_E7TbG2HguC{j6W?Luqc~Nyqw^4iBD#F5HIyrh_3nzKG zLGi_NCaUx@6@2y#;fkED_c5LU>P_=p+YeaUsEd7Q| z|GXQrZGm#{b{6|yF{v^sbUv#wZ|pQYOw3Hi9(U|_ThAA7S$6yuU+Y9lw23OJH`iB^ zV6mm4z>r?6ns=boea~I9qsXn`?{n94%Giwyyi>7iOX5RzgQhX}UI!EJd$-Bbk*}9* zwL+Wi$e2PYtc-+0FL|F=6$C=E*N`f&8;9G9-F?v0?`>MqkJAsH8)Pms5#E?(V_@ho zfOwN(W2W++&B^BXb$AIzq9U zj?mh(Z}RxY!1G+U*2FgTrW1EEgPblfSp2|mqgttTnl0$jMmm6Dn0wW7pmMD-z*I0f z$_x0ukwu4EXuOHMG@KaUamW(6AgYK>!P=|UUNBR1y0aYS3~wW>*RGD z&Lr=-jPuJE`L_3L*WXBxL`1OT83N-3vvtcT-HytvNsWtK=C*r4YVcgDs;^W;t~2o8D*^_2ig;E#O|^1!+7(p*QeoW}U{bqT%K5D+uGd zGQEt8W9zxd?uUOavjxIOZcAZ1@OUTT_q<@H65?R#b-iG>tW@m!*Gz%)e{5Ih`L+p# z+*2`R{j#bO-HvrcxVM_l7qXF7$yzWfg(Eb)btQQOLy<^%n^J|-daC=~Kc0mb0~3g;HD3bhZBWx`6jbU;ER zQBGyWs@Y5%{E=H~rnR)1GMxdYQLrxEsAzMsqwdR^fE-@oC$h8MCi31s?z8s7^9dQu z=LOENS$rk+H-ypNjBQZHSpVY-TA!QX9k+vWaxYIkbdQRt+y+Fq-(ybv^G;~Pct>wY z%X?DARJ9Q0gDLnw#s$;^;gy}A##)}YlWdUep2;X8?BrUMrsG27>gr0$fk{2!ih{12 zt9=V1;x0f||1tZd)sDQtSIS0P!6fAnp}wtBt&6OGuac1&69o*X7zeG|vJ0#ZbX{JE z@uoj1D+pZuVH<g(c~9QmiH$xgZzvrLuT>wbkpyi=%F>+tX@kszt)|57=rUn zch{=ZqhZv}dwH)tB93{Fl?VSR#tV4%yQE}{?15DE#< ztyHC5E`{f+r#Q}O3D!^wPB*N7N}Oj`Sh~f{&2xckcC~=>I5~J^b2YGB5*f$-3AiFQ z`~C8KCWQHXYV0T(K zr}#V6_UfB8dw5gyf~KZa7M_O67wR}r5p}Y2kt7~(?(cMI;{boHzMeCR$5{M`%Iip> z&F%aO>cU?IgUo{I^W-5ElR?yL)G#J>Upc<Pv&H)lgK{O2Q=CBf;SN1s66 zd0^~sOxyV4{O%>|(S<(%8{;1(o#4PuRhP&^MO|s1E;ig%LB<^4# zb&i}5m+BR>937R{-hbpw?uYVqM_UO_uC=>OvsuY6k2^Z=zH*L_Bjg+aw;98$IlpB7 z6^xkKB{Xb1IuW}D zvAtp4B?lK<7=LKm+C5{Q$ z@oaDLxi4|RS8g3Hne8_%Vxe%(}ZJs z2O%tPf?iB*qOMam=5Sqq+DWO{uKn-jb}UrdPBGZ2_1$J_lYu*8aT9k<6pttG^Wo{Z zsby3lmDwj0W80~s9>6G1tv9?2B4cJ_tbJ++{FOn~Y3Gas&P72%UlP`7zr18>>)jaX zGct3-GZx8xPlG-wQ4qYwPl2rWxmQU`wS-zTUFpE?VTnCFam0XuF*%Fj`dq8NEk@~c zcjITe<`GayA{bubPJgDcM~1&tyYc!dJ<*_WytRUjCMhRZ!TRn_iN0#E1i!2YokL)L zIGWyWn7{DtnwM#IDAtEz=kHH)eChg~QlvjYy4(?_m1Yk(*wZ1iA2(V*(Z|{Eym~$z z{kB}Rexq^sr2qnY6;3^9AcS{QZh;R5`%88Bq zKCrv*U4~RIlT(5&_96X}{baE*-7K4(`-2cCG{k;M;;`_Dp0mz3OiwC2m>uVg>jQNV zw`*sxZ)a5Mow)OxjrA-=gq@FE9yFM7woB2BeV&uan_hl-Gi}(h2^>Jo@7;Sdp?A3V z+u$JYNuE3?=J|SH`lQ>M7fHWb`JiWq@=f5U@Xj6C_noJsdrIdwe!Ry_{9y?tXJ&nS zfouydvAlUzRf4x+ovs^Q?y7&3)phM%nm{Y>n6En17L3 zj6qb(x%@Pq9BF%v3gbtA#`DaHe9&&$#d7?TRF#6Ipj4GJ0Rf4ecaR0ffZshg zZL72k@6h6MuLe@)6t{%z=4ZlfjEw?!qb1Pk4uTHBZadtH`WQF&*h-RtbM?PJN*-R8 z9^eqo&t<~gaCpv%pdb1HNo|wpDr;wMTifs4gk~n|X_WD9IU2|dJM$KOC1@E(u?`>U zoIIl|R*oiUl z7cv3Bgz(;muYHCv!pF8gA@>!vvyvwRT%V?T_t&p*zv-u?O2 zE66Eul-I~;=zWuZaxPGkeUP{(crAbg9}Q59-^%5hV3JJ`b0Pztew$yt+%!z|!BqDX zi5DOG(;`pZlSC0&hWzOk5${++qT@x$=URPrzm+X%c%C2UG}*aN>!hRAM-Wd;EfNTZ|q>%{<3hw)O?;iqp1yWP(9~}j*+ThVV;sAtp*sn*ysExPueTFEM z_NEGCJNGX*kzy`&58w>nEnB<$Q7Hf#LYewNB8GLqX15gRFCZXLfwdqm6CX4)Gm|r4 ziZgVhd>6L=gnPJ-B))~T<7VMmj2ib=I36|>E?ypaSI2!vBC7olo_O0W+HV1YxJS?% z`dD&mZ;WjYF41?5h%84J7{rA6@R$R}WbduLm|C5vyM+t+<2~oJE{UyEwIqRNy{(~Bn;3xKPkm!=g7V1QdBFF?kUQ~e)WeK?u%^#es_cO-Cr2FgAw z8Hjzu65j$i1~ZrRpGIaBU7hB{!p3H1NO(-z!T=hotfFE7g@}3-78OxYQ-ALE7tT9t zKwl1?^ub3eD3u9-mr*9^A7q8mP(_4GhRH-@P3+7$dJF52D4z)ujwc@;BBSEf2%wU+ zu$#<$2Z&+*UTWjDAh=u*d`oll#N;GPE>O-L4-R0Z*|q^}`b0=uAvtlkmzvz=q2mObSGD9&YYsi5?s8C~K?bY!5 zIVjP!lq8KgTr4J8;kg{IYG~c1S@z+TA61#QmfuParyF(fk;^D!czAf@MhKzZ?g+k< zi_2yRp^dPpXaM(eM%RC-7diQ<_hpRgA^y7{cJ`9W8(69_=^%wKU$p${-W!j{g0~5< zCKgxxLPCu84~6{a33Ug;ee4BG{N+q@;&y9NQz0vEThZK(yWp`bfyn7%g{_e^w#M^* zLJTY{$}vG2=wHRoKUV@9GlqSS!2TR)u37#LxmM?`Ot^F>8K~R*>;88_AnaGmwk>#U zOkPdH)Rg9z&!crzbhP^jpW6SqgQE#dkNr34*Awwf<~vJdDq%@8>hrCJF=h0#YVJFq zX)g({g|&AHuat-xtVKV>)USe6##Awtt`c9LO`)YBs+LJL*r|G$ly_I*{^ zfbM}Xo)NEF(U(3$!d^<(JDQ0M^^h3J0X58#)fH>VaoI?k222wF9vYPJ$1rm(qTq5h zgn8mV2b2!hopz>d1YU*DF2rJDjx-?#D!)9-WK%`*U*L6Z%|cOo-oHOTqM0BaF%26Q z&-;|NTX)AqZ$;8I1&nY}=y7e$Z*br)Tix=TlqN4xkyiVLFJb>nwPWfGB*J`DcsJ)( zYa=VFX^}yHh5++KBi~cR<%ZZAKNUw{+GDQ9UP($LznsHm+z4lOJg^>7cb(md%yP!b z7;p#f$>iQ~)oRwS>m#4VNBt;N{3)~JD0P?3S;IiA8~#BHY)JSsQocB_OaD#em*iwn zrj1R=C=ei467`9s06-zC|3g%UiBb)3t;O)|O&&N^X_jwpo3p(1udQEvjScG~9}=#Z z3PK-fPV_zM(||^e?atd9>N24uqvqUSW9^Rvoi^zy4|dJFzlLRC24?7IQpT4VSn*_3 z_AO^UtlXlP3Yp#mkm))jTvNpk9U~@|0-x5kc`?rm+67zK5AL_+y-R?e>>8_csBTcC z)Ke=#)$lm|LvPb()f9RwwW*;x^#nJ~=^7(CDC_2s#+;3T|J@6+JF(Yc(Y&<=N(n42wq)aRPX49C{@= zngfxcuXd1h&=$DSnn}}-V|GQA(8aFc-d)D)vv-5oQ-%J!dQJ0U16qWL9 ze6%t$CLki}oy?c2wpwIm&~1fC#gb&&k=b$T|CgYq-W!6!j7rDw)1m7g+J45W%=d<3 zS+Y~^dPHNEjf7)WHW)!2qoIaXyg(t^p&ZDVxux<(RGxF@A^e|cYN8q@+DJ$AFw8%u zXO$f-h!aOFB?t59I>i&nqYkKkqnFk;Is+3nDpKN1w8Cie`Hl+$?(gbZlz~c|>w{k? z&1`J?ftsq^?(zod(BQZK*NVgc%WfKv)Ug}nNpmC&y!o$*4GSA&{xAO@7DfU8-*BM6 zAx-~XTmT0Azs3_oDd>OO97ZepzqU#oo4iQiuV^=Vd)pWS4nb~R`hCgyGrk48hBIn!2~YpW@xS_m}d)JsW=V z#VTu*O+%T(EeAzk*&VUuD*y4)Mh`qb*W}cU_=&ycQ$z@hK-#qe4n;fpW+&-tV{G;*&2oar?l6O7-0K7yzFNii$vOy5&s|M*Q>k|5CR!)=rI!f#Zxfg*B~Mu7WQBpa-@m$Ti*@2tw)|FBI7Bb`X{5%e zCWDIE@YJCDxV&9SVQCV=uEBMaYVNWiSzvvCjtz&0E3O;wTpWOxE&L&bb^XcQf1y15 zr}6=hf-{fTbM`JQS6nETB5fqoewgg%=Gr++I4W&6`H2$ zn=OtxeSnt#@ge~wi`22Aui_Wk|N1Jn8*V+tOf7bcOT92A9 zGY*}Z$WW5%eQPcBt|u;UTRcRs$D$l6*HAVH#QC{AubOs^T7YoWQEig-HgT0sV-0k% zqYe94UexNGdp#azC!kk*>HBx?j?{0EV3a?C^S1VY@aVS_qkI^X9}NJ`^8d(I+3~h_ zFDw#ww3LeFnd#_6WQY}ML02O?B$u-qmrA?oU4ZDE931^==&_W*fEJr+Wj69bG`|Q8 zqu(#tLq6JEKFEw^OG_d18m(ao*qz-I)8}@C(FGjl+`YaHLSg1AaB~28;ro7BBjjNG zonR2VYEsU&MM2x&xP3YF@yf0sXC4pXY`F1CayXEBt{3XEB5P>&h{}FO7oX|+$wi?c z|7~}6^_I|gsNErhYB~F6%qK~3HeX<>F5yya@rL0Z?TI!I`pZMO!j?a}Kv*-JZ|7L% zi~rhjDUhkaj++Hy z+U05=`~EHTuN;@7W9{u*TDotdmhx$?XJhC){<`F?zQ4G-?W7x@C$!a5=kO;qcQSNC zU5s)cn|q8!Of+IVJwDMpu+M{l?!?X;YqP?ZC-alR4nsb2DC5T7?;Zj^bp2Uh!A}s8 zu53Rq&(zzZiWyjU`+3~lZ!sh|L2v^~9rij=ZsqvCk>3u1M#1?56oORyS9}UK?upW-Of=#%&6Ha21AfCpiylp{&M0m- zfFY2CGuK4LJNnW;d@2t)`qRntGz`a`cCh5O(H3_{-@meQB|u+%nte-50*e`Y1cG7Y z;A2OxI2b*E3{?fXVNL!N)ei^~u@`ztq^LWH(_1y5Hf3|0>x{~%v20(&qlpe<%G z>CAan0iU^-2!*)JN0&Nml-B|o1A)m-Pp9^A(?idZ3U)hZzS`6C22=~;3p1G{6TkMSH#fCQ>>{FX6_-w;!oDAUw52il zRwmgbA;;mEs%FB}!D~LnUTCZ#`SByR@uL6p@RNFanm@t~#`bCz!A}`` zxBHzA!z?szU*%9E8ikzdJ)DpAx9h%@R~s!tYk_+FFZ?78UZ5HyaAn5>#X7{Ek<0A= zr9mYy3Alji#OcLoLAQIhb|Ic7Vf^kzoZzE;sxh!vk5=lMvnb&ew6phZG%v__l1lroZpd6u`^f!k-e{$^j@y6BKqx(9A z#+e79qg(5nYtClJ(m9x(9=s$%Nb@p-b#5{%lZ#D$qYH8KjV_(>Jb3*#MkTg?)k2S-X@+w`85L({QsI6B zhV>`sOf4eIIsVK#r*%&_SRupb?w?ONJ)1$B7$^x zNQj~|(v5UWcZak}NtYW|>!T_6O@kcnlGgpYZ|u}nG~|**0q- z*%y7YZ?12Z;}W%UF7)|Ic_$th8}22IDU?aS9yl9A*G*eYDvPO&96kRi@5_`@fWwLY zgA2xuLk$UV=K%`{>|E$~|bkxm?zYnDe?B**MhSn>(_x3`e02^PTjF-@W_r;;SMeImU?WO+7!MY_T4p6A%*IUl1cn%?CjXX7w)nPkMtbn@ z;M|<>Wy(7-nwK<}{>0VMod@>{!ly>gY`6IpU`_|EN~KvuW_NrqeH*DvTlsQV-WZZ- zLd=n)C3FKfIt(unGmz(ws#VPA=eRy=>({k6Ez{6f!{X{5;YwoSUyHW3uut4e(P)6= z_L+LA0sA0*y~*6>c=a`dRw+&qxd-yIf{o(+ZUUwz4>D6^{KbctyFYtFC9VY!(8#rX zQjn7`FN5$`G84&O8oAPFUyhKM*#E*}(2NfOmB~%}+Cg=AK8?Cs^^4qshkVjPk@OvB zj*Zq}idv{avX$*NvP&MC7zdD$;gO{=JPU|nM3k!a=qr+7gXZQ#8IP1b#9xn%!SCgJwHJ!v+uq&jv{mdYFrOL2gh!iq_#8C( zr@ZqD>Ne--n0QZttDMA}Ce82o{V6u)CvI?+2GJ;%(O{o@l)9WIF6-UmsWkJ9c$~E? ze;MXW>$Tb3Mp4F$;L9)GLjCEBNC@vF(v3^aVc5(fgV8G%+md{~Au07U=jr&K}WBhi5MLvxno;;U9?GKB#7U^%GWI1Ox@;GbzGj zA>z=P=Cp977wL~448p2AruAfU)*G`J&FE>ad0Lq=ndVG&HqVnhpSA()!|cxzg&1@7k~)QFb8?x z<8hC>r>Bn<*TLy+~2>6 zGURRN&~vVY>Sc3A!x+|khd?0j>)Mhm+~6W`I|Qo`ov=Fv=fgX(IrSlSUC1)EJmDmn zd*EKRf-y(R*Am+BkIiLEKe^mu>~!Nb6AcyCuL$`Plh2;svbXi9IXTE3h`G-WH?IRW zd8aWBZ%=!TJp-x~@Ttbs4pXI_>2*{6=dPC;i7l`sveE^Feb zSwtI$`IOWH!c)Z?)ZQVq1kAA5Hj}aaOgcHQd{S3qFE?+j$+@Hh%<@EzGb2vn1@_JF zr^NBt*CyR(pk{G8qC&M;xU)lFGT-dVtMU`=Y4XLlIBn6D9_E$gl+epL;-F7%H*-7{ zAE2*OW+L17_3B-+5QVRf$Zqdz;GvFQ=@9shJH0%d{v_`1wlTtU+4>^Ch7R4DOpwb* zBrT)O3>1R=zKevZ@`2PAH=%Rx@q)kr@T55{8K3%kN$`n=rmFXpD}GDbgb0Vz3BrXh2S1X+lo!O2|XssGgtcD z_E`Vc`!ax%-YgusM*iN)uTNW%pS2)>1R|tx{bc)vd{_6Ekq*~tjlVOSs?F$D1$tv2ohf3H*q(I$8VUIuQne1SzpD+MR~{c#8Ez(^A^6Vz?{?CDDnJ-l~f#= zURH;YX#jYyBPx(<8dWQYPAJdgvP@D~!$n$Rds56}K-qX+QKZ-68=zWd6kgrkJo-XN zcckt4sPqKy_&6i<(^HK8s`ZI(v&k4WUT|)q;(MOtSHl7qkxK z%LiPG8y9moRV^!;WGF}6Z4Uc*>m#@O!6SkbbQWK1q!+Jh+U4LM8`FPYytBg)mRUE{6IFseg!da9)dfSzb}GJf@=K2TL(lj8U~v25sGV z#9i-lN?WMoAQ;P}5qNrvk|gYf#_yy|<#O--o=MHO<7?=r3JW@+o2jl63N><9mO;Xw z<2R4Hf3yf3h=dW`Vn2)@x;8I2kUfoh1TSZl{)c+_55!m17At@f(78ZX35$SFRVFe^ ze(c1GctR=B5!_MsS%Ay;Q%es(eIdHndEzevT87{Hr}nclxxe*K&M*Al*=QFtyLwFM z2l7>PxYH#aw%KV@?-64))?hm*HYC!SznV~4UE z4~Tvr(YrckP_3&wnqHa!^$nlXQ;u1$2Y3s2-6v3ppzgftLl4|>{&pf7@>@_eZ+cr&okNWZ6Y11X(Sb-6nkeCRAc7F77M6dpQ zdm$=ACpb(Z6dZ0iNX~_v{N9dGtrJL1wL1nHh%tKiw^#Ap%$R6F26*r=Fy+s)it+za zKtaV(1GZnmu}*N)?GuDI&Ik<&WTHX)%tZ8=Nh*mX_I($@`z~6NCv7%iaQMBb2unmL zB*er(q`sIIqWbWK8W9}o&!0aJ`2w@wKoDeE;hUQqRsjK$$vp`Fvl!CwqSwa4F5z_=_4Hu@xYZdZJQbwxGL9rT99#>QsQd?xs3BK2$4 zN{g=(tQ=Z2SSU&3L;jMIl6qxR7{tW<>3Y8u6%_%w&A%i9proPpczJEDf-oGN4#>Bd zm_U?l`HI@rU0#WTg3y>^B6qp+PdN|#W>#tEbHL2>QL{#2Ffl@cn+5J^s2+^i9E~1V z0ks(N%32IR-R<~y__lc}AOa%Q%g2|_?Cq9<;;>P&NWr5Pz}~9-ckC_r9Yed^UrN|@ zOj}prV5ZpqWWs3QhB;x&igTy|LHQ4=DuB+|MlRM+TtedGmyfi*5)u+M>gYko6h8lf zNL6f6$+ZFS&iX(q`7r9k`{1*9fd91gba!KgW(P3zKy>NFMcu(Ch>-dI-yK}eB0T}^ zeR4uV2!M4WKX|oYL>doeNNAq{v^--Gcv6>cuTJ!BMONSr#g}i>VPU?~{3!(Ebh^(? z-aLN-MEue&yB`O}e<=yHVVAWfan!%g0LeVh&I&+@ccEI}T!eb)L;Urr5)O~H4w5MD z_j>$?|CUP4{6BZn_tW3+6)|Ag-p9wsfBcTP5u-mb&OyR3AK}qo`Uh!qAJd-l0m8@l}0n?pM4?x)S+|6s}7JP;d2%yo{!C; z)$To4YS?3QeQKIILSx<$f{P6@vuSgGbOi1vPnOmpieNrB<4$wiz}vOL+MrHIEG;dC zY&=Sw723U1zBC<+05a?Mpb+N>y^_MMPdMMRhC(6}#q_QpM*V5Uzlj9991a4x~criBk7h0zIkABImY#*s!6?YvwkKFx@7n;NpGCxj3 zrSZQ`K)R_skZ^k8ll@MY%t|X6xS{Kodhx8LJuob%%ry&O6o+H^zw0gtt>cXB(vYd7 z*Jl&|Et`}zzlBB2?x(ZAcx2hv|3WPG2_xLk`BfRX!h$(}i!4fZ^vS9Q0=JUabPMm0 zXb`dCxW1l%g3li(MVzBgCcUl-AC*4_NAIFXu=r==p4s)`(b#0SH^or-KaMs2t$A8r z9%2y*0un=`FF86c`u|ejhZs0x zpdV2o$trpz$-4bEfB+8dXLonPApMgkFksobtpAq-fanpNIF3;E%4N#u6Rhkf zx+3B#6ZWJNBYfVk0Hz0IP8JRhY8j;0;1-~-uMb+~J(VF+p`CfNM&<`n(T(q<5pWtD@5w(!B;pch#+Q-UMu;YN9dYT_grrR# z#Ny{dQp7;{Q|;JKfjfuW^!T=ihj8tk9eVlZP5+9PtpR)-0QBgQ1_QaW((8c37lCNH z?6><@zTP91M?zl7XIgq{({l17BQ!ooUEdyGx=og5=#XKR0fz%F3o~gcM}g&AU#eed zi`{VI7xm$rBg|qGH-$VsNo7E+OcL@?XMl(L`QcU7l{Sy}c zOiXBhC$?hZ<3s!)LpW|6XAIqBQf<2H3v%q2#Jf7vzFHIK%gGMh%bH3^`ei39)_Z%e z>Ne0ePv0C#z2Ufzuf=N8j`CUQvBTu{5{mtv(rT#&8b5@9MZq;O*Q{Qv@O%T_!)2pJ z`xx*=s+za%Gj`C8eKpoWvIlsuf7pOiVW7KC!5 z4{2Ynd9oP|P`U4a&~>*Qmp$|qx@Sjs&Jsx?W!-Z3UkKD1wLz@wlb#6!+K1OAJj*;V z$n2P!6d50Dh`P4Q5nzn*zmb2LR_`-cp=)9mn%zK^tz!6_+Gl1xds*+jL^1e)oE1B1yQ*jGgy+~pH+Dt0&E1EVl(slIQaBM5DRK9A_MNb zQGN3l+~>I?AUa#V9)FS={xsyd!1~OLmUlrRA!J%$4-+{)KUkRZE|*SNly1JjTS_nY zOK@TEq4EXUwjt9>V?si z<0*4*M^BU4%M0Wn+ZspamtG|Z2cZW(3=XZIP9Ir$E`(MOoeB&W6|_CA5AVG~yzCFr zyXDA45N+flpJP#@g%_G*C(Z0AUbY`9|<%T22n5`o1pd?3@5@DKr z_cqePqPCV;L>wnWU>1CV;E`ezDpvw14S?N|(q^f(eEP7LZ;DAvq}E6l0ZLTM!QWBE zgPExkh?YxmWx5DK^?$O;gLztExR^vL%1Y6Z_#DqVNb=HT!4c=cQtTXFdeBCi%a!=N zZhfYz3A$m*JUUHlzCbm3c)d~AY&zV}l1|kl?|9$)phL)F0>0>cPg2a9Yy7Zr$gj)u zNk-aTTTS>6_nS6nG0#T`^Vry=^9LkJPsdHuqu%7rwV$CwaBzhAGSz zXW?)g-@(K(-twp2JnHvYqvv_plpLzt(&I_FL^+(bE-{&ZBw)sbr-Gm1G1*v!YLkq< zkzE-G5IF1FZs^xk85lT%{=WN013L!qw71~jKOs&W#hceaR)|t4=DbAU$H99UH^+o$ zn%{1>Py>@(s6uuR2SwH^w&64%nc%Q|OZa2TGibo{;W*2PcSdDJ-gZj1aI}8mj_-I2 zWdIKGk+ty0Te#=9G1#BJPub+N5b&hbzvaQ6X{SgI^5`>pqlWr4Ma7?Us)46)kK-FK zA*=W~x>OauluF!y8);nU%F1uVby=yOnE8AL0I^ixmYrJLz#mO|`+$C!Q z?_HXs3SCIK=_FZBRbo^)4vxiHYT)kI);)`otxSpZTBdKWUfUJY9=~-O*M7oZHDYk( z$(+$JvEf#ibaH)fMa$MO%IE7Bgz#yx+P8WL**SN)?DDc}e8mT$wB$bB{3zhSoq)SQ z1F2?(v;JJC;z!;k_I=f|_2r1{fXIhl$=s|q1h&)5LBX2Is45(%&A_OmnLD1FyoPE) z7o_cp9II0*)UVqa?MnJ30hN*-PWQ=x*Jzwq1ka6W>7VdX4ZnaN`G}{w1~% zYPg1&6Sd*zJV(Df*#@Rc`e3O%Z_(~^#$#Jg#96HX(ape?uD2;S&0RHxm5(I)4}R4& zw7N`9e1PPcbJ)BZ*=J0^n+MCQ!O;1@WXktOay$gmT2Jv@Y7UKv*-|aqKnS}twVaKW z)^n>Abf}W*EBFidhvQY!%h_R1_Xm*NdbRrIXFgAaPTokgVUvIFL6S{hB)f5Rsqn>< zyG{#%i!`^-wDEhX;YNImke$lP4t0VhNZhip$OoBnD@;$b|mYRK)2!@B=7r z?n}RzM&Xv|p`Y{K)qY6klze{S2@^8joIKu8g-Qp9e$~_>L)Q#HT0LB)RbZFkXz&K` zmFZxq6)L|=KlZc;2hS4eYTn2;!n>4P&70_~L4UiN4ThoLl79YUV7c@QxPxOUC%v8R zmC3Ez$Fg?cDDd8y43C96E$e>2vc?jnAHiviopCq#t~Bi9EyzfimqIV;MKMd)nGX)~J8ZSm!GWe4_-pJF z8I=$i?)s8!_CT~nxzFX7WP&4ju5rEi(%n!sb4ObJ-r&oL+jJ?hGz49xlje=%i_1$+ z4mSGQ3==d+!pf}0@U>XdIzIBWNAU7K(J`y&RYxY2cMPp6Qu%ES;sZ^ip1^?PakZJcsa`-xB4a|lD(ugl)rN)#u8!~t`KteGq~d|~JN z?~{(ZhPQxEbH5YEZk)cx5<06R*K?kC*G#M+x|q8Ya?fW#<5uG<&aKAYsZ44!PE`+f zIOqx3gZ-;W2+L?WOJ)EYOl1qb`UTW6ExDudw}^V+)FjnVV`E1 z7yGKsG5WX*=C-1qOwt<0(ae)P8Y<@x?`qHyY6;4OF*ug6$HaZC`dm`*oH z*a?c+y}k~g+PszF;>tjfeW-qul;7QaN3U`e$F=A$qBwXYPeD5^~`jFBSwe*LjY#) zg{NKi4lhiA6w+e32>@aEBMpF}Oy|_XKQ>2?=fXD@Zo4kG^UXL-=?X16ZLM*yV=`1a zWy=j`NJ!;GaMY2cW!S;o_F;~^wafYeL&(#M_4C9+_z9@n9!)JQqx*&0EGHNbCLa!L z#x{C?5z}ekFM#)rHN? z8Y^D>czw)gOy7iE2vsL}fhonl7N!1y8}2KUz>9m0TK=oczTs?B zW?8Y2Y;u;h3S2n4R=4&8&AlB*>^d5X1ndMyYsA@*g!Mpr{B|tnLM3f!*CKpQ2_A6Y zvY$_;&O++a|3#(e8DlraeTBkiq}%amQS`u@r-dN5fW+eF*H-w9VGWmU5GlriWSJ3nU(GE)1DLPIV?DSv)DKqdlBCJ z)@~-|DV?g~DS?$nLgZ81H>|Q!60YUYvISQZLbi97stxP#S>c<9$3?YAt;~fjp$N!> z^C$AR7Z3G*RS}iTV-uc19b1Bzvm5)Z*r|1JiDYVsBjL8r6-!W_m#GiW3$5JAG7;Uf z_we40W;pJck)Y4mk9e5i!3Paj4x@G|eMgq9nTJ=whn-egR2G(=Y>=4JnS;}i?@6P; zl%EXUchO)-h=SZl?5l6!Ztn?cb6SJk4y$^+P4~<=EqP$kjr3RC`R^S^Rnp{G-^~c; zkzNUPb6Iy9ZS0skER%@iydXe9>1f=WoY7h&WdZRgd)XY)+h0GEWn1>8@3o=boM%GA z74ukof-sU6PLrQJ2aK+d;Y>v2)QqxVdtK|6%w`qJX@X-18w79GC# z;il_GCw^T{Ociq&1- zi%~f&g6a)fOTmeQ>dZs{vD?6k{>}`~^@z^WD7t5uQ|cA`{PY#>t)2#*=eu)QA*Dm1 z*$+E6N0Ua#jU_8|vmO`f;CmvAOA#(16{GeIVK3D8H%j9rRQbQ~MpTQq91;`eo^5*E z5JOEY%2^J+Mfyym#WNylu4_ALzqj~$gaU+>ys{O#1anW@vZpI*ug$TdNwf)l8cb{k z@l;PW1|$UrF3(=x5l!#!=|TpN4_TuUBrCHDyf4!r<&X;qEDZ*O8s z>kMoc@rznNO!BtOv{$7Dn^@_yu!!GO<}v;#HCI73?!@N%XNU$H zOl|MU+Yk(1+OAA-k=zZTA9gc)ek_6Jcl0Pkf$_Q)+>gmTH2J_qCS6OG`c}(lcZBq^ zXut!y4d2bC+!6|(c>z8sI$%hi5XLVK1DDgAA2~zr_)-ugioQUsHm|dy&3#NG?JO|g zb4EX7he2+5C)!*D7Lr|Nv+A|*Q!h|RmcOuTRi`zVaUM1rl~WQE&x#Rbj#Blq)6vmR z=DwEirw{l>0oTx_Bj1m`O+mNZ7MKxYJDea$mV|*hWRbSxfzSFK?PEtSwsW%z(m|QD z)O7K6?N--8v%(TD)nSp>?Q^zNd-&tp=q)hA=zGo?u-EMx7OLVEgTT+KFwjtinEaOl z&dqO0Y3w>_5XA{Ye_yzwZm#lY5W;$=t3S}L%2$+f|349ZpcL-G#r~C&^M&{mB zl|KG)>OI)Bhkcu)0EMw1`H{3lk;ux-)hmObb7iHFekO%nm7Q%X$|8~yk{dDO&hFYSgg2*}SI${scl?&OR1I8fo4 z(UZEZKZ_FlVC+#=u6@@(N@7cP07shf>*J=b?tfbyTWeBO^%DIJWK}E>pk!^~s&y$= zAC0j^8X^70g|?@#UoMtJpXeWfYNgFK3L08Q9e;JBHNdROVxFw2hcVTWX6EF1yKF^$ z%UigKrsnsi$H$mE;mVM0BEigQ8Bv=6F<%Ku!D#TE0AdpqB>f|l6|E*9jrw(PXsDQi z0v3~IHA{M${@+!)L+9EM_iw+3!}LI!AcmCSP22RAEb6#EIDns}VF1qw?GOq85vnu> zd^<#-*7^l|A8=kC{_Gqa{=iR70SE|ixmXBLC>sFp1sERoKlG3>d4D7?Kj=S%1ucn@ zX*L#;-pakFaFEE;r6ciAAr7fVqO@mWrmbc8BmQ(G(#Bc_J-^T2U)skHLF{n)4`Hfr z^<+R|*4f#|4)N7EU}rZ|Qi*HZ<^1Iv{hNF@xQZZ)bXS*k8I>DYj*B`mvZNntEPkdUgjd z5O3LF&|-E)8V;EZ*($0N=Q8G6#Ppe3(l7>3L@o!CKDB3({ z$`6<+%Tl3IA!407{kD{poPq-At-z;x(j(U|1NSi-_g__PRCT#B$cJtk3}Rq|rV&Hh z-=zr)yL?^}ht~lTjDnZpo?KZDqnt<<$YA-kdm3&d{)srp*}t;kOqC)@9Y9y84Y7mg<}FLg z#9;wz2{`)f-N@l4!ks07AG5!_=O8jHVTsCT(9v`IBTPQnsG+9b91cal!k&U_heBMuL~Q&0;zE&m@ddxBYmjM(qLjrJpQ}b|6lnHeSozB&GnUx48UgM2kCiv3Bk9^`j7PN z`=FqR?O%((Q2Mjb4i*LCBSa{`tP5nDNt%##oQBZ;(dGo*GGX92$djAJ_1zVyI2)~750X?UTcvd+FG}-WX z+EGnmoEN9HR~fe@*WLLuvZAagi$Yk{L^sw{Ig({t?GCaRO`I}#dh)rG9W43cq;U{i z?+6mcV|{=I3sRr)LdCcQ1i~gKRUtjMz$^RX?>1vlQj>*noI%riy=M!B14-s0E6^b9 zEff;=7TZ=(OvpyTMV56~!TG@8Xl>CYHYKPUD`-Fx3l8pd%DQ@-5Xq5QQ$r}3kYKZF?IosY$DWW7QwlH@4sNcD zEA)Y-@VkMGoP9M8avtyXI34Brk=Zcr(Fbyu6;zIfqrmG%2>gSm0^*JJ7=Tr@qKB{( zW>60m<0t!*iNTPzgeec!f*xpf^g3TZoOwqp9v^T}?aOLg>APgRvo@j(G{V1KyU`%< z{6%m`2+|GDczHIWtYO*Dk4)wn2bp=He`+D5ydPkpC?a`T@JIs)pf)Sg4+fYsPQEo| ze7_^r+^_Q=0u9kJ?4umygKc>*=zqOR;3h{_&KH?xG%vAfa}{UQLL&4wu*cy$(?8Bm zv^v&Y!eNEv`VI!?T5`55=q5n2|3wVOxJF^`XcDA3}3J7Cl zwVoGv^_g0RD#I2$66jS5-`4ijZ?)^DAzTE6g!bL64?{ZNb-jgj@k`H^t9I$#s32kQ z&O_EydN3U29k<~}F6IeAl^ln}OhQPAN#yHjGbhD6P*9k%Ju1BI0(&mZW@ zymVY+w|O-~OyItUD&FAq=uMf5-qpBQbA6(fKL;1Q+UKaaxMyHV1@Y!2KYNX;!~Izi z3xz{XPA%3?InrR^s!rEn&;}3b+dj7RsAi#Y3jz#y5?F~(a2@RE$x~}S>kHts6`O_v zBNab%BWxI^lXoac_lHB@iO_ggML3w)g`vz#WD^Dn4>$SE==hNIxpR{UU`JO zCO1J9-FWCsM1Nu$<&!9zDF2Q)@N&-q;0^NHkme2V)HSy-{wo8bs)ZT}J^r6CkkPPu zyu*fmwOn~d*hVVIoyG8~*z8>EW2u2J!IhQSUoFd$34xL6h9EpDd+vt;PH;raH!I0o7-!pPgSnhduc7=^D13e28l-DO1U!sCXaeGRRvjt{P zR^tv^boN`OHy+Sos^&u4QW?d%s+?Ltb2w8f>9v_1j;`_#ni?lP^)EB?7v!<7ZB?3J zo<8+~abG`XTiuzF=k9k08RGImWAI{u>s>rOPz@D5H=5@2!R|XHwlF?Wg9>E`;XhmW z?mL4j5DNEjLt$fHT}u)okE#s2mfSkD=RG}&{H1!>ZoM=GQ_rSzES7qDa`EibrN7&i z_FCk-TranQ9o{DE6|cscpJCyFVhL`l^v69M6N+HyBcqz+D`cy163K1WqI0!;HkXJw zX;{9?tGzwmHcKDsy}X^9NMNWb&Ye+EPzZP_M)};Yh8Osx)b?(CN^9y-u9P<_zI~A9 zZL10q*Yg9Y<>{jc~JBO}Qz4FxP40 zXTFE~o-p4W(_i-Ub`gHl>(a8m%!_>9ZQZRo`jlT0bV_??QVu+1eJa*8Z@wMa2>~z> zVw7IBRw{ZSU7XLIaTk94ipP zD55n+MJ_6SqbK^nUIf~x-JYuDelT=VN*|(;;dnA(GLn?HZJRcPXCp_QQ4f+gS ziVUn1tnibT-%~X2Wzg$-x=a#<@MwXxdE^}e=DXUVqESi3#yHAQ5=gigI=1*$} zG;Eo;;J+qse6qbIP#3;&slWT$WxMA>?>dmuver}|e8EZHF_~Ot&@udUlh%c#OZdu^ zR_}*2xc4h%rh5JP}9HoB{wLa;YfO1k-tTDYsNkDpN4T<5E zh(S!GNSYk}+|Il0nhQnqwQ7Uprx|MB|4WB5_bj*wZkt!gQ5x$)#(0k$(koZ93FCMd znDA=W@TgqpUBWml74LY85lOqa5lR412FqecC~v@Tor)GOoCtM)0Zwugc!J!n2&@vl&P&mn zB2GGb6!(1-;I{UfA_2~D%an~=u(}`%w+f~L4GUIStb0{poR$$~M?t?cbg@`fnGwr+ z@<6maRM))-)^#X1snJuBZwtXm%AAIES+GGUSNn~0qu!!wGI@Dw?(Z^Rn0(5TY+Q;z z_7oO2>TJ~{vCH?>$L!cI}}5MGeJlHSoBWaFsOq}DhGkr+^=SRFGKxK(>l`c`A;broktu#&{?SGvy)i=V+Zj>r zTSz25Dio}gM2MyS*tj}voAgDZu?85aNxoU!k@_ZY5$bRPqBjYsnKgq?!9>%E4{@2$ z3Oxy0z)<0~B~_l(_2zPuezS!wIrFWJk^l*YL_>Y&5emby>+-H zw9^ykcjw5aq(X9IJ*c}d9 zNxIgCuwJz}rvC9Q!YY(V?fx?}vjgSoV}uVy0caabgZ3Kh)%NpuUDfUu=q{{k<8E+W zzDD4|aQ9YwCLT1`Ls7;Wde1_z=~ps1x15QQ?w}-9=AC_2r_#+eI%+eav#rS1Ct>xb zkFwlN;KeW(_eDWNzsHh>R~jZ4xD=DQC2*W>L`!42bAB{X3OYp$Dq8(yeH(`s(?vGc zl7bNxZl3sOUDMEFfzwE`x7yLMs?do;RTHLGSpM0!pu1H1SI6pij|Z05J-AoCAh!n%@SFZ&Rokllz^D0m~Co%Zr78 zA>k&doq$jREsN%>-I!NAwnRs+g8HaA&6@;F_9+4T33Tr2!^3b7TEuzyVF@c}Ke{4v zk0KapTkhO5H(W&9>RHK6W>;b=mo2_+?o=aB<|cvEC9t=|`(RFi8Y5VHPxocj@LMFOB>m`-}j_b3mIfpUelpECF6q&?h3m2hv+f)I1`=2&ecXmGsNE z!|qvL*Q`lbt1GI<=sMyuD>}A4MP31859iDTwUeQC24b5JhcxwHJy0XagagHh$(!#r ztY6*{VWZ7OBj?T$|&B+dY}rbEq1&JATY&-)yEh@=j}u@##v0 z2oV-*bFAUxr0z)tKTES*2BaA8v?9K5@wyl_pi5f8kf47232yg@SliicgFSsfonM>9KG4Ti-WAz@moiCK>`A7qdK!tMkU1BZ;@>XqBcWdRF74!*}w0@qWu>;4>0$*Yy` z1eYx`VTKm(6x_)#F-VG-JG~=?GjXv!~<`v(Vv0x;blBbp(V>?g~nKSUY9Z`5*T z;?;GJGqwD*Ypm*`JKRXji?;Gc337L^T+Lew{Xo7}A7`UA5cEM9s`?rm<;t^Fb6@yy zvzA;zM?19(f&9V)^lELCeD!_t?R#OlNnI8e9I)Cm?vwm_$o(*ZZ#-HtU zA^6yEl?K#$@`O2&$Lk&`uhhr6gNe)s7NYIYEJ@Pc6?7iHu}rE;q`%sO`OD$3^O*|NbhH?usTMh{- z)JT`EqJ|ezjlB}3wjE3WJrDc9r%9faog@?VV@Q6s-jbfJ@kYA-yhmp_fPcSp%j@=8 zzIrjn!GKQayHLEP6u12jEvJR>M5|iF3yVo_w}V<_r;SyLlQX>b##5EkhXwLM)e~$K zi)!r1yVWk1URhr;%?W?gojBqB7jc@M$mQl0qq-VefS5E)Fp#N{LyKoZ-{94D5z*^E z6FjB?myCyhIyv~xGDp9plk3z=LqXB~sdSnQT~qnO)N|S70|fm%p@oy0hkH7B&qeLV zrsGEIqK+sPwMCIdumdI8lfeny5IT9e+U7L@2oWNm+rGjbmq;NvX}o-HSH}X5hS8xO z810>aACP9o;R%fkQ|Ocsgj-ChDHHZx0Wa;zD@>T}_Gfr!{L#=Pqb>qBWEKE7=TlA2 zF*4*e8FN%3KWtc4yhDpN88(iIV`B*_>MxwzF3A)xW6sU{-qj z9tY>*qKw!)3JKC+ky;Qg{6zh<{9V1Uq?!zUuCK@Oy2OvnZTiJ7D{DBex+XWLCbE90 zsvCBqPSo|W6_F<#nTSr!X0)fb76LTcvPw8Ce1Y$(79!ksF7$pC9;7|tMPwE_5hQV5 zU2$GI5DJdF-}iGqYmpqhTnsu~_6XonwLwpryJYdKT1j+1vq#7fIwIh@Z$v}Cy)(u* z0A+2%P3qU0ikrP_qIbvXkQ1_WB-cSGg7W$fO^I__S4m@0)bb1=lO;alm+yzj=9*&+ zO5n$C~e^dQ1YON*a4Zn2{OO8+STTz$j+_x4{Bt-(e%v!MupY?XX@AMW-}v_&^X zfAFuT0ek)W6{o!)CqrG~HM2J@A2)7hz?r;3ozyayN=1G!COP+`bldPl}z9pHYFHS1PFkO=|;ki_zX=U0*3j(GJ< zf)^gT;ROIh`tK`8dGQ}7nLC6R3XSLdWCe*WAkYQW0Ri&y@rx)HIe8=~ltFT$k~o-@ z*Qe+{TqL@c=TG5?fICaQ#QqWWA@*(}9(xVbap)f({R-@1V>}*al=k zN?i0}YGwGRyt5&OR$X1^(4-YQ7Lc+b+1+y*|I6W%*Pq?O{$JhIX#5<)vx#<;R^!KY zDY7YW^{J#!DpbE3KZE4xV1MlTQd5sbh`>>BJUTjmPPj$<67jf{>IGNh>AS=TA4YWe7L;PlvKaVvL@;PSqYZl zcw@5wKn~5;Kg#AqC?Jam05rd25r4B5*knHeIzg++Djna7^-me&(GKB9)n_Kze;v97 z;a?GEAk^o7QG5Qk>>x_Q@Rw=~DAe@yZy5e8xP!HbnyzR|b3_E%p9NP)(Y2N2AIU`j z=V3(ur^o$2%sl#^{hIb(I2hpG0S4dW_G84K^m75z)9P!ut!$ys&E(~&W1ojSA6*+8 z&lq3$6OjPb^s>n?SQyCv0|N`)vj6X&D#(j8Ft%k42@NedxiqstrE!i^2|=B*G?{-U zBUfpSeV(DJwXSW^S~#pL7WOAs06wV=n2fc2DjO`9vk-rR-V}<1jyBv0qn{yusMrSR zm5%*mD=k!x-5@81;>YHtATD%4&=52-0J;CLnEHQq-T~b}I6=ZwwY3{-NR?aA;&0F) zo5He2wJ;_~Lj|Tw$2Jh7YY2qFW>MNDK|T3HIs+rpf^82dkYoNT5f@Z$e%Yzb89{O^ z+V{3YVzkY+ml1ILVs;uxNMs+XV0wXp&mz(VG8%rrjGEN&P+)=Sre%Krk%a@=c}X@g zYQwT-O33(ow=BHSbIS#YKd%s4oPj4I=am`FUjq#3nH~t#CK#%6j9c)8y0BD%zounk zdUc2@8+LSP=W`B;)LZ_Y>4oDOn&zKgvfT$snb3)^zz+jN^Yv z_SaE?QGX5xE-6P&JFrZ29P+E$0`Kmg(;`L{5ass`!AGv}`&q>NJ^MI9U%kwf$3uqs z)!i-n8_$Uid2Uvc?)I#br4*F>|9EjAYrw-x6Y{K5!2HFMh>JICTK{Vni(A=M8~)XL z3KP?m_3wA7GSI WbVT$goJF9(>$QZ8c%i7S@Baf`BM{>N literal 0 HcmV?d00001 diff --git a/docs/docs/assets/images/concepts/ui_table_filter_group.png b/docs/docs/assets/images/concepts/ui_table_filter_group.png new file mode 100644 index 0000000000000000000000000000000000000000..0060f2bef7e523046f6ad47d01e462ac01cccd4c GIT binary patch literal 29037 zcmdqJcT`i~w+9$NL_o11pj4HnRB6(Sg)W^CDFLMy2_^Jy1C^#gLa&06(4-5Y2q;Ji z9YT+ELMYN}U~c^W-h1=jyjklvYt5QJX06;sZn$^fbM`rB@6Z11eeOGbUG)oetaKm{ z=z^xkBSR2~G9Ea7oI4BrVw{dC1O8CJ4b>ljio4kfz{weh`#SeQpwd|S<7d>sIjy^f zDI5f1XdxdIZEjy|K_CxG%}4i*{VZ1}1A~m`Uz~2NYkm{Ng}tZKqAa>BcAIW|n5|Mk z*a>>m?1#QfUTJO7st?q#^1Wk`P8Cbh$plotA~hjes(KKDHEE@~ioEhSfOdU zJ1(3vF@H9~)^Rm6QyfAA+V-pfx^X3>(HKK8sxK{8HCI;p@)>!LL-tDVM{WwKdt7~Z zWhF-#C1{BXP(!a1MdNmBEpuf>m1dl-tW#EN#$EkS;d}8sQkCp|{1}Gi^v2`vklcCLvW(qp@Mj7>taF=hZ!X*0MK6_f zM4&X{kP3z+iKqQMnuq=y4qj6U&st4Dz2$$O&Gme=1UY=~!ct~-PrAItVuqBljo!7a z7gQ3G?oY#Y<(`FgCo2q22-ztgS2G9CBPS0#gfIL(Hia=OZCLqNu^fk+Sb1a8SO|RJ zn$WBRrAZu-cY2wtu0+(*iZQ5;EofhIi%p5NXyo%N*k31-M>|?ry<)8-5DNvVnB4$W zl>js#`0Gywx5dQ^LrVrEEVvfQbQmkdeZ3IyLzPzPXYuX?cl{!t1?+ zP2dVGRTrAGcl7NdLjvs+-6(CJS3e#!-Bq1d87(~vV#l#`52Oih?QC}_FX0mvFB?>& zyh~sh5=`pez5H#|o?|lsr84lA?ycHqLh^EY_@j0g&5@}cCxY=P2ab61(cm>pgATBZ zt#WiHpmjpj_!Mpao*|Nlu4}SSo(|u{uzAN<44#c|&XI09D zt1CS9Z{i%My%8*YY@fYgkzAsDLa5QtdJY@?G!APt$6|#AYC=mr`O;u88?5uP2+R+nlEeo3le0`2WDsu2f)vC&_#oTJsKO1S$$q{=eM`3A(IJ{JkJ-XHE z*l?Vv7QDEY@^&X}Yomqcgtas_wC+GOz-^$RSFj>9sfYFkl-%gzebnOiQvZDI z>Mo|zL9Za>a2UCa#P1jy5vGY>2%S zX56&cxSh)8O^}vej>I1qH0)y=m*b%k+$Qh4Ty=4E(EUo$m_9+ffd|tfE{{U%4MQ?A z{B6-!(-LN%?=8DIEDbT8W@X|t1ltW)7lO^qZK`t2YPaE^b^?A<2h`6z&@{B!y4)Vu zuwTQt-D<=_j7Ev{xza1!Jg2#l9$fy%Y(DhB6RdbtSG7KpAD1~%G@!@kR=hwe%)CU~HuF8SRPh6aWql4?Z%XpZuk;8`12ziZ?OU)&Xe42-Cow~!y zmOf=QSHdJK;gDA+W%lVY^4%F(`w?gdOkvww^19NM_x>uRJ=W*`1mlA-AFNGeY@E=J zX&z_WL71~{j~zbbfHe;EKKJ>hPHUe%@BU_VvhGuM(QGdJY|V^^+ulsP!}3plej@qE z<5*s&JnDV>`0+w%awlE2Uq(=K*3)FK&3CUPPYY&m4cGi3mJon; zva;&Y-l$)7cIiE!fU5>l$B=@Mh zHQ3p4<=Sn`j5SlV{0G^S?biEJtEHLiGfuCzS3dDC0hZ3-Q@DfIlj_+rR|lKGFU~91 z9IQW%POe-vKRhhF957wVezdXwLqBn^qTK^#V0*UDQSOY=VrE}8VWf=k)obC$?Dn!7 ziiS(#0dxwV?B)x96T{mf0&7_Fs<-sW4)JfhijzYk6;`~msWc$tzAJ-`$4f8{89#mA zy~!dYUCsi3h*h2}WP$h-VrkSa%C)vFl>%scz*Cnk=W@#-;m_s9lTF=%sS~2*>WKG~ z2!V3 z_&P^FzKR`b3t0WfkfaKncU4C4MsIIJ$le5}tJ}HQ>(J9F3gN(7u?lvhrTy8raZj-( zhV2cdHGmU-9XmV6cy_t#-L9;k+g1o^J@RAxOPFO{U*+J2g;xJq3iITa3&#BTxLo~A zo59!%Pltz9ih$QG+yh(Ny>-TPzU ztahBzl!pdj6Nk1+qzI=|j{UVMCc$+B3@*^_bLK|MY%8~_a@p2l!w{HLZ!8ysuDIB+ zw=ZdGL;sU~@FL^n25~a`DL6@aqP}XwsCMD~boM-PedKc|%P_I*&CX$;sIr)Z>D4Bt zoY$)A6~#pTXald^>uqm#W#LWZDM$6byqfrwKrP2~E2RxzsNpx0#H+ElL%x09tSU2|u{Y~sCVo8KH$gL<7dnsf2% zkQ^13q-j))O*!t*@6mmcc5e{9xQ%(o!?d%gLV|#MH{%P-joe06lMjh}r%#0EKNoPJF<7&bvKr#P}t+m$nbjDrU8>>9E?i8SY8sO#< zU;QeL|BD5pksEn4uqR&nMG`xb!LsB zs9|xCpnA9V?Vf7e`NUK~3YA!3erULqD$(*|A%*NNFPvFi^>17{r*!X2mM6L}&6=0% z4mXvBMT7PHlY`}aKgbg%{Va5^(Ah9u&D}#l2OsXm)w}cdpk`$A`g1Oz1>50>#r#~@ zE9QJ--(BMwsxYM+W8P#dyuMkaZ%2AA{O(*_i~?5lmx=eAbiUx9vTBf0y`Qqk&CZsh z)FCv4U@SP1Ll88HDIh8|S{V8_6z1olA(hNeiq{r5kFQOxbZ>pb%wU=I1JnOhNv(DK zvJve`L>Lur&ZPa>N{0Skv+)>~!cm0r0DaFD-sAu6m>JH99{qB-(w<_Cq?y-gM>xA& z@%3Ird=b(AJlZjwbAf_-Su26%`A(NGytcbjQZJ6K;OfX%jnR~%GL>&fHFXbmJ#S>G zj6NSqoVwn3!LmNi+6H+$Y(s1R-VrPe*ezQ80~hZieC zk7Jo?)EM1i1Akg7DtH67OW`nke=G2#i5zhe;n=?N#{&s577XkoP202!_I0R^X6sOV z7f!yo3Cx0ETtfS_KJ%NB&n6w|IgaVS-;K_S&>CilV44-1>pPKt8>Xj?4WO6<{#B2cyldr08U1 z+4TvV-Pj%aGF+dQ<-{kvm4+)Gl^&SLR3m zgt)BlV0&tuAQBH+E3RDKEAzX%K9$wgE`NSEEeI@8&L1F| z_3o|zq|J>uEmSB(<6=XSIvc-c!UV28W!^KTVPMy93?U_a{FogT72_I_ApX8)GodhPreC1Sw*2T5Pd^sWT0ftL z9NN-No)1&UcoVP&+I_Y4ebjUX4_ateXzpJj5UP7P#UlG3=yBjat_P{FHj;`=*`0bg zIcj!H4o>$%u_>H@g93q^=6?>kIy>t2TuiuteZlFJ-u3Ozg9AvhaiD*cc}!*1@-L{b zW^{DfX3QG@1G1md5Old$m8vR6+Q`0nIO|G!rA^u?hzMVby?CL&nkSf8bziAa zNc58)Aw6AzwngxQH}1}?i&gyTUL)klCRWv?3J{y_tEHo}yceJOOK!E|*C8ihc!Ac~ z4Ghn%A8nZwvL_BGQLZ2qnK;c6NZ#!-`3EgN+}G@v1W@uvRVQ&VU+hzJpCunQJ$$%r zCA}N@M4rRW(l=e)9vc@rB;eG>fKlDN?dyv9r&aB&oDDa9tX+MGb9c45=W&9usqr=z zlM~9-4%VWl2O+^byqJQ3xlt-ZPKo5P4eu9F%$ya*gjM`e+*}Dd?uwV<9?w6c6W@xu zrgzd?jE$=(nv^mTf1%7?(WVWHmlS#^@i|rS2XYh8)WcVkmBC9N4ik|ATVpQsp#(_+aEZ#1somSR@L3!DD8KfBfz!A#a2?Sa z16I5LLh;Vx5M=12z$#BQ3t;d-VHKW)s1R0(vVz(;s14t%>ht~IPO`@-p;FyxBo2Ji zN2Ex4AJwdoFCc5&Epd0%s4;Nu-8JrHf6`9Jet+WJ=~m{zEqyap9Msn<7Nk;=xKwpH zq|plabY=#06w-<9O$*UbQUJ@YpuQgZisoX>6B-r#&dl;X#c#Jr4fIDeTQu7mNeZ3= zI=h9dn02K0Lb843)pK7+ed^?{+KD{LiV8hehezwmy8jM4+##Z(qM~|nCABq)PGn-z zX|ex0DIxUPUPP7goYhE)`paA%yO5oN<-J)h^^0+Fwx%6*2ljR$vutJEGA)Ix27vhj zeLw<>{KLH$;-}3awfRrOOeb8$H@EE4y^*Huceo#3hgfQoXZYLs&o3zsn~o``}9r>fPu}x60fkg!Q6A*De%x!If3n)v_zdhQi_Xjb#OeK z>*6F1>q_TGC6g&rNr`hQfKTYf!#xrO3rj zt#5I@Z@?5oh`HpS88v%}gG8!cLBK9;L#5cj%7Gbl>GO405U-g*ASi%jv(^RDP@_Zi zGhRi*Uu5`4s56WT|Clwn*Vw%=KfPr}x$4~<`LpBQ*dViwm0Dt1V2uL4|D|(&zzev= z$D?1O7da#AXZ(Q(AQj%9# z5HZb}c>1ky^fptMG~?s6VAaCJ?+NW4G2_k4=c>DPgo_}g))am0N*Vg8Z)o-cwiwr% z^80>7_lsP>>E4#Fc=xQT1O3wG4BeuW4@qrEV{>Rw0027K*=PKDwI#>vO%0tZN*gTm zjM9-msnI4y&M!r!kCk-#=2o5y*DCKnH{$D*ov6E0gBDF6o2H@)TLYk$d(>@XFrW+? z^DFi31ILv4o^SM|*x*tnU-h><1uL5&#qY-`y?@0)c}pI7zX&sN)*WOvF|XMy`kAs) zA&%sY@oGphE5B_g#YRNP=LuTwul#v*N3!;Jp#*I8R_>%F7Ier)g4qgVuew?Jr^K0;bTBo^;pxDw zE7n!OIFCXxeUzmoYLy*`cw&d(74LgAR@#L0>5b@l-&VpxOtE`LL8tu4WZHhRj*+A+ zMlQ#Es-PJic2B5`N;xd!J`ivCGEJ4VN4CVveKuisd^G@OGs@6ferdDya$H#7be~z) ze+#T{E{vu3Jy;l4C(f8O2QvY1({p*@xp8qpWR3gO%AYe#dpyb1?^j?xe80au(zb`V z+;^{kZ!4F&rB&f+;OfX$VC|U(Tf0VAV2m_J=Qjm+8Qd4|VLv#`NkjdjHF#IUPoYyJ z^!Az=C@XNo`#nfb_&e@S^E7}W*`4g5nh8iVP(8I3>KsT$VB#Sqh@B14A80-3XNO1a zXY5T1(BYYKa6dU*^kYeL;!Jsy?*3RHtRWl-frNPvdCr6Wni(LxvY-6s{_NN(3G^XM zmT`QpYvBYNua^S8*|$6Gl`fvj1`0q1-t$#cYpYVXhf{$-S=xY|0f8>vM0gMZLj^=_ zk*q)ylX12Hhf?v>G7SW(e^vRL4Zk9@%mFgI_K5`vq7rp>+GMVm(OS699>)_A_0RZG~^--z-c+`O2$3jact4;qs=2y zcIN8pYId;fBz`TxA#hKrizI7}pi*(WT0q?gU0Yif<4R6Wj>`qS&f7KDa&PgmEpi&b zEa&NP^4?bN7JrhFQ&A)a8 zr%{u5lyd5W{PYgY01Cce@fCF~yPtyx8_Lhd^N(QaiekF>wNOlA`mh$N``EXFM4@8E zBB)Z^+2y%~GXEQ;dcAq{tVpmqH|LBhTz0I-FV2((6!7ZF{hrH$k7|isnV*y9=~+bP zoawTRuDlWFf2?#c7jF-KT)OLYRs*gGAH7__4m!+9YU;TyO_gi9{uV4^258~Uqx-@` zNKN%ZQp$Y(Yb}rrvnu_og>SzciMMrYKFuy^fi#TPdY6vJP49{N=t{>NQGnVgx5gYS zPt(M=s{APJ2mjK)r~x$N>bz(#hoKd;_Rf)Tdi-YubJ|c?Z-BNyaH{9kLX4 z*T=wDqnRIl$|iFS$t(i#I2bGfuBR#3x+(ySZd=WQ8pg?A(gHz|E5-jvj^!Q@@OxUh zFiJ6#DPd`i1#2=P&{x}L1Ay><2$!&m#14LdZ&=LpoaFtF9|2HBPE{^3#jV09K-)s( z*{lBHOjrh@!#fdJB}I9j_o+Z$>9!?}~cJphlw+?Zgi1oD)lsTJk_+SF zcgT(rF_k|vBMZ3mNC{;B->AC&2Lm!L0aEs;yg;zID1J23tFb0{_g0Y*E$kyChqpX$ zEamAD5UCOm=%jj}G@yEbn)+TUSn^1aWe8m%39&1U&&_3ZElfnSd~SN5P%aCk+6mk0<2tqsnav2Roi#U+5YH`~M)F1X^lrB& z*LtZb!x1*kO|NJW$;tUqQRnS!y`BeF2nlYl$5evcAO8XPlNZJ&d1$owJhJ;8TrdkD zhdyX6dJXX;1KsTzp1afSSt9_Xn61ea01!-5kb~-}?aG4enm_weM7AU)p)3-n~74P|H9>A_%RL4SUCJukiY=`Gc+ z1s}eZ$KE~PcZ2rexD#P*B={!w9**LM=BcUw6LMr9zA)FK0|A2jr6#6`9daZsaHbD? zA#31D@Jq!Mz+wlK{1c%Mpul(k6SDJj$hfPJ4tG8Qo(Qz9D_RWGF1T?=6I@cw5f7bu z2UzLcJV#*!D2Agkc=xSo0&~Ffx0s+sdFRtrH|&fCkZ}H0RNZmfcO|#j&2vm1DUm&$ikWG7>7>wm0uWC3 zak&w>ES5{G6eS;p204Cc;3b$>UnnJ}w*^yqJN*c-_xCiERVooL!RTJMI!ZZiJgpz& z3KS|Us|2gB)fqWE8#ZPhKN@yIsSfYm{iiXhReYiN%xW{o2XnwtKvpWE2zxhp8wsiLZf36IAXa4*|$AmP;$DlU6jQcJ31MBAQ zX|{+<+SJxOcz%b=%0W_c1UeqUkRR%lFJ4k_a*}9ic+_$crIWSNR1N@|4=t!7YGxS-zwhs0_AH%Np4eTzIuh?`84O-+JOrDa0dhxV z4kodC2_?pjK?{yb*^B#i-iRi0)e855XS+u68`0OD2>sU;?{<5VWs!WG@Jc(F#f-ON zamhHVk|@z&%@gHQSz$_E{NMF3d9S(C7cSo!BrWa!{4Zl?;V~klv>b9bR3-LxJGbT45zN#f!^uSZMc5cuurawi3oofV_S-@waZ6YCeBtIurVZ%C45kK{!?hT|fXrKs zkg|oD4p?@HAAu#5Y(+vJlJ?vBUgh$bBE{VrOq22Z;e`_2cU=On{vDvaRJyadI$2%+ zL6`ZaMjZ#4I;7h%t9Sg;Z$&@=x)KDkt^s0ea?@C1vL9msGU0DC&$ds617WiqmVMpP z8pr|^{{iet(dbCAjycJBg7HHmTf@*@?v{qwx!jHGDN3^CZMBsHIs!I)Ma|94`=QjJ z8x%kgop#sMz~Gt5o1`NkmipcoZ&egwN#ho5v>?-)#@a&wH9iZF{cv`ZhBOBtE0JLJ95;XU zXpYP>c=!+EW(B)x8<}xRGw^h_Eq|!IyJ)KSv-u8R#Z$WSu{;I5_f$0Q0}#5e^Y8Pl z;Sfd^jHO(NMfFiVAcPBIVp;q}mvQYBpZ(W?{HjbMd)mwIwu?D+@MZ}vuJGa@8 zslk2Yv~rco$h0k4JvMD37Loh(gGE-^pHgOHXEf2Ds4eYm31lL`*~S?q`FSN{Nc5K;!yCO$=(t2HrP4Y|xE`2f5w5(b4TIIgv8pa>?n(PI?DIf-A?~91*+l!jr zk&l@F@8P`EZpoh$Rl|9@gUy8k6@=Mzd5g_j9B;>k@XnNI!=@m3-P7oM!?*%3^uSn^ z$`BeHtp{)v9Th6WgIY|5LLY1LuC9Cru#z!q{`vjNx!0ze<%y4AETo;=Id<;OPW8*u ztVMnXulIQ85kh?{%kO#2C3O}Kga%2GWzpU|?WmNoQ2{u$+?Ibi%On?T+3$k}!Jv8c7h(Mfp*z$LALNDOUp$RWf=bwVR_NO$alrEF&%6{yF35Qx z1o38t?QChoI{cnHm#m_lv1KCq7^w~!YV8@k|M86!qAq7Vd}x!~Rtu6EeL`>`SmVAR+W zZ-32JLBOpmqI8lASC)Tfmm)IuosA1DbZ9v({8hh5$P^!TFcojSj|6k1{Q`2yRe~Q9 z1*g}5arr(pFM=R;f0>*ha|axK>1!dDM$>hpXv-B&qZ*k(Y`QcrWGBy;4#jxDbc3S_rhLQ4M!E3k%g&+sIE^7as1 zZUAzB2V^S&qzd*}wETI^;>=lD*`CO_`S?-lTE1KE@Ptmz?b@a$%#qVl&cf$lR+pF0 z$B4@News9MNR!48M+py#^=BsM^KIvE4T-p0K77NczPf;DiQ;}N$(CU@X^%~fG%L)Vw zH>iQZ2Z4UrR%wwLOCTxSWk%)$nsmv0z*OH{RB{ktM6u`(jz{h=VsnxvkcC|ni@$!I zW1Mrc2=VwkMXyue%dFHyS{Yp+pAHJJ6nIu~8+%?*EmQAM>nj5bk^*kSPH~cV7XNtMR%(BFyqrQ4v;%6695CTv8cC#So?&xw|R_ zYY(D|X_-jGuU{kqQToMI!As{}pR8K;91OEZ)F`VLdV-dstt)S+1+8WmRJR4$+S_Zz ziHnOTBqv`#TwweEbFdGLZ93w1LLMt0lS8I`m?Tajk)yPOB1`oB_2Vc{36+$cm?!f9 zgj%9|_cA5%ZobTsRHqRw0^~0Ap7|`+<73~jL7FEyRSqQgVNeb}rcWYf$>uo$pe6b% z;f=R<`a0M*mI025%zH?dJTs)-U9DsQ#Yk;XX5-}k6l4dr$4MoydDkObk`#Ku!^935X zLKK49foeHbI1)W$PAxY%@nd7HC1tO-B>*c#(|-n->b;BgRW)ihWp2YmvpxmO!nGe> z6#td!;YKKO{UkM8KI_%DD1u9JCFWFZ2Jd%p6vLL}ji;U#-_&%={{fWcQQNT1Mt=-) zwfneGZ^50f7OP}@b@YLgPp0}x%i8eil%U(_)Px_bgWf~7X;Nl; zBS%&nECzp{d#B0fC_}{XuExolEB2gsIzI0h$uIZ1|16#>Pjs9Jnj{y*EVWb-q7Nro z;}yAO_&m}?esLCs9}X42lW`;5!NbxeB(4qeXl5F1NF};Fb{wV6OC(yowBg_-Y-@+0 z&6^`VR!oN0Cm7wY^jwKutgOyR+=Q7-KS9~1(eN-ip%ZCEy=S>gmHw+g;8xYA@j zJ*Qxj;!pXan(mL$lTxMrtHEn4y#fZVuAUM7#>tHCA!F}8RO^_V=bps}f0X!PRV)S> zOfo>FsH!BAi`5ScaZ>@77qU0Po7&bhAg=;WAEm+V)w&s~xz>ikSq|hVFnG{Bz{PyK zcc;9rPc6|sdMZHL+9v-QM$Fz&ZSUKIqSuNpX|1szrbZ_)Eq4zYfRG@|ExRn%O z@FB0&kgRSPyLnbYo924mN<-qTxqw)0wCLf)JZt%$KdD*Df3XE}0tE+hn-BwRTAib+ zTnb#G=2aO{8si!I@8m&lCC0SU584a>@CDk|oF_WxdMy52+9jnaN$UnUq?4j$Sg@vO z^VS+n3yuJ9J;NR?+}nb)5UFVuIC&t=FH3=9Y-JwVYdcOS4y!nX>M=>6meLa^C-=s8 zWN{<&;4kO+W)6$$f{wYP^;bQ;^|+b`>OnG5V;NsNp=|Is+@nN zwf@bMdNpOc6je}|2y(d+2~cD>nNoaGf~Y4bY;MQsv+fGZhH4J&U!uDR)u4MBsKWVY zO9Htx=-+(Ae_i(1IS@keBoRG%g zA{`3A$gST8=)bkZ8FKT0NB(a`Qb2{*zxy8ccp{AA6^_qB2qBPM$csvon#@&})xV70_b*&hFK>an9OEso*srz2H8 z5Wh?gD~TI<%zv}1+m_ylcx{FoTS=>VF(iFJ*s}Vu@GO`2kRGlf z6SK^#>9XDD!ZNzk_tF+McY9H~haf@CKYFvD#GW0t?3JpFE-X@(=386Qx2f?ug!ecF zd>z`2$G{9`_y4$@JZ|#C9fnDh4Ued_oOfr13)U-rd2O>{CACA&DPp(b>f=aR z{BZKxaCfIj|HfGM!=33{1RlF!iDcLohjZOeMT)lbdHDx(?OOT2VUS4c7*9Hswu@zC zlDk(>w*2p5!gmv=@B1tI?Qh-i>IFP<(PV== zdG1vqu(&0loj$h}Ec~_S&TnL54rh5a`JJB1NQYCR>Y=P%p6Z!EP7AbcDT{JZi5PC? zk%hLkwpukNSlzw0I&$biyLN$c8* z5`~}Ui?*@2Fb=mbV)l^>^v(R6LB{Qw#6aTl3ugSoDHlGeY^i+i^RzueJt* ze>>2oEnnr_SgBHlaR*LWjl z#tcu`V&i`uj>Aixq&C53*ykspH)>jWt1P?{YHLJ~K9}jz#jJb5EJH?vn?~o0aeUp<{T899+?1SY7OS2$cmj-`peDJ{`>Z4a;~HgTrS*7bz+3Nc@a6GH!`L1%0Ff<=z0Okm1i^B}TyZ zqjwFurP-yb+!0*(1Kv;SOaylDkXm{-_SyJNo77cX)Q%Ak|i0|5C0{2$aS)S)gzbI{sYhdAD%4P zSO(-6mcvR03*&asr+)RYZ}o=0CG;l6f#7mjC|LCRILMMLd{X2p?7_w6$G-Wevzf-V zE-yKQvs4P+qwb7bP%K%Kmz}h8?<_Au0Gwf>sDCLy=rF2=^9uRm6{K2u^PlN8Qa^1= z^Uci!r+}Fkl#_v$a{)v@nF{H^zmel0%_tsl{bO?3ze z2+#rPsSoc}Zk*WV{-gVn`Od^t@STm-d)gm%l`KoxI7f3l;Ioxcqm#e$xLzlsH=!0HMNB@6 zWB#}(vKf3mryxD}hXRd_bz|ZZcvCHvx0GB5yrhJBJOIt)%8}|ZUJh4Q3rBv4#SsyG zED@Nd#hAVnhm+hkWu(_sdrI-y`YV0Z7)`x~8mj?OZ|e3v-HNtzO8Qw~e0r8^&yV%0 zV8T1C$;|~1v#ZMiJp*3wyhloZ2#7mCE#6YOYbZS4*fBBU)toN$4|K6cWOxV@l(O@K z57)g*B&aL(@fO3slCYJ#vc1J!s>>bH-X30sSpj@G4C?KTarpetguPKOq_jWplS z#hj&9Zgm{oVZPO|xPlcb8@~q?Hsam)BQ{bNp^ppZ#KOqdJfunUMz+3_E)VTgLu&?s zV-$S!vyXRD|++#LUR8TL(V>GAbOSM6Q7!zrfyW^-1l#M5Kq% zzF+;?y*7>FKs~)`nWD(Gr%r){cfVjT&5o009-Y(QjFZrTODTRf^fCECe4BhrJE1{R zK9M7L1}c6_9PMm#ueshMtnuG_^OCqLji<*I1xkff`%_w_iK`ucXOX>md(2<+M&OEv zVW(2CqluSU+unEBg{cx$CwByQ-S(s7R4hMQ9Z!zjyb4@7TIsbSIo-`}wJo(a|CviO zt%fWk?)2H4==JkvI`yVpOnWE&%&IP1B~pn|wqYGP$=~Kgh^mU#OR@HibO_xEf+{wH zA@DNA__2a55r%Gk-}G1NyM#Eu$)9~`zV`dyy2McF)_UhWTfN7!eWPGP4No90kuZ;R zTv=aJDO#+ihfokO`*?9zZK?BH53rp@+bdJE5ii<^?;*Rh#NYq8v&;XcI~%UtqMyaz zU;te?cl*TdM@`S%fF3vre2456dnF8OdU<*Y5}Jt>SuTvJR z=v-jBq_MbXKOi6+EZgxBwI$Z(UNLp_p?AHab3a)iWeD6jneSo&&2|VX;)vnCbna21 z1Ax4Nk6A-djVU#NgT;u5fQyeB?1jqMRADpy8b zihWi_Dzvl{MTYvpoKpmo%nZ|7<94?Iuh5d1-M~htAwyxQSGH~y2eQKERgYtp8%GO) zGKR~SpLrg4-C|;*=4!9HC3P?Vrx1~QY@8%_@Iwr!veCD<4{yzoQ3G<=3(k|)$StKV z?7&^ken0HvoqB?Gw9cKnftF3l>K2y|RmE0CxpL95o9jb;LF<)Hh_u$pXa4Y(Q$1$v zpdWlv5;rpVoEfMyN_q=h+mML7+V^T<*`5t44cW4{eS@iyw3Kkr5@my?bO+e`I($(W zS>D_|cRp?4| z&7A|>rEHH%fiBS4@_+=?GmOx3AjOr*NIboJMD=ivrr>wYm%HX6=JW8Exi1&L%~0d6 z5ljx!PMaRcohV-;va27Zj}p!E7ng>B4M%D-V)60z?cMR_JDz_o9(=9qTtP-@mdkmy zbf?~Qow7c?PUoFULq!;to4pt}z{J{DCi&PO9%*bW3Gr`g=tJ@y^~~m)7Q^=S6Rjd& z4zyQrGNreIKn)%i%Q=`OkFMq4e;q?%!6ZZomx+F$r*%Mnm7ld2Qqv1%Re z($1cMc67JPHD!rS-={8P48j6e^k7M7bE$&!{kmc zhKJJRWZLYlcUAAKx`mqK8A#pFhkpn*6v_HOTm`p53)x_|-Q9p!6mVO|Bzx87@;db& zOpCeo`{_ic-b#5OESQb#b}SF%y^wlWOlxoMTy#fVu23|cZie@R{?FiP&CY?x@9~^(>GYPNO~G?mNW?uir4SVE0N^yitkr> z?f;oSSGgPm`L^L{?1<55+FCt4bxML}38Av67EkYMep0JF!AsYKIv|}!%k0dC5sea{ zFw2`Bow>O>E|cY2)ywnOpq8KC(kiN|dbEY|4t_HuR@a*4S;WiLY8z=6FmO513v(&; zfBua8k&VKPuB(6B`Q@abrA9O=$?_%eG1^;(fXi3b&@v7zdJZ*4kKtlILpG?(pE0k=Jp`!cv)y}x8 z_2>G57^~IQ5Lf)@jZSf#oSE5tV5?GfyX0A&4%*L^zl8&kB2w$Za(52)T#21#wH3EI z*2A=y{3q6j{IF5yKDXDMUED*9O+4UqPOjk645`v=2h2{ny#@1H+^*tmK#{KY3XiOt z!+t&8@P*ESgLK{D>Ajy$Vlh*ZzfaO>s~(G(f41w)Fp9VtKW;h1sArs#2Ld)tg>=q+ z24^et&7!dSCd22UNNJ({Hoj}(W%iCKedq)!8%sY06UaNijAtFG#{*fG0L#7 zN|T`~nQO{fv$1SBA6qc{-u{=wR-PVr&2{hOntmikXO3n|-R(O&%C2DM^&q%Sxb`FtYS7KxWnte@gAoq zhh*&GuLBkJPyZG^F4H+46;GDg5^@=HPVeiO2vkQ9d<e>n}&0%!3wm*0AQN>ZpKiV+~f6CZ$&f2X}t-& z@>82Q{Vm}3l)sz7=goao6;2NDDZH9JqywPf+$q+|4admiV5l6Y<}-C0SS8cmB(rD&-wIJ`R`!HniJqP4&&TK2xaK- z7eUyVy;40ORS#o&=J&OSKu*M^ZYu|c2o76s?_{~$F1V>uyd1U#71M zgx=^Z90v4)>R{Q`jzi*8^GZKS?98Y7YQ>49+|wYdaP8PTz7%2Xe&A8NfzFQ0*B&$TIhIG$;qkSs zh!C%rrX16y4rbfi@Ll&;=Je_W+`P`NPjx2nViiLF+4{2K5NK6chLul%BjF_PLV))w zs%eupE_WHSx17B>8JA0Qa=@b_5B~}y5!%p2%0R(g@*$2*uQxX2`kM3U=taHZ3W=6R zmc+?#vfFN&wfo1j+q3IY(YL93Wy!CUk?NM^o}k-3lwa*=^e&n5Z?usn7W2tZ$O@ST zESxep9dI!$ce0%C{W9%C%y2U@cT8`DRhDY4Tb^DFcN7z0nYB7JLt3O&;RKh;RI6`V#Em}M$@%3MK;20jqd z7%F?FQ#mxvfGx8AXGte_%Ub2>;YUkowG~oKVS3Xo^vlkAvT&gRL+evb=ZS%0E|O>9 zk3;3ddH%7fr;Uk;!i8|xX^lF!|D(P04r=Oa_dSY;qJRnlQY{G5l_I?;f^<-tbPZ(y&sTOE-1(qY9HbYwSnJ! z`e=4L2sGWH685;$w-p%M&GfUmLZt#|`iB%uZg_BMxzM??&gB|A%0Z)omNr1!`%CO! z5|$mqvi8>Y;cHuG(3vXN!g`9;BLQ|zbiWHAWK*zy*S&Bw7?mai3=r(zj{d>0pbe3C zaN}O}oYl0r8ryXtm-XiD_RBUjA4sRZ0Vz}SE^Kd#lc-eU0xN7!kPoU=f0su?nnJ!9 z6WZePeL|Pc1@;yfy~Xn7&!xnUXxHZ!cIJ2L|t>i^;xfVQ|qS*t2sdeaI`kVnz3k1oy9tN%5oh9{A05{3|2=0hy=m~aWw)V zXNGd5ornpdE9WAg-xaO=T%kFb{AF;lKa91|0<%M`Za(=S{fy#xOx5!l_CE)yHP`^EOiFf znHQ)Qj?os?@i%-cS=ZRe(Xcj$T{Lg@D!~*X14sY3ypSOgt)DPa9sICDR4hcg@2eos z;$TkD?0q-ZdMv%KqwZA|^<{T38P2Cj7TvG8WN|c)yml{bJkYh;O0l(IT}pvA{oO>s zL$mbBWE{f4O6$Doc{j%)0En@ zF|sQ`BP=xJS?o|YW%fvCtFP|~q`ivNJJA?6Ctm0;;*=%*>(^JE%I<4J#|vbId+q{n zbfOGd4@Gahn%MtXnJCu9rD~SJG+0&a&%J-#=EtL=gJJ%m%6HEBEj;l`M{L*dIgX=x z@U<}%BW(e$>k>1)5qL9Y=*)OkJ?TW8b_A`_$|eP@TSs@y0^AH;U)*LwO_v@PQ-3Fy1Z;D9d zJppbdq>{9RR%xm}w8hF?@qK&*u#DyIk<5SiZ_mhlOLP}r@PqoX6NlAodA7T`ml&qr zCGRdRq<`?iDi`ExgrNkwBX_@QVD@|se-2dSO4WBNsC+WF`Y5rRn*koVL?s({&b@n| zXS;IPt^atzl1n&%`#Av2gzj$c+(b0a(C}F@q$X`d3xb&Tgab;7Wrj|V=X_;LLip13 z4ldH}%7)qFiznt{kHsuE(LXt$@;zWxSH^hD_h*wg?hOU@@$-+7D6L~eD805t6h~jX1iA%pKgA#nBeYNN>|Ear zc@I9q*}t=M(eK2eyv+dYY!GuLHYevauQt#NYwS!nYzD_=So^25dfA+(gLv71=2!@hu`JiPI`(*7~h(y3XB?IswB!zxIT!NiTc2 z2~^Us=4;Jl-CGsQyX48$qo5!5BU0}lEd6TTrzG8%D9J3EOUWq?#Mb&{Do}cFe0r3$ zVFFCX(q-SX9V)Q+Sk|LMVzLrI@3JKy6Qz{f%S4E?NqxNdO zBOT*f&+JWWQWK(3;rWQ+LZoS>g~!MS3u@&}Kg)p5Qecy`O-N&aJr06ZFSf2@;_jV# z?S;sJE}d1*{Hzw;p+F<<>pK}Vw5}yDhLH$sz>egQK5G4`=~^WHf~wkHc#{ol-b=Tf zFlr-U1#xg&EfMnav)i?En2u|DKX+m&4uk&*hf6{sH5`?n+h%Y zu~bea<$CxG;E!+|lCn|pG^_PXn76qdTU!R*cSYa3PF`=#sen~)C-kXr+GndSaa7t` zmi(BT{r1#rb=9^e^dnGrq%`mw>;9HaWjSAQplB?-eR7OW+f{JFardcP&*k8Y*I^U= zdqaJLV%owBEYP$kT*mbu=g`KcC(1c`dEV_@oN$vl|@E2!+rhrx)8GrThM|FHf&&M%SKCoW9 zJYb+!LAKVq@1x^`$u8) zjJ>?#b>Fd6k-ilU&*Buze0v;YdL9MeFtv!4$eW#hH!=}C!qo14bqUqxCYzCwQFOYX z?djT^r~!2IA+3vMhduM{+FkFm$(N4GunNiRGSXSc&I}AHX^F-(SZuq<;M^{C8jKZ= zY$6SKi?eD{#i2{vVo}`_6`q(-A3l{E%3`%5(cX?F!JDzxx44F_nty$B3Ei#fT-!1S zP1c#Y^vN#?IMCtYqenOvP1> ze1&lpe@hq*R;YX|9$qCFW`w;hfC6d|I*-4q9MpgO;hi^a#PMy>oJw;AeePIR={SMv zA6}M3s`0F@0C-O+_UO)rI%X(8hL67}UVF2=any3S!NzVQS`;^|?jEc_N&|z65for# zdm(GqEk(1>G2o%+F7P%Scr>SW^EANDkd|<`x^iUT`0Blv#t6*BG!Vd-75`05qsG% zmrudCedlGX=3v_x>L6Oe8VWEH<;LsO9qEdhKw*=;Qd;-ur z0X~7eo+VR4i5V45Z%V{AYEeinP{SfYAqH8aca>ficQg>aTVb?nNiV_)GFg)%^N!|!hM ztSpd)w+*bnB@%cC@D#?n*@&$l2J)4K>T~9@40-N_|Kv;j&zcq0_gIxw*{OI@=HT+} zpMt-49o(q`KQ|4{MDoHz(Sn;!3z@88@`v9!;*MV9X|9(*@8d91}Bxlrbvz#D1}&dMu)<$*e&PF4cXzn7JhOOB5}%`0~fwB!n`G1<()ARh!) zlKN;auGjFbzH%AU8zBB_kTLTDc2Fa?D8{UsCg7RPlA`Yvyw=Mx8A=j7ExgvS$#kiV zQ!E9UwO$LMG4gGm_8l6$*4FdsQXDs*4%o-4<;?S1R}ap&bxU? zq0B#{1=vu8f0Qj=04v`B@!OIx3(PU6LSbblWT@FX^QOKw);iLvs(D<~dfTRv*4yvBbFDO2;~R<7wi6&#jOACp#5C)| zB@JDevjN&pL;K4(kMB=h_s_d|PTsNxck`Cj8AAs|8B07Lq||y+482t7hNvwI)jZc2 z@1f$>@cgGkBI1VH;Kk48XWvL`o8bP6R$QNWIt0O&X$vcOuF@D)X4+oszeIFoDAqcE zmv?wv*Zk$ZIdl0B%qIBz8Unm{YGJCirL4Gy+XEG-_Vj2a>0)+d3R&r-wn=vB_r-+h z`QfLmp{vb|AAD{;U9)e+`w3OZO)W_fi#8@U)%z-zB&wSRD;Ce&UR~dz116uvk?LHV ze-k7bfGey||B0DQ*SPwgPLLA*sIQyVe4lKSQz=rLp72)dP4u7fS;5)Hx}$AaYvQ zYgYPn zEhFEYIlK68(?E9v$ya0eFY9Mo)I-ulZoR;~&baCgTfE+Q{kW%v`CIu17XI`O5o8+d zGp-b4XRDymN$ghASDvy%x&;q7-d*;*1K`& zMUnjWn|AR0>a;|;#L)2wP^@s#c*gNOzikg}kb`w3!U}Hz>eg=zb?sve-5~5&uJ7+Y z+uQ8eA7q!79)v;s7C=4KsmqBm357vWbR!>DBXasQoxZn&nPl7B`-_n_|A`qh={r*C z{7Y-+2BP%&zib(4U+uewp)Ue3aHRz0SnxS@8c5IFoA5X-+_8GLzJ$LWvyi~H|$#Yp^`rW*vPD6dXDZ?&XX6Van zTT@FuabmxrZQ`lIfV~Btt86szm<; z@21T~p=0Rj`@eW*K!4_mGwU{f85M ze4bW9kd{e)8}*d?ES6`Fl>+2CQ+D+*Y5$7H4=_;jkajM>b-Gs^XsS-AND-z(I(KM= zke6JMR27PP+O1U2Hy!k!FL}+)@*G-svg;%ry{$k!lV8Tx(Iii!8&5mvJ*{cD938aC zZ3*CjpsXa9{^=J1>D#Ja+28_mZOGhVDj|n0+oInRjwcszl*CQPUJ_97f_%BFKBQ)> z)6u&ypXKXMD7G|2g6Vn~sW+Mf4+ksKc}XapptyCB$^cu*L=R*wx=+!w(zIJuGyH{( zoV0n)vmI~yN|sFx>qgq7V&&jq5m_O?_s$!s^a$&z#Wz12ZBZ7~A*SVyTs6H`6!|1Y zv%d<8BCAuz1;ReA&$cd)XcE_R#>NiQzGUa(8WO|E3P-fumox*k&Mxo9RjGv4b+D-p z0Nv5N`Y2{LnONv&xvRCQv3WvFsrcvCAqUlNXj{VNgHDO=?tZ1!=(h4e!NST5=ns+4 zo{dW;z-YM5#^cKc$!?Z12oiR!7rb3xoC+KI)9BhlRgQchM8YZe*jZIxA{!kDpxGcXGdcD#>d`S=lf7p8>7j|(| zDmzwvwu0KHLPm6w_Xr|oH8ZbT0_SuUD9R72@-a|Sb>?!oDTQ)KJ(QHLqFId?VMp@~ zpZn} z_%Pv1()eWe2%B`P&3DKk=I-c{TDCN!#z?LA-jjl|?S;a|g4eGVDSnW!fy+Psb_>xEoF*@k4?}2k*Nh4*vORxT4`20f z%Who0bz|_ygtUQKmV6IA{B=jjL(h(;E1f)*Jz;|trC4TgN78+mOD4HaQ#9sW-ac)H z6NzM&pDV71Oy#$hH_JVSKP*^8h=L4mIp-8lM?bf=e|))|V3yZirXN&^LZ_67c-Vkf zaKi?T<|;2F{KDbE-0prY_qhXaaX$uZu?H^Z8T?^ObQ{>&GCjc1&=T!Yl*P{%18_LY z0Z;5mpwVykmC0w#xH+z7f>^t0f^c*FDkDO?IQ4q-hZM%JVNFCBRf>OctcA8%>T)G6 z8aVT|@30R&zJ#T&XnA%G0yp@dd*dEF^Q;LA1`A^Q%dK_gL>V8Ne`~qZn46WTU-xvH z)V)XTDRzK2^O*zE_LQg@uv*!wDG#6J`}Q6ncV5Pt)W;L+6!=unruBZbM+_kA`#~%k z*X>VzB&9)#$vRfo~~6b@B&9B~-LeDzyIG6c(2k z$+(VxN$xFAb0ooSwQ1~l%`E)7(~Ng)ynLtG2Ip!hk>Y&!6P0>GH#ha~6M3ODPlV$# zW#Z_mPfh-imvKS-!<$?qizk?1>#4!E;FWjryc)H+RA`~26Uw(TvSvxUD4YjyroML& z;NRp1EYD0hgn~>OsMx5_Dq`l1*?S4BQ=Zod>W6WOM?lsQmpW;hm4%4V(Gnx8polUm z*wo*KU*!$wZ>RGj@hR52;xoDjK!7!Ni1Bu>Dj?xn60q`GS@{&%=(fih6v6gU{cM%` zc^u7sV}yz0;rt8+itosV%E45BM!@g*4OinYbF}u)xQJlRFU(hIrFTQ>fw;mmsia)2 ziZyUt8WMYMI{3c#lLOuscwxYeirY_p6{u^DMlM8JDuLnduQ`a6?G&NFxpRGp)jBsH z?VDZdM1(}QY;E810QSS`MnP&A2o9bHtt9hAs z5Ryx&`f+Tn@Q<{v??H|6#38H5Mxsv$pegvao~a@ZQa14bg5z%%tE zD;MCC4A9JG!6vc4$u?j3mW~ycW$*BU$=#~RM{}e#WS6x^_c!}&wO&EfZGAGE&(>CT zc@)V!B#ET@47r`aFC;*DiV#?yat>Yg z{)pBpb4RL~deij1t(HpPy8vqEMkSZeu{h|FP(J8i)uf7@Y{5wSBLUy#ts-V_xBchT zonLWD3We^`YY@dY*NlIJmo#iofekyaZqvpd5`*?hN$D3Nel*3?>Qyyh!6XvQZ{MS! zvD}15T?-msL1rG>w3*q4b2TvQKjaV|aOVe3)=*HXIi-&s{E_lrS4h#IgiQz*X!5$r zPuuTynvr>gy4m>ywZ`oe0It5R5HarH46l^RJ1AOCM6mk8^Q99rcvCj7iC{&KZ~c+t zsGzLt`w^{HRbypcxyp`lsabARz&9rOPc@!6`K%axGO@;cG)PM{SILZ#`5QM@fc2#U zkV1%NkJ)GC0YY#9I87CQ_^)f;Z4IA3oG<$x(|bID;nZ&k%Wqdl;pJd%79hX^M5O-J z-~p&iX6)L}YfOYOXgL99()Sx_?*MGuKLFf%Gi^)^N};`Eh5y4OqBVw)glX3Uk)$1^ z5u$5VGoY&R?1?yykTmr1@j1QD@T4kr5sClbtQVjE3AXgYV+XLU{o%IdnxvyA=;n7e z+@%?{oLuWfGK6{y)Bz9oO-;E!p%?MD^_oES0an=ssnM%tS9X3Avckf`N+$%aWXo=% zW;G`DE!Y_rzMh1LASP`3z8(uULNgYaQ;+DE^kM9|0Jn~{9%qLNhe)>U+>cr{73aHE zcs)72jxlbAHOo8gIRml_yI@V%BZk2Z;I}9!z%S@C;Os|TG*Zzd62H~#`B2;K0d?im zbGyA}=cMlG+6BF}JwTV+yl%47G$cz{q@Z4EGB)Yk#&0xBhL{0-52j8p(wxY15(kfCI@dzBfuL-EjJQ*(Hy(n-XyMf%@e!P)dQ|6p{{X zrG^l-Qw;oX$49!Wnj8WD(wf-pm%(sg?7BHF_udY6J`7+34COBr!$iLW8G(cL{?~}k z|I@1V|6jm=f%N}>d?)_SS^On=_V+g~5O3bR`2#;X{B$ez zw5XBvfkpc;@P#w*0h;r_`wMIb-q8O^4<(OnNBuFmo9*_zA}s^Rkdfc67C?x4u)BJ* zZ_NPsU5*@RS+D+11O5JF#{XNg>A!jKRsfi+CpO0z%6?b(4+S4+0+3eLl5r>cx3m7C zV0A@z!QrxhB)I_k^WERtas{yg|>%KsWt39N}dsWOUy0=$`@!yi}`|Fgc&|EPe` bedgG6iFp!ZPm#cr81!{aZdKj9|LorY-7;hG literal 0 HcmV?d00001 diff --git a/docs/docs/barcodes/custom.md b/docs/docs/barcodes/custom.md index 560f142742..daf7b48967 100644 --- a/docs/docs/barcodes/custom.md +++ b/docs/docs/barcodes/custom.md @@ -31,7 +31,7 @@ The barcode is tested as follows, in decreasing order of priority: InvenTree comes with a few builtin supplier plugins, which handle their respective barcode formats. -Scanning a supplier barcode for a supplied part will link to the corresponding supplier part if the [SKU](../report/context_variables.md#supplierpart) from the barcode could be matched. +Scanning a supplier barcode for a supplied part will link to the corresponding supplier part if the [SKU](../report/model_context.md#supplier-part) from the barcode could be matched. The following suppliers (and barcode formats) are currently supported: diff --git a/docs/docs/barcodes/index.md b/docs/docs/barcodes/index.md index 6d5eb04d76..e9fa6020ea 100644 --- a/docs/docs/barcodes/index.md +++ b/docs/docs/barcodes/index.md @@ -101,7 +101,7 @@ If enabled, InvenTree can retain logs of the most recent barcode scans. This can Refer to the [barcode settings](../settings/global.md#barcodes) to enable barcode history logging. -The barcode history can be viewed via the admin panel in the web interface. +The barcode history can be viewed in the [Admin Center](../settings/admin.md#admin-center) in the web interface. ## Barcode Settings diff --git a/docs/docs/concepts/data_import.md b/docs/docs/concepts/data_import.md index 16b1e1f259..eac5712c86 100644 --- a/docs/docs/concepts/data_import.md +++ b/docs/docs/concepts/data_import.md @@ -4,7 +4,7 @@ title: Importing Data ## Importing Data -External data can be imported via the admin interface, allowing for rapid integration of existing datasets, or bulk editing of table data. +External data can be imported via the [Admin Center](../settings/admin.md#admin-center), allowing for rapid integration of existing datasets, or bulk editing of table data. !!! danger "Danger" Uploading bulk data directly is a non-reversible action. @@ -57,7 +57,7 @@ An import session can be initiated from a number of different contexts within th Staff users can create an import session from within the [Admin Center](../settings/admin.md#admin-center). This is a general-purpose import session, and the user will be required to select the type of data to import. -Users can quickly navigate to the data import management page from the [spotlight search](../concepts/user_interface.md#spotlight), by searching for "import" and selecting the "Import data" option. +Users can quickly navigate to the data import management page from the [spotlight search](./ui/index.md#spotlight), by searching for "import" and selecting the "Import data" option. ### Data Tables diff --git a/docs/docs/concepts/parameters.md b/docs/docs/concepts/parameters.md index 47e42cec97..0a520a4be4 100644 --- a/docs/docs/concepts/parameters.md +++ b/docs/docs/concepts/parameters.md @@ -30,12 +30,13 @@ Parameter templates are used to define the different types of parameters which a | Choices | A comma-separated list of valid choices for parameter values linked to this template. | | Checkbox | If set, parameters linked to this template can only be assigned values *true* or *false* | | Selection List | If set, parameters linked to this template can only be assigned values from the linked [selection list](#selection-lists) | +| Unique | Enforce a [uniqueness requirement](#parameter-uniqueness) on parameter values linked to this template | {{ image("concepts/parameter-template.png", "Parameters Template") }} ### Create Template -Parameter templates are created and edited via the [admin interface](../settings/admin.md). +Parameter templates are created and edited via the [Admin Center](../settings/admin.md#admin-center). To create a template: @@ -59,6 +60,45 @@ To add a parameter, navigate to a specific part detail page, click on the "Param Select the parameter `Template` you would like to use for this parameter, fill-out the `Data` field (value of this specific parameter) and click the "Submit" button. +### Parameter Uniqueness + +A parameter template can be configured to enforce a uniqueness requirement on the values of any parameters linked to it. This is useful for parameters which are expected to act as a unique identifier and prevents duplicate values from being entered by mistake. + +The `Unique` attribute on a parameter template supports the following options: + +| Option | Description | +| --- | --- | +| No uniqueness required | The default option - no restriction is placed on parameter values | +| Unique for model type | A parameter value must be unique amongst all other parameters (linked to this template) which are assigned to the *same* model type. For example, a template with this option enabled could be used to enforce unique serial numbers across all `Part` instances, without preventing the same value from also being used against a `Company` instance | +| Globally unique | A parameter value must be unique amongst *all* other parameters linked to this template, regardless of the model type to which they are assigned | + +!!! info "Case Insensitive" + Uniqueness checks are case-insensitive - for example, the values `ABC123` and `abc123` are considered to be duplicates of each other. + +If a parameter value is entered which does not satisfy the uniqueness requirement of its template, it will be rejected and an error message displayed. + +#### Validation Against Numeric Value + +If a parameter template defines a set of [units](#parameter-units), uniqueness is checked against the *normalized numeric value* of the parameter, rather than the raw text entered. This ensures that equivalent values expressed in different (but compatible) units are correctly detected as duplicates. + +For example, if a *Resistance* template (with base units of `ohm`) enforces uniqueness, then a value of `1k` would be rejected as a duplicate of an existing value of `1000`, as they both represent the same physical quantity. + +Templates which do not define a set of units are compared using a direct (case-insensitive) text comparison of the raw parameter value. + +#### Copying Caveats + +Some workflows in InvenTree allow parameters to be copied from one object to another - for example, when duplicating a part, build order, or other object which supports parameters. + +Any parameter which is linked to a template with a uniqueness requirement is *skipped* when copying parameters in this way. This prevents the copy operation from creating a duplicate (and therefore invalid) value on the new object. If this occurs, the new object simply will not have a parameter created against that particular template - it can be added manually (with a distinct value) afterwards. + +#### Category Parameter Caveats + +A parameter template can be linked to a part category, along with a default value which is automatically applied to any new parts created within that category (or a sub-category). + +This default value system is not compatible with a template which enforces a uniqueness requirement - applying the *same* default value to every part in a category would immediately conflict with the "unique" requirement, as soon as more than one part exists in that category. + +For this reason, a category-based default value is *not* applied for any parameter template which has a uniqueness requirement configured. If you need to assign values for such parameters, this must be done manually (or via the API) on a per-part basis. + ## Parametric Tables Parametric tables gather all parameters from all objects of a particular type, to be sorted and filtered. diff --git a/docs/docs/concepts/pricing.md b/docs/docs/concepts/pricing.md index 037387e019..8d08c2ece5 100644 --- a/docs/docs/concepts/pricing.md +++ b/docs/docs/concepts/pricing.md @@ -23,6 +23,36 @@ Throughout this documentation (and within InvenTree) the concepts of *cost* and | Price | The theoretical amount of money required to pay for something. | | Cost | The actual amount of money paid. | +## Line Items + +Orders (Purchase Orders, Sales Orders, and Return Orders) are made up of *line items*, each linking a *Quantity* to a *Unit Price*. A line item's *Line Total* is calculated as follows: + +``` +Line Total = Quantity * Unit Price +``` + +An order's overall *Total Price* is calculated by summing the *Line Total* of every line item and [extra line item](#extra-line-items) associated with the order. + +### Extra Line Items + +*Extra Line Items* provide a way to add itemized costs to an order which are not tied to a specific part or stock item - for example freight charges, service fees, or other miscellaneous costs. Extra line items support the same *Quantity* and *Unit Price* fields as regular line items, and are included in the order's *Total Price* calculation. + +### Line Item Discount + +Line items - and their associated [extra line items](#extra-line-items) - support an optional *Discount* field, expressed as a percentage between 0% and 100%. This is available on: + +- [Purchase Order](../purchasing/purchase_order.md#add-line-items) line items and [extra line items](../purchasing/purchase_order.md#extra-line-items) +- [Sales Order](../sales/sales_order.md#add-line-items) line items and [extra line items](../sales/sales_order.md#extra-line-items) +- [Return Order](../sales/return_order.md#line-items) line items and [extra line items](../sales/return_order.md#extra-line-items) + +If specified, the discount is applied to the *Line Total*, using the following formula: + +``` +Line Total = Quantity * Unit Price * (1 - Discount / 100) +``` + +!!! info "Optional" + The discount percentage is optional, and defaults to 0% (no discount) if not specified. ## Currency Support @@ -63,3 +93,9 @@ Currency exchange rates are updated periodically, using the configured currency ## Pricing Settings Refer to the [global settings](../settings/global.md#pricing-and-currency) documentation for more information on available currency settings. + +## Rendering Currencies in Reports + +Currency values can be rendered in report templates using the [`render_currency`](../report/helpers.md#render_currency) helper function. This function formats a currency amount according to a locale, and supports currency conversion within the template. + +See the [report helpers documentation](../report/helpers.md#currency-formatting) for full details and examples. diff --git a/docs/docs/concepts/tags.md b/docs/docs/concepts/tags.md new file mode 100644 index 0000000000..87454431c0 --- /dev/null +++ b/docs/docs/concepts/tags.md @@ -0,0 +1,82 @@ +--- +title: Tags +--- + +## Tags + +*Tags* are short, arbitrary labels that can be attached to InvenTree objects to group or classify them in flexible ways that don't require changes to the underlying data model. Unlike [parameters](./parameters.md), tags carry no typed value — they are simply names. A tag can be applied to objects of any supported model type, and tags are shared across the entire InvenTree instance. + +!!! note "Shared Tag Namespace" + Tags are global: a tag named `prototype` applied to a Part and the same tag applied to a Build Order refer to the same underlying tag record. Renaming or deleting a tag affects every object to which it is attached. + +### Supported Models + +Tags can be attached to the following InvenTree objects: + +- [Parts](../part/index.md) +- [Supplier Parts](../purchasing/supplier.md#supplier-parts) +- [Manufacturer Parts](../purchasing/manufacturer.md#manufacturer-parts) +- [Companies](./company.md) +- [Stock Items](../stock/index.md#stock-item) +- [Stock Locations](../stock/index.md#stock-location) +- [Build Orders](../manufacturing/build.md) +- [Purchase Orders](../purchasing/purchase_order.md) +- [Sales Orders](../sales/sales_order.md) +- [Return Orders](../sales/return_order.md) +- [Sales Order Shipments](../sales/sales_order.md#shipments) + +## Managing Tags + +### Adding and Removing Tags + +Any object that supports tags will expose a *Tags* field in its detail and edit forms. Tags are entered as a comma-separated list of names and can be freely added or removed at any time. Tag names are case-insensitive — `Prototype`, `prototype`, and `PROTOTYPE` all refer to the same tag. + +### Tag Names + +Tag names must be unique within the InvenTree instance (case-insensitively). If you type a name that already exists under a different capitalisation, the existing tag is assigned rather than a new one created. Tag names may contain spaces, but leading and trailing whitespace is stripped automatically. + +## Filtering by Tags + +Tables that support tags can be filtered by one or more tag names. When multiple tags are specified, only objects that carry **all** of the specified tags are returned (AND logic). + +For example, filtering a Parts table by the tags `approved` and `prototype` returns only parts tagged with both. + +## API Access + +### Tag Endpoints + +The tag list is available at `/api/tag/`. Individual tags can be retrieved, updated, or deleted at `/api/tag//`. + +The `model_type` query parameter narrows the tag list to tags currently applied to a specific model type: + +``` +GET /api/tag/?model_type=part +``` + +### Tags on Model Endpoints + +For models that support tags, the `tags` field is returned in the detail endpoint response as a list of tag name strings: + +```json +{ + "pk": 42, + "name": "Widget", + "tags": ["approved", "prototype"] +} +``` + +Tags can be updated via a `PATCH` or `POST` request by supplying a JSON-encoded list of tag name strings. The full list of tags replaces the previous set — omitting a tag removes it: + +```json +{ + "tags": ["approved", "production"] +} +``` + +Tags can also be used as a filter parameter on list endpoints. Supply a comma-separated list of tag names to the `tags` query parameter: + +``` +GET /api/part/?tags=approved,prototype +``` + +This returns only parts tagged with **both** `approved` and `prototype`. diff --git a/docs/docs/concepts/terminology.md b/docs/docs/concepts/terminology.md index ba127d9a48..050a4231d8 100644 --- a/docs/docs/concepts/terminology.md +++ b/docs/docs/concepts/terminology.md @@ -9,7 +9,7 @@ There are different systems in the industry for the management of getting, stori **InvenTree** is mainly focused on [**IMS**](#inventory-management-system-ims) and [**PLM**](#part-library-management-plm) functionality. ### Inventory Management System *(IMS)* -Evolves around manufacturing of parts out of other parts. It keeps track of stock, part origin, orders, shelf live and more. +Evolves around manufacturing of parts out of other parts. It keeps track of stock, part origin, orders, shelf life and more. ### Part Library Management *(PLM)* Keeps track of BOMs, part variants, possible substitutions, versions, IPNs and further part parameters. diff --git a/docs/docs/concepts/ui/forms.md b/docs/docs/concepts/ui/forms.md new file mode 100644 index 0000000000..8c153eacce --- /dev/null +++ b/docs/docs/concepts/ui/forms.md @@ -0,0 +1,37 @@ +--- +title: Forms +--- + +## Forms + +Data entry and editing within InvenTree is typically performed through the use of forms, which provide a structured interface for inputting and modifying data. Forms are designed to be user-friendly and efficient, allowing users to quickly enter and update information within the system. + +Forms are typically displayed as a modal dialog, separated into multiple sections and fields. + +### Data Creation + +Example: Creating a new part via the "Add Part" form: + +{{ image("concepts/ui_form_add_part.png", "Add Part Button") }} + +On several forms is displayed option "Keep form open" in bottom part of the form on left side of Submit button (option is visible on the screenshot above). When this switch is turned on, form window is not closed after submit and filled form data is not reset. This is useful for creating more entries at one time with similar properties (e.g. only different number in name). + +### Data Editing + +Example: Editing an existing purchase order via the "Edit Purchase Order" form: + +{{ image("concepts/ui_form_edit_po.png", "Edit Purchase Order") }} + +### Form Submission + +A form can be submitted by clicking the "Submit" button located at the bottom-right corner of the form. + +Alternatively, an open form can be submitted using the keyboard shortcut `Ctrl + Enter` (or `Cmd + Enter` on macOS). This shortcut works even while typing in a form field, providing a quick way to submit the form without needing to reach for the mouse. It is particularly useful in multi-line text fields, where pressing `Enter` inserts a new line rather than submitting the form. + +The keyboard shortcut is only active while a form is open, and follows the same rules as the "Submit" button - for example, it has no effect while the form is loading, or when editing an existing item without any changes. + +### Confirm Actions + +Many actions within InvenTree require user confirmation before they can be executed. This is typically implemented through the use of confirmation dialogs, which prompt the user to confirm their intention before proceeding with the action. + +{{ image("concepts/ui_form_hold_po.png", "Confirmation Dialog") }} diff --git a/docs/docs/concepts/ui/global_search.md b/docs/docs/concepts/ui/global_search.md new file mode 100644 index 0000000000..1219ec64a3 --- /dev/null +++ b/docs/docs/concepts/ui/global_search.md @@ -0,0 +1,42 @@ +--- +title: Global Search +--- + +## Global Search + +Accessible from the [main menu](./index.md#main-menu), the global search functionality allows users to quickly find specific items or information within the InvenTree system. The search icon is located at the top of the interface and provides a convenient way to search across all sections of the system. + +Clicking on the "search" icon (in the menu bar) opens the search menu, which allows users to enter search queries and view results from across the system. + +{{ image("concepts/ui_global_search.png", "Global Search") }} + +Search results are organized by category (e.g. Parts, Stock, Manufacturing, etc.) and provide quick access to the relevant pages for each search result. + +### Detail View + +To navigate to the detail page for a particular search result, simply click on the desired result from the search results list. This will take you directly to the relevant page within the InvenTree system, allowing you to view and interact with the specific item or information you were searching for. + +### Preview Panel + +Instead of navigating directly to a result's detail page, search results can be configured to open in the [preview panel](./preview_panels.md), keeping the global search menu open behind it. + +To enable this behavior, both of the following user settings must be enabled, found in the *Search* tab of the [user settings](../../settings/user.md) page: + +- **Table Preview Panel** - enables the preview panel feature generally +- **Search Results Preview Panel** - enables the preview panel specifically for global search results + +With both settings enabled, clicking on a search result opens the preview drawer instead of navigating away. As with other preview panel usages, hold `Ctrl` (or `Cmd` on macOS) while clicking, or middle-click, to bypass the preview and navigate directly to the detail page. + +### Full Results + +The "global search" menu provides a limited set of search results for each category, typically showing the most relevant or recent results. To view the full set of search results for a particular category, click on the "View all results" button located at the top-left of the search results list for that category: + +{{ image("concepts/ui_global_search_view_all.png", "View Full Search Results") }} + +### Collapse Result Groups + +To collapse a particular category of search results in the global search menu, click on the "collapse" icon located at the top-right corner of the search results list for that category. This will hide the search results for that category, allowing you to focus on other categories or search results. + +### Remove Result Groups + +To remove a particular category of search results from the global search menu, click on the "remove" icon located at the top-right corner of the search results list for that category. diff --git a/docs/docs/concepts/ui/index.md b/docs/docs/concepts/ui/index.md new file mode 100644 index 0000000000..758ee4a904 --- /dev/null +++ b/docs/docs/concepts/ui/index.md @@ -0,0 +1,190 @@ +--- +title: User Interface +--- + +## User Interface + +The InvenTree user interface is designed to be intuitive and user-friendly, providing easy access to the various features and functions of the system. The interface is organized into several key components, including navigation menus, settings, forms, tables, search functionality, and more. + +The interface is designed for large-format displays, and as such is explicitly *not* optimized for mobile devices. However, the interface is responsive and should work on a wide range of desktop screen sizes. + +## Navigation + +Navigation throughout the InvenTree interface is designed to be straightforward and efficient, allowing users to quickly access the various sections and features of the system. The navigation is organized into several key areas, including the main menu, navigation menu, and page panels. + +### Main Menu + +The main menu is located at the top of the interface and provides access to the primary sections of the system: + +{{ image("concepts/ui_main_menu.png", "Main Menu") }} + +From the main menu, users can access the following items: + +- [Navigation Menu](#navigation-menu) +- [Dashboard](#dashboard) +- [Global Search](./global_search.md) +- [Spotlight](#spotlight) +- [Barcode Scanning](../../barcodes/index.md#quick-scan) +- [Notifications](../../part/notification.md) +- [User Menu](#user-menu) + +As well as allowing navigation to the following main sections: + +- [Parts](../../part/index.md) +- [Stock](../../stock/index.md) +- [Manufacturing](../../manufacturing/index.md) +- [Purchasing](../../purchasing/index.md) +- [Sales](../../sales/index.md) + +### Navigation Menu + +The global navigation menu is located on the left-hand side of the interface and provides access to the various sections of the system. + +{{ image("concepts/ui_navigation_menu.png", "Navigation Menu") }} + +The navigation menu is organized into several key areas, including: + +- **Navigation:** Provides access to the main sections of the system, including Parts, Stock, Manufacturing, Purchasing, and Sales. +- **Settings:** Quick access to user settings, system settings, and the admin center. +- **Actions:** Provides quick access to commonly used actions +- **Documentation:** Links to the online documentation. +- **About:** InvenTree version and license information. + +### User Menu + +The user menu is located in the top-right corner of the interface and provides access to user-specific settings and actions. + +{{ image("concepts/ui_user_menu.png", "User Menu") }} + +The user menu provides access to the following items: + +- **User Settings:** Access to [user settings](../../settings/user.md). +- **System Settings:** Access to [global settings](../../settings/global.md) settings. *Note: Access to system settings may be restricted based on user permissions.* +- **Admin Center:** Access to the [admin center](../../settings/admin.md#admin-center) for operational administration +- **Database Admin Interface:** Low level administration via the [Database Admin Interface](../../settings/db_admin.md). *Note: Access may be restricted based on user permissions.* +- **Change Color Mode:** Toggle between light and dark color modes. +- **About InvenTree:** View version and license information about InvenTree. +- **Logout:** Log out of the InvenTree system. + +### Page Panels + +Most detail pages views within InvenTree are organized into panels, which provide a structured layout for displaying information and actions related to the current page. + +Panels are arranged in a vertical stack on the left side of the page, with the main content area on the right. Each panel contains related information and actions, allowing users to easily navigate and interact with the content. + +{{ image("concepts/ui_panels.png", "Page Panels") }} + +#### Collapse Panels + +The panel sidebar can be collapsed to provide more space for the main content area. To collapse or expand the panel sidebar, click the collapse icon located at the bottom of the sidebar. To expand the sidebar again, click the expand icon that appears when the sidebar is collapsed. + +### Breadcrumbs + +On some pages, a breadcrumb navigation trail is provided at the top of the page, just below the main menu. Breadcrumbs provide a visual representation of the user's current location within the system and allow for easy navigation back to previous pages. + +{{ image("concepts/ui_breadcrumbs.png", "Breadcrumb Navigation") }} + +#### Filtered Detail Navigation + +When a detail page is opened from a table that supports detail navigation, the breadcrumb bar can show the current position in the table result set together with Previous and Next buttons. The navigation uses the table's active filters and sort order, so moving between records follows the same list the user was viewing. + +The navigation context is stored in the detail URL. This makes links shareable and allows the same filtered result set to be restored when the link is opened in a fresh browser context. The position indicator uses the full result count, while the buttons are hidden at the first and last records. + +The navigation controls also work with detail pages provided by frontend plugins that use the standard table and page components. + +### Navigation Tree + +On some pages, a navigation tree is provided on the left-hand side of the page, next to the breadcrumbs. The navigation tree provides a hierarchical view of the current section of the system, allowing users to quickly navigate to related pages and sections. + +Click on the navigation tree icon to expand the tree and view the available navigation options: + +{{ image("concepts/ui_navigation_tree.png", "Navigation Tree") }} + +#### Searching + +The navigation tree includes a search bar at the top of the panel. Typing into the search bar filters the tree to show only entries that match the search query. When a search is active, all matching results are expanded and displayed in a flat list. Clearing the search field returns the tree to its normal browsing mode. + +#### Highlight Selected Entry + +The currently selected entry in the navigation tree is highlighted with a distinct background color, making it easy to identify the active page or section within the hierarchy. + +#### Auto-Expand to Selected Entry + +When the navigation tree is opened, it automatically expands to reveal the currently selected entry. All ancestor nodes in the hierarchy are expanded so the active entry is immediately visible, without requiring manual navigation through the tree. + +## Dashboard + +The dashboard provides a customizable landing page for users when they log in to the system. The dashboard can be configured to display a variety of widgets and information panels, providing users with quick access to important data and actions. + +{{ image("concepts/ui_dashboard.png", "Dashboard") }} + +### Editing Layout + +To edit the layout (add, remove, or rearrange widgets) of the dashboard, open the dashboard context menu (located at the top-right corner of the dashboard) and view the available options: + +{{ image("concepts/ui_dashboard_edit.png", "Dashboard Context Menu") }} + +### Custom Widgets + +In addition to the set of built-in widgets provided by InvenTree, custom dashboard widgets can be implemented using [plugins](../../plugins/mixins/ui.md#dashboard-items). This allows users to create personalized dashboard experiences tailored to their specific needs and workflows. + +## Tables + +Information throughout the InvenTree interface is often presented in tabular format. Table views support a wide range of features, including pagination, sorting, filtering, and data export. + +Read more about working with table views on the dedicated [Tables](./tables.md) page. + +## Preview Panels + +Rather than navigating directly to an item's detail page, clicking on a table row can instead open a "preview" drawer, providing a quick summary of that item without leaving the current view. + +Read more about this optional feature on the dedicated [Preview Panels](./preview_panels.md) page. + +## Forms + +Data entry and editing within InvenTree is typically performed through the use of forms, which provide a structured interface for inputting and modifying data. + +Read more about working with forms on the dedicated [Forms](./forms.md) page. + +## Global Search + +Accessible from the [main menu](#main-menu), the global search functionality allows users to quickly find specific items or information within the InvenTree system. + +Read more about the global search feature on the dedicated [Global Search](./global_search.md) page. + +## Spotlight + +The user interface features a "spotlight" search functionality, which provides a quick and efficient way to access common actions or navigate to specific pages within the InvenTree system. The spotlight search is designed to enhance user productivity by allowing users to quickly find and execute actions without needing to navigate through menus or remember specific page locations. + +{{ image("concepts/ui_spotlight.png", "Spotlight Search") }} + +### Open Spotlight + +To open the "spotlight" search, click on the "spotlight" icon located in the main menu at the top of the interface. This will open the spotlight search menu, allowing you to enter search queries and view available actions. + +Alternatively, the spotlight search can be opened using the keyboard shortcut `Ctrl + K` (or `Cmd + K` on macOS), providing a quick and convenient way to access the spotlight functionality without needing to click on the menu icon. + +### Disable Spotlight + +Users may opt to disable the spotlight search functionality if they do not find it useful or prefer not to use it. To disable the spotlight search, navigate to your [user settings](../../settings/user.md) and locate the option to disable the spotlight feature. Once disabled, the spotlight search will no longer be accessible from the main menu or via keyboard shortcuts. + +## Copy Button + +Many fields within the InvenTree user interface include a "copy" button, which allows users to quickly copy the value of that field to their clipboard. This is particularly useful for fields that contain important identifiers, such as part numbers, stock item codes, or other relevant data that may need to be easily copied and pasted elsewhere. + +!!! important "Secure Context" + The "copy" button functionality relies on the browser's clipboard API, which may not be available in all contexts (e.g. if the user is accessing the InvenTree interface via a non-https connection, or through an embedded iframe or a non-standard browser). In such cases, the "copy" button may not function as intended. + +## User Permissions + +Many aspects of the user interface are controlled by user permissions, which determine what actions and features are available to each user based on their assigned roles and permissions within the system. This allows for a highly customizable user experience, where different users can have access to different features and functionality based on their specific needs and responsibilities within the organization. + +If a user does not have permission to access a particular feature or section of the system, that feature will be hidden from their view in the user interface. This helps to ensure that users only see the features and information that are relevant to their role, reducing clutter and improving usability. + +## Language Support + +The InvenTree user interface supports multiple languages, allowing users to interact with the system in their preferred language. + +The default system language can be configured by the system administrator in the [server configuration options](../../start/config.md#basic-options). + +Additionally, users can select their preferred language in their [user settings](../../settings/user.md), allowing them to override the system default language with their own choice. This provides a personalized experience for each user, ensuring that they can interact with the system in the language they are most comfortable with. diff --git a/docs/docs/concepts/ui/preview_panels.md b/docs/docs/concepts/ui/preview_panels.md new file mode 100644 index 0000000000..1f16485417 --- /dev/null +++ b/docs/docs/concepts/ui/preview_panels.md @@ -0,0 +1,37 @@ +--- +title: Preview Panels +--- + +## Preview Panels + +Many [table views](./tables.md) in InvenTree link each row to the detail page for the underlying item. By default, clicking on a row navigates directly to that detail page. + +If the preview panel feature is enabled, clicking on a row instead opens a "preview" drawer on the right-hand side of the screen. The preview drawer displays a summary of the selected item, without navigating away from the current table view. + +{{ image("concepts/ui_preview_drawer.png", "Preview Drawer") }} + +## Enabling the Preview Panel + +The preview panel is disabled by default. It can be enabled on a per-user basis via the **Table Preview Panel** option, found in the *Display Options* tab of the [user settings](../../settings/user.md) page. + +## Using the Preview Panel + +Once enabled, clicking on a row in a supported table opens the preview drawer for that item, rather than navigating to its detail page. + +### Viewing Full Details + +The preview drawer title includes an arrow icon, linking to the full detail page for the previewed item. Click on the title (or the arrow icon) to navigate to the detail page and close the drawer. + +{{ image("concepts/ui_preview_details_link.png", "View Details Link") }} + +### Following Links + +Any link within the preview drawer (for example, a link to a related part or category) can be clicked to navigate directly to that page. The preview drawer closes automatically when a link is followed. + +### Bypassing the Preview + +To navigate directly to an item's detail page without opening the preview drawer, hold `Ctrl` (or `Cmd` on macOS) while clicking the row, or middle-click the row to open the detail page in a new tab. + +### Closing the Preview + +The preview drawer can be closed by clicking the close button, clicking outside the drawer, or pressing `Escape`. diff --git a/docs/docs/concepts/ui/tables.md b/docs/docs/concepts/ui/tables.md new file mode 100644 index 0000000000..a1ba89e020 --- /dev/null +++ b/docs/docs/concepts/ui/tables.md @@ -0,0 +1,149 @@ +--- +title: Tables +--- + +## Table Views + +Information throughout the InvenTree interface is often presented in tabular format, allowing users to easily view and interact with large datasets. Tables are designed to be flexible and customizable, providing a range of features to enhance the user experience. + +{{ image("concepts/ui_table.png", "Table View") }} + +### Pagination + +The pagination controls are located at the bottom of the table, allowing users to navigate through large datasets by moving between pages. Users can also adjust the number of rows displayed per page using the pagination settings. + +### Row Selection + +For tables where data selection is supported, a checkbox is provided at the left-hand side of each row, allowing users to select one or more rows for further actions. A master checkbox is also provided in the table header, allowing users to quickly select or deselect all rows in the table. + +!!! info "Pagination and Row Selection" + When using the "master select" checkbox to select all rows, only the rows on the current page will be selected. + +{{ image("concepts/ui_table_row_selection.png", "Row Selection") }} + +### Table Actions + +A particular table view may have a set of actions associated with it, which are typically located at the top-left corner of the table. These actions may include options for adding new entries, or performing bulk actions on [selected rows](#row-selection). + +{{ image("concepts/ui_table_actions.png", "Table Actions") }} + +### Searching + +Some tables support searching, allowing users to quickly find specific entries within the dataset. The search bar is located at the top-right corner of the table view: + +{{ image("concepts/ui_table_search.png", "Table Search") }} + +### Column Selection + +Some tables allow the user to toggle the visibility of certain columns to, enabling a more customized view of the data. + +Column selection is accessed via the "Select Columns" menu, located to the top-right of the table view: + +{{ image("concepts/ui_table_column_selection.png", "Column Selection") }} + +### Filtering + +The dataset (which is fetched dynamically from the server via an API request) can be filtered by providing query parameters to the API endpoint. + +Select the "table filters" button to open the filter selection menu + +{{ image("concepts/ui_table_filter_button.png", "Table Filter Button") }} + +{{ image("concepts/ui_table_filter_menu.png", "Table Filter Menu") }} + +Table filters are saved across browser sessions, allowing users to maintain their preferred filter settings when returning to the particular table view. + +#### Column Filters + +Many table columns expose an inline filter icon directly in the column header, providing a quick way to filter by that column without opening the full filter drawer. Columns that support filtering display a small filter icon alongside the column title. The icon is highlighted when a filter for that column is currently active, giving an at-a-glance indication of which columns have active filters. + +Clicking the icon opens a compact popover anchored to the column header: + +{{ image("concepts/ui_table_column_filter_popover.png", "Column Filter Popover") }} + +**Single-filter columns** — for columns linked to one filter (e.g. *Active*, *Has IPN*, *Status*), selecting a value immediately applies the filter and the popover closes automatically. + +**Range columns** — for columns that represent a range concept (e.g. *Start Date*, *Target Date*, *Creation Date*), the popover stays open and presents multiple controls — for example *before* and *after* date pickers — so both bounds can be set in a single interaction. + +Once a filter is active, the popover shows a badge with the current value and a remove button (red ×) instead of the value picker. Clicking the × clears only that column's filter. + +!!! info "Column filters and the filter drawer share the same state" + Filters applied via a column popover appear immediately in the filter drawer's active-filter list, and filters added through the drawer are reflected in the column icons. Clearing all filters from the drawer also removes any filters set via column popovers. + +#### Saved Filter Groups + +Frequently used combinations of filters can be saved as a named *filter group*, allowing them to be quickly recalled later without having to re-add each filter individually. + +The **Saved Filter Groups** panel is displayed at the bottom of the filter drawer. When one or more filters are active, a **Save current filters** button is available. Clicking it opens an inline name input — enter a name and press Enter (or click the confirm icon) to save the group. Press Escape or click the cancel icon to discard. + +{{ image("concepts/ui_table_filter_group.png", "Filter Groups") }} + +Previously saved filter groups are listed in the panel. Each entry shows the group name alongside two actions: + +- **Load** (green reload icon): Replaces the current active filters with the filters stored in that group. The table immediately re-fetches data using the restored filters. +- **Delete** (red × icon): Permanently removes the saved filter group. + +Saved filter groups are stored in the browser's local storage and are specific to each table or calendar view, so groups saved for one view are not available in another. They persist across local browser sessions until explicitly deleted. Filter groups are not shared to other devices. + +!!! info "Loading a filter group replaces active filters" + Loading a saved filter group replaces all currently active filters with those stored in the group. Any unsaved active filters will be overwritten. + +### Data Sorting + +Some table columns support data sorting, allowing the dataset to be sorted in ascending or descending order based on the values in that column. To sort a column, click on the column header. Clicking the column header again will toggle the sort order between ascending and descending. The current sort order is indicated by an arrow icon in the column header. + +{{ image("concepts/ui_table_sorting.png", "Data Sorting") }} + +### Data Export + +Some tables support downloading of the dataset in various formats (e.g. CSV, Excel, PDF). If data download is available for a given table, the "export data" button will be located at the top-right corner of the table view. + +This opens the "Export Data" form, which allows the user to select the desired file format for download, as well as any additional options related to the data export. + +{{ image("concepts/ui_table_download.png", "Data Download") }} + +### Row Actions + +In some tables, there may be specific actions associated with individual rows, allowing users to perform actions directly on a particular entry in the dataset. Row actions are typically accessed via an "actions" menu located at the right-hand side of each row. + +{{ image("concepts/ui_table_row_actions.png", "Row Actions") }} + +### Right-Click Context Menu + +For rows that support row actions, a right-click context menu is also available, providing quick access to the same set of actions without needing to click on the "actions" menu. + +{{ image("concepts/ui_table_context_menu.png", "Right-Click Context Menu") }} + +### Row Navigation + +For tables which reference other objects within the system, clicking on a row will navigate to the detail page for that particular entry. For example, clicking on a row in the "Part" table will navigate to the detail page for that specific part. + +If the [preview panel](./preview_panels.md) feature is enabled, clicking on a row instead opens a preview drawer for that entry, rather than navigating directly to its detail page. + +## Calendar Views + +Some [table views](#table-views) associated with various order types can be switched to a calendar view, which provides a visual representation of data based on date fields. The calendar view allows users to easily see and interact with data that is organized by date, such as scheduled tasks, events, or deadlines. + +To switch to the "calendar view" (for a table which supports it), click on the "calendar view" button located above and to the right of the table view: + +{{ image("concepts/ui_calendar_select.png", "Calendar View Button") }} + +This will display the data in a calendar format: + +{{ image("concepts/ui_calendar_view.png", "Calendar View") }} + +### Calendar Horizon + +The calendar view provides a configurable "horizon" setting, which allows users to adjust the number of months displayed in the calendar view. + +## Parametric Views + +Some [table views](#table-views) can be switched to a parametric view, which provides a visual representation of data based on specific parameters or attributes. The parametric view allows users to easily see and interact with data that is organized by certain characteristics, such as categories, types, or other relevant attributes. + +To switch to the "parametric view" (for a table which supports it), click on the "parametric view" button located above and to the right of the table view: + +{{ image("concepts/ui_parametric_select.png", "Parametric View Button") }} + +This will display the data in a parametric format: + +{{ image("concepts/ui_parametric_view.png", "Parametric View") }} diff --git a/docs/docs/develop/contributing.md b/docs/docs/develop/contributing.md index d2b2d2abe6..c27d1d5801 100644 --- a/docs/docs/develop/contributing.md +++ b/docs/docs/develop/contributing.md @@ -60,15 +60,17 @@ invoke dev.setup-dev InvenTree roughly follow the [GitLab flow](https://about.gitlab.com/topics/version-control/what-are-gitlab-flow-best-practices/) branching style, to allow simple management of multiple tagged releases, short-lived branches, and development on the main branch. There are nominally 5 active branches: -- `master` - The main development branch -- `stable` - The latest stable release -- `next-breaking` - The next breaking release (e.g. 2.0, 3.0) with all deprecated features removed -- `l10n` - Translation branch: Source to Crowdin -- `l10_crowdin` - Translation branch: Source from Crowdin -- `y.y.x` - Release branch for the currently supported version (e.g. `0.5.x`) -All other branches are removed periodically by maintainers or core team members. This includes old release branches. -Do not use them as base for feature development or forks as patches from them might not be accepted without rebasing. +| Branch | Description | +| --- | --- | +| `master` | The main development branch | +| `stable` | The latest stable release | +| `next-breaking` | The next breaking release (e.g. 2.0, 3.0) with all deprecated features removed | +| `l10n` | Translation branch: Source to Crowdin | +| `l10_crowdin` | Translation branch: Source from Crowdin | +| `y.y.x` | Release branch for the currently supported version (e.g. `0.5.x`) | + +All other branches are removed periodically by maintainers or core team members. This includes old release branches. Do not use them as base for feature development or forks as patches from them might not be accepted without rebasing. ### Version Numbering @@ -182,7 +184,7 @@ django-upgrade --target-version {{ config.extra.django_version }} `find . -name ## Migration Files -Any required migration files **must** be included in the commit, or the pull-request will be rejected. If you change the underlying database schema, make sure you run `invoke migrate` and commit the migration files before submitting the PR. +Any required migration files **must** be included in the commit, or the pull-request will be rejected. If you change the underlying database schema, make sure you run `invoke migrate --detect` and commit the migration files before submitting the PR. *Note: A github action checks for unstaged migration files and will reject the PR if it finds any!* diff --git a/docs/docs/faq.md b/docs/docs/faq.md index 7f2b2c79a0..cd2c7c3971 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -35,7 +35,7 @@ If the installed version of invoke is too old, users may see error messages duri Make sure you are running a stable or production release of InvenTree. The frontend panel is not included in development releases. More Information: [Error Codes - INVE-E1](./settings/error_codes.md#inve-e1) -### No module named +### No module named xyz During the install or update process, you may be presented with an error like: @@ -196,13 +196,33 @@ This means that either: In either case, ensure that the directory is available *on your local machine* and the user account has the required permissions. +### Running on a Non-Standard Port / Behind an Existing Reverse Proxy + +If you want to serve InvenTree on a port other than 80/443 (for example, because those ports are already used by another service on your host), or you want to place InvenTree behind an existing reverse proxy which already handles SSL for other services, refer to: + +- [Proxy (external) port configuration](./start/docker_install.md#proxy-external-port) - the `INVENTREE_HTTP_PORT` / `INVENTREE_HTTPS_PORT` variables +- [Integrating with an existing reverse proxy](./start/processes.md#integrating-with-existing-proxy) - a worked example, including the required `INVENTREE_TRUSTED_ORIGINS` setting + +!!! tip "Automatic HTTPS" + The bundled Caddy proxy's [Automatic HTTPS](./start/docker.md#ssl-certificates) only works if it is reachable on the standard ports 80/443, for the Let's Encrypt ACME challenge. If that is not the case for your setup, terminate SSL at your external proxy instead. + ## Error Rendering Component -Sometimes, following a software update, you may find that certain components of the web interface are not rendering correctly, and presented with a message similar to the screenshow below: +Sometimes, following a software update, you may find that certain components of the web interface are not rendering correctly, and presented with a message similar to the screenshot below: {{ image("faq/boundary.png", "Error Rendering Component") }} This is often due to a caching issue with your web browser. Try performing a hard refresh of the page to clear the cache, this should resolve the issue in most cases. If the problem persists, refer to the [troubleshooting guide](./troubleshooting.md) for further assistance. + +## Expression tree is too large + +If you are running a large InvenTree deployment on an SQLite database, you may encounter an error similar to: + +``` +Expression tree is too large (maximum depth 1000) +``` + +This is a [known limitation of SQLite](https://www.sqlite.org/limits.html) which can occur when performing complex queries on a large database. Due to [structural limitations](./start/processes.md#sqlite-limitations) of SQLite, it is recommended to use a more robust database backend such as PostgreSQL for larger deployments. diff --git a/docs/docs/hooks.py b/docs/docs/hooks.py index b038738565..fc1f98e4a0 100644 --- a/docs/docs/hooks.py +++ b/docs/docs/hooks.py @@ -4,10 +4,10 @@ import json import os import re from datetime import datetime -from distutils.version import StrictVersion # type: ignore[import] from pathlib import Path import requests +from packaging.version import Version here = Path(__file__).parent @@ -57,7 +57,7 @@ def fetch_rtd_versions(): print('No RTD token found - skipping RTD version fetch') # Sort versions by version number - versions = sorted(versions, key=lambda x: StrictVersion(x['version']), reverse=True) + versions = sorted(versions, key=lambda x: Version(x['version']), reverse=True) # Add "latest" version first if not any(x['title'] == 'latest' for x in versions): diff --git a/docs/docs/manufacturing/allocate.md b/docs/docs/manufacturing/allocate.md index 4594e85839..ca20217b62 100644 --- a/docs/docs/manufacturing/allocate.md +++ b/docs/docs/manufacturing/allocate.md @@ -35,10 +35,12 @@ A [Bill of Materials](./bom.md) to generate an assembly may consist of a mixture ### Tracked Build Outputs -If a Build Order is created for an assembled part which is itself designed as *trackable*, some extra restrictions apply: +If the [BOM](./bom.md) for the assembled part contains one or more *tracked* (trackable) components, some extra restrictions apply when creating build outputs: -- Build outputs must be single quantity -- Build outputs must be serialized as they are created +- Serial numbers *must* be provided when the build output is created - this allows the tracked sub-components to be allocated against a specific unit +- Each generated build output is single quantity (one output per serial number) + +If the assembled part itself is *trackable*, but the BOM does not contain any tracked components, serial numbers are *not* required at the point of creation - a single build output may be created with a batch quantity, and [serialized later](../part/trackable.md#build-outputs-without-serial-numbers). ## Allocating Untracked Stock @@ -80,7 +82,16 @@ The *Deallocate Stock* button can be used to remove all allocations of untracked ## Automatic Stock Allocation -To speed up the allocation process, the *Auto Allocate* button can be used to allocate untracked stock items to the build. Automatic allocation of stock items does not work in every situation, as a number of criteria must be met. +To speed up the allocation process, the *Auto Allocate* button can be used to automatically allocate stock items to the build. + +!!! info "Background Task" + Auto-allocation runs as a background task. The UI will display a progress indicator while the task is running. + +#### Selecting Lines to Allocate + +By default, auto-allocation processes **all eligible BOM line items** in the build order. To restrict allocation to a subset of lines, select the desired rows in the allocation table before pressing the button — the dialog will indicate how many lines are selected. + +#### Auto Allocation Options The *Automatic Allocation* dialog is presented as shown below: @@ -90,12 +101,16 @@ The *Automatic Allocation* dialog is presented as shown below: Select the master location where stock items are to be allocated from. Leave this input blank to allocate stock items from any available location. +**Exclude Location** + +Exclude stock from a specific location (and all of its sub-locations). Useful for reserving stock in a particular area. + **Interchangeable Stock** Set this option to *True* to signal that stock items can be used interchangeably. This means that in the case where multiple stock items are available, the auto-allocation routine does not care which stock item it uses. !!! warning "Take Care" - If the *Interchangeable Stock* option is enabled, and there are multiple stock items available, the results of the automatic allocation algorithm may somewhat unexpected. + If the *Interchangeable Stock* option is enabled, and there are multiple stock items available, the results of the automatic allocation algorithm may be somewhat unexpected. !!! info "Example" Let's say that we have 5 reels of our *C_100nF_0603* capacitor, each with 4,000 parts available. If we do not mind which of these reels the stock should be taken from, we enable the *Interchangeable Stock* option in the dialog above. In this case, the stock will be allocated from one of these reels, and eventually subtracted from stock when the build is completed. @@ -104,6 +119,32 @@ Set this option to *True* to signal that stock items can be used interchangeably Set this option to *True* to allow substitute parts (as specified by the BOM) to be allocated, if the primary parts are not available. +**Optional Items** + +Set this option to *True* to include optional BOM line items in the auto-allocation. By default, optional items are not automatically allocated. + +**Item Type** + +Controls which category of BOM line items is considered for auto-allocation: + +| Option | Description | +| --- | --- | +| Untracked Items | Only untracked (non-serialized) BOM lines are allocated *(default)* | +| Tracked Items | Only tracked BOM lines are allocated | +| All Items | Both tracked and untracked BOM lines are allocated | + +**Stock Priority** + +Controls the order in which matching stock items are consumed: + +| Option | Description | +| --- | --- | +| Oldest stock first (FIFO) | Stock items updated least recently are consumed first *(default)* | +| Newest stock first (LIFO) | Stock items updated most recently are consumed first | +| Smallest quantity first | Stock items with the lowest available quantity are consumed first | +| Largest quantity first | Stock items with the highest available quantity are consumed first | +| Soonest expiry date first | Stock items expiring earliest are consumed first; items with no expiry date are used last | + ## Allocating Tracked Stock Allocation of tracked stock items is slightly more complex. Instead of being allocated against the *Build Order*, tracked stock items must be allocated against an individual *Build Output*. diff --git a/docs/docs/manufacturing/bom.md b/docs/docs/manufacturing/bom.md index 7e82cb68a5..e69d4b6195 100644 --- a/docs/docs/manufacturing/bom.md +++ b/docs/docs/manufacturing/bom.md @@ -22,6 +22,7 @@ A BOM for a particular assembly is comprised of a number (zero or more) of BOM " | Quantity | The quantity of *Part* required for the assembly - this value is automatically calculated from the "raw amount" field, taking into account the units of measure associated with the underlying part. | | Attrition | Estimated attrition losses for a production run. Expressed as a percentage of the base quantity (e.g. 2%) | | Setup Quantity | An additional quantity of the part which is required to account for fixed setup losses during the production process. This is added to the base quantity of the BOM line item | +| Piece Count | The number of individual pieces required per assembly (for cut-to-length items). Defaults to 1. Total material = quantity x piece_count. | | Rounding Multiple | A value which indicates that the required quantity should be rounded up to the nearest multiple of this value. | | Consumable | A boolean field which indicates whether this BOM Line Item is *consumable* | | Inherited | A boolean field which indicates whether this BOM Line Item will be "inherited" by BOMs for parts which are a variant (or sub-variant) of the part for which this BOM is defined. | @@ -40,6 +41,45 @@ If the underlying part does not have a defined unit of measure, the `raw_amount` The `raw_amount` field also allows for fractional representation of the required quantity. For example, if the required quantity is 0.5 kg, the user can specify this as `500 g`, `0.5 kg`, `1/2 kg`, etc. The `quantity` field will be automatically calculated as 0.5 kg, regardless of the specific representation used in the `raw_amount` field. +### Piece Count (Cut-to-Length Parts) + +The `piece_count` field supports scenarios where a material is cut or divided into multiple identical pieces for each assembly. This is common for cables, wires, tubing, extrusions, and similar length-based materials. + +When `piece_count` is greater than 1, the `quantity` field represents the size or length of each individual piece, and `piece_count` indicates how many such pieces are needed per assembly. The total material required is calculated as: + +``` +Total material = quantity x piece_count x build_quantity +``` + +#### Example: Wire Harness Assembly + +Consider an assembly that requires 10 pieces of wire, each cut to 200mm length: + +| Field | Value | Description | +| --- | --- | --- | +| Quantity | 200 (mm) | Length of each individual wire piece | +| Piece Count | 10 | Number of wire pieces per assembly | +| Build Quantity | 5 | Number of assemblies to build | +| **Total Required** | **10,000 mm (10m)** | 200 x 10 x 5 = 10,000 mm | + +#### Example: Tubing for Hydraulic System + +An assembly requires 4 pieces of tubing, each 500mm long, with 5% attrition: + +| Field | Value | Description | +| --- | --- | --- | +| Quantity | 500 (mm) | Length of each tube section | +| Piece Count | 4 | Number of tube pieces per assembly | +| Build Quantity | 3 | Number of assemblies to build | +| Attrition | 5% | Account for cutting waste | +| **Total Required** | **6,300 mm (6.3m)** | (500 x 4 x 3) x 1.05 = 6,300 mm | + +!!! note "Default Behavior" + When `piece_count` is left at its default value of 1, the BOM line item behaves exactly as it did before this feature was introduced. Existing BOMs are unaffected. + +!!! tip "When to Use Piece Count" + Use `piece_count` when you are cutting or dividing a material into multiple identical pieces. If each piece has a different length, create separate BOM line items instead. + ### Consumable BOM Line Items If a BOM line item is marked as *consumable*, this means that while the part and quantity information is tracked in the BOM, this line item does not get allocated to a [Build Order](./build.md). This may be useful for certain items that the user does not wish to track through the build process, as they may be low value, in abundant stock, or otherwise complicated to track. @@ -50,6 +90,8 @@ In the example below, see that the *Wood Screw* line item is marked as consumabl Further, in the [Build Order](./build.md) stock allocation table, we see that this line item cannot be allocated, as it is *consumable*. +Marking a BOM line item as consumable is a per-assembly override - it only affects how the part is treated within *this* particular BOM, and does not change the underlying part definition. A part can also be marked as consumable directly - refer to the [consumable parts documentation](../part/consumable.md) for more information on the distinction between the two, and reasons why a part may be marked as consumable. + ### Optional BOM Line Items If a BOM line item is marked as *optional*, this means that the part and quantity information is tracked in the BOM, but this line item is not required to be allocated to a [Build Order](./build.md). This may be useful for certain items which are not strictly required for the build process to be completed. @@ -163,6 +205,7 @@ The following BOM item fields are used when calculating the BOM checksum: - *Attrition* - The attrition percentage of the BOM line item. - *Setup Quantity* - The setup quantity of the BOM line item. - *Rounding Multiple* - The rounding multiple of the BOM line item. +- *Piece Count* - The number of pieces required per assembly (for cut-to-length items). - *Consumable* - Whether the BOM line item is consumable. - *Inherited* - Whether the BOM line item is inherited. - *Optional* - Whether the BOM line item is optional. diff --git a/docs/docs/manufacturing/external.md b/docs/docs/manufacturing/external.md index 2ad0d04655..12de800623 100644 --- a/docs/docs/manufacturing/external.md +++ b/docs/docs/manufacturing/external.md @@ -65,6 +65,8 @@ Once the purchase order has been created, add the assembly part to the purchase Follow the normal process for receiving items against the purchase order. When the items are received from the external supplier, they will be marked as "build outputs" against the external build order. +If the assembled part is [trackable](../part/trackable.md), [serial numbers](../purchasing/purchase_order.md#serial-numbers) may optionally be entered at the point of receipt - or the items can be received without serial numbers, and [serialized later](../part/trackable.md#build-outputs-without-serial-numbers). + {{ image("build/external_build_receive_items.png", "Receive items against purchase order") }} The received items will now be registered as "incomplete outputs" against the external build order: diff --git a/docs/docs/manufacturing/index.md b/docs/docs/manufacturing/index.md index 433f375e38..711241004e 100644 --- a/docs/docs/manufacturing/index.md +++ b/docs/docs/manufacturing/index.md @@ -23,3 +23,9 @@ Read more about build orders in the [Build Order documentation](./build.md). InvenTree allows users to allocate stock items to specific build orders, ensuring that the required components are reserved for production. This helps to prevent stock shortages and ensures that the right parts are available when needed. Read more about stock allocation in the [Stock Allocation documentation](./allocate.md). + +### Disassembly + +The reverse process is also supported - an assembled stock item can be broken back down into its component parts, based on its BOM. This is useful for reworking or scrapping an assembly, or for splitting a bundled "kit" product purchased from a supplier into its individual components. + +Read more about this process in the [Stock Disassembly documentation](../stock/disassemble.md). diff --git a/docs/docs/manufacturing/output.md b/docs/docs/manufacturing/output.md index 018fc666dc..2f98c2ff16 100644 --- a/docs/docs/manufacturing/output.md +++ b/docs/docs/manufacturing/output.md @@ -35,7 +35,7 @@ The following options are available when creating a new build output: | Option | Description | | --- | --- | | Quantity | The number of items to create as part of this build output | -| Serial Numbers | If this is a tracked build output, the serial numbers for each of the generated outputs | +| Serial Numbers | Optional serial numbers for the generated outputs - see [below](#creating-outputs-without-serial-numbers) for when this field may be left blank | | Batch Code | Batch code identifier for the generated output(s) | | Auto Allocate Serial Numbers | If selected, any available tracked subcomponents which already have serial numbers assigned, will be automatically assigned to matching build outputs | @@ -43,6 +43,15 @@ The following options are available when creating a new build output: Refer to the [serial number generation guide](../stock/tracking.md#generating-serial-numbers) for further information on serial number input. +### Creating Outputs Without Serial Numbers + +Serial numbers are not required when creating a build output, even if the part being built is marked as [trackable](../part/trackable.md). This allows a batch quantity to be produced up-front - for example, a quantity of PCBs which will not be individually serialized until later in the manufacturing process, or units received into an [external build order](./external.md) which are not yet serialized. + +If the *Serial Numbers* field is left blank, a single build output is created with the specified *Quantity*, rather than one output per unit. This output remains a single (non-serialized) [stock item](../stock/index.md), which can be serialized at a later stage - for example, by splitting it into individual units and assigning serial numbers - before it is [completed](#complete-build-output). + +!!! note "Tracked BOM Items" + If the [Bill of Materials](./bom.md) for the assembled part contains tracked sub-components, serial numbers are still required when creating build outputs - see [tracked build outputs](./allocate.md#tracked-build-outputs) for further information. + ## Complete Build Output *Completing* a build output marks that output as finished, in the context of the given build order. diff --git a/docs/docs/part/consumable.md b/docs/docs/part/consumable.md new file mode 100644 index 0000000000..b9a60beae2 --- /dev/null +++ b/docs/docs/part/consumable.md @@ -0,0 +1,55 @@ +--- +title: Consumable Parts +--- + +## Consumable Parts + +A *Consumable* part is one which is generally used up, or expended, during a build or other process, rather than being tracked and allocated as a discrete item. + +Consumable parts can be used to represent things such as: + +- Glue or adhesive +- Solder +- Cleaning fluid +- Fasteners or other low-value hardware +- Other general workshop supplies + +Marking a part as consumable is intended to help distinguish these types of supplies from other parts in the inventory, making it easier to filter and report on "real" stock items versus general consumables. + +### Why Mark a Part as Consumable? + +Not every item required to complete a build needs to be tracked and allocated with the same rigor as a high-value component. A part might be marked as consumable because it is: + +- Low value, making the overhead of precise allocation not worth the effort +- Kept in abundant stock, such that running out is unlikely to be a concern +- Difficult to track in discrete units, such as a fluid or adhesive +- Not something the business needs (or wants) visibility into at the build order level + +Marking a part as consumable communicates this intent clearly wherever the part is used, without needing to remember to configure each individual BOM line item. + +### Stock Items + +Consumable parts can have stock items associated with them, the same as any other part. Stock levels for consumable parts can be tracked and managed as normal. + +### Bills of Material + +Consumable parts can be added as a subcomponent to the [Bills of Material](../manufacturing/bom.md) for an assembled part, in the same way as any other component. + +### Build Orders + +Unlike a regular component, a consumable part is not allocated to (or consumed by) a [Build Order](../manufacturing/build.md). When a build order is completed, stock quantities for consumable parts are not adjusted. + +If stock levels for a consumable part need to be updated to reflect usage during a build, this must be done manually. + +### Consumable BOM Line Items + +Separately from the *Consumable* flag on the part itself, an individual [BOM line item](../manufacturing/bom.md#consumable-bom-line-items) can also be marked as *consumable*. + +This allows a part which is **not** normally marked as consumable to be treated as consumable *for the purposes of a specific BOM*. For example, a fastener which is usually tracked precisely in one assembly might be treated as consumable in another assembly, without needing to change the underlying part definition. + +In other words: + +- The part-level *Consumable* flag is a permanent property of the part, and applies everywhere that part is used. +- The BOM line item *Consumable* flag is a per-assembly override, and only affects how that part is treated within that particular BOM. + +If a part is already marked as consumable, marking the corresponding BOM line item as consumable as well has no additional effect. diff --git a/docs/docs/part/create.md b/docs/docs/part/create.md index 842e2133e5..46f1c1d669 100644 --- a/docs/docs/part/create.md +++ b/docs/docs/part/create.md @@ -85,4 +85,4 @@ In addition to the primary methods for creating or importing part data, the foll - [Via the REST API](../api/index.md) - [Using the Python library](../api/python/index.md) -- [Within the Admin interface](../settings/admin.md) +- [Within the Database Admin interface](../settings/db_admin.md) diff --git a/docs/docs/part/index.md b/docs/docs/part/index.md index 1c7d048268..b3ca3f4994 100644 --- a/docs/docs/part/index.md +++ b/docs/docs/part/index.md @@ -53,6 +53,8 @@ A *Template* part is one which can have *variants* which exist underneath it. [R If a part is designated as an *Assembly* it can be created (or built) from other component parts. As an example, a circuit board assembly is made using multiple electronic components, which are tracked in the system. An *Assembly* Part has a Bill of Materials (BOM) which lists all the required sub-components. [Read further information about BOM management here](../manufacturing/bom.md). +An assembled stock item can also be broken back down into its component parts, using the [disassembly](../stock/disassemble.md) process. + ### Component If a part is designated as a *Component* it can be used as a sub-component of an *Assembly*. [Read further information about BOM management here](../manufacturing/bom.md) @@ -87,6 +89,9 @@ A [Purchase Order](../purchasing/purchase_order.md) allows parts to be ordered f If a part is designated as *Salable* it can be sold to external customers. Setting this flag allows parts to be added to sales orders. +### Consumable + +A *Consumable* part is one which is generally used up during a build or other process, rather than being tracked and allocated as a discrete item. Refer to the [consumable parts documentation](./consumable.md) for more information. ## Locked Parts diff --git a/docs/docs/part/notification.md b/docs/docs/part/notification.md index 7ca8d36aa3..33e131c347 100644 --- a/docs/docs/part/notification.md +++ b/docs/docs/part/notification.md @@ -7,7 +7,7 @@ title: Part Notifications Users can select to receive notifications when certain events occur. !!! warning "Email Configuration Required" - External notifications require correct [email configuration](../start/config.md#email-settings). They also need to be enabled in the settings under notifications`. + External notifications require correct [email configuration](../start/config.md#email-settings). They also need to be enabled in the settings under *Notifications*. !!! warning "Valid Email Address" Each user must have a valid email address associated with their account to receive email notifications diff --git a/docs/docs/part/pricing.md b/docs/docs/part/pricing.md index 1f19c82958..f11db486d5 100644 --- a/docs/docs/part/pricing.md +++ b/docs/docs/part/pricing.md @@ -51,7 +51,7 @@ Each price range is calculated in the [Default Currency](../concepts/pricing.md# Price range data is [cached in the database](#price-data-caching) when underlying pricing information changes. !!! tip "Refresh Pricing" - While pricing data is [automatically updated](#data-updates), the user can also manually refresh the pricing calculations manually, by pressing the "Refresh" button in the overview section. + While pricing data is [automatically updated](#pricing-updates), the user can also manually refresh the pricing calculations manually, by pressing the "Refresh" button in the overview section. #### Overall Pricing diff --git a/docs/docs/part/stocktake.md b/docs/docs/part/stocktake.md index a226587b91..f6067fb23c 100644 --- a/docs/docs/part/stocktake.md +++ b/docs/docs/part/stocktake.md @@ -41,7 +41,7 @@ If this tab is not visible, ensure that the *Enable Stock History* [user setting ### Stocktake Entry Generation -By default, stocktake entries are generated automatically at regular intervals (see [settings](#stock-history-settings) below). However, users can generate a stocktake entry on demand, using the *Generate Stocktake Entry* button in the *Stock History* tab: +By default, stocktake entries are generated automatically at regular intervals (see [settings](#stocktake-settings) below). However, users can generate a stocktake entry on demand, using the *Generate Stocktake Entry* button in the *Stock History* tab: {{ image("part/part_stocktake_manual.png", "Generate stocktake entry") }} @@ -95,7 +95,7 @@ Enable or disable stocktake functionality. Note that by default, stocktake funct ### Automatic Stocktake Period -Configure the number of days between generation of [automatic stocktake reports](#automatic-stocktake). If this value is set to zero, automatic stocktake reports will not be generated. +Configure the number of days between generation of [automatic stocktake entries](#stocktake-entry-generation). If this value is set to zero, automatic stocktake entries will not be generated. ### Delete Old Stocktake Entries diff --git a/docs/docs/part/trackable.md b/docs/docs/part/trackable.md index d833829929..7531bf7eeb 100644 --- a/docs/docs/part/trackable.md +++ b/docs/docs/part/trackable.md @@ -8,7 +8,9 @@ Denoting a part as *Trackable* changes the way that [stock items](../stock/index For many parts in an InvenTree database, simply tracking current stock levels (and locations) is sufficient. However, some parts require more extensive tracking than simple stock level knowledge. -Any stock item associated with a trackable part *must* have either a batch number or a serial number. This includes stock created manually or via an internal process (such as a [Purchase Order](../purchasing/purchase_order.md) or a [Build Order](../manufacturing/build.md)). +Generally, a stock item associated with a trackable part should have either a batch number or a serial number. This includes stock created manually or via an internal process (such as a [Purchase Order](../purchasing/purchase_order.md) or a [Build Order](../manufacturing/build.md)). + +However, this is not strictly enforced when creating a [build output](../manufacturing/output.md#create-build-output) - see [below](#build-orders) for further information. ## Assign Serial Numbers @@ -35,3 +37,12 @@ For example: ## Build Orders [Build orders](../manufacturing/build.md) have some extra requirements when either building a trackable part, or using parts in the Bill of Materials which are themselves trackable. + +### Build Outputs Without Serial Numbers + +When [creating a build output](../manufacturing/output.md#create-build-output) for a trackable part, serial numbers are *not* required at the point of creation. This allows a batch quantity of build outputs to be created up-front, and serialized at some later stage - for example, after receiving a batch of unserialized units against an [external build order](../manufacturing/external.md). + +If serial numbers are not provided, a single build output is created with the specified quantity, rather than one output per unit. This output can subsequently be assigned [serial numbers](#assign-serial-numbers), or split into individual serialized units, before it is completed. + +!!! note "Tracked BOM Items" + If the Bill of Materials for the part being built contains *tracked* (trackable) sub-components, serial numbers are still required when creating build outputs, regardless of whether the assembled part itself is trackable. This is necessary so that each tracked sub-component can be allocated against a specific build output. Refer to the [build allocation documentation](../manufacturing/allocate.md#tracked-build-outputs) for further information. diff --git a/docs/docs/part/views.md b/docs/docs/part/views.md index 8867c7a44e..e16e8c0b81 100644 --- a/docs/docs/part/views.md +++ b/docs/docs/part/views.md @@ -8,7 +8,7 @@ The Part detail view page provides a detailed view of a single part in the syste ### Category Breadcrumb List -The categories of each part is displayed on the top navigation bar as show in the above screenshot. +The categories of each part is displayed on the top navigation bar. [Click here](./index.md#part-category) for more information about categories. ## Part Details @@ -83,6 +83,10 @@ The *Build Orders* tab shows a list of the builds for this part. It provides a v The *Used In* tab displays a list of other parts that this part is used to make. This tab is only visible if the Part is a *component*. +### Part Pricing + +The *Part Pricing* tab displays all available pricing information for the part, aggregated from multiple sources (internal pricing, supplier pricing, purchase history, BOM pricing, sale pricing, etc). Refer to the [part pricing documentation](./pricing.md) for further information. + ### Suppliers The *Suppliers* tab displays all the *Part Suppliers* and *Part Manufacturers* for the selected *Part*. @@ -101,6 +105,14 @@ This tab is only displayed if the part is marked as *Purchaseable*. The *Sales Orders* tab shows a list of the sales orders for this part. It provides a view for important sales order information like customer, status, creation and shipment dates. +### Return Orders + +The *Return Orders* tab shows a list of the [return orders](../sales/return_order.md) which reference this part. This tab is only visible if the Part is marked as *Salable*, and the return order feature is enabled. + +### Transfer Orders + +The *Transfer Orders* tab shows a list of the [transfer orders](../stock/transfer_order.md) which reference this part. This tab is hidden if the Part is marked as *Virtual*, or the transfer order feature is not enabled. + ### Stock History The *Stock History* tab provide historical stock level information. Refer to the [stock history documentation](./stocktake.md) for further information. @@ -109,6 +121,10 @@ The *Stock History* tab provide historical stock level information. Refer to the If a part is marked as *testable*, the user can define tests which must be performed on any stock items which are instances of this part. [Read more about testing](./test.md). +### Test Results + +The *Test Results* tab displays [test result](../stock/test.md) data uploaded against *any* stock item of this part, aggregated into a single table. This differs from the *Test Templates* tab, which configures the tests themselves rather than displaying recorded results. This tab is only visible if the part is marked as *testable*. + ### Related Parts Related Part denotes a relationship between two parts, when users want to show their usage is "related" to another part or simply emphasize a link between two parts. diff --git a/docs/docs/plugins/creator.md b/docs/docs/plugins/creator.md index 39bee77aa8..74d4acd2b0 100644 --- a/docs/docs/plugins/creator.md +++ b/docs/docs/plugins/creator.md @@ -214,10 +214,10 @@ The frontend code for your plugin is located in the `frontend/src` directory. Yo Refer to the `./frontend/src/Panel.tsx` file as a starting point. This is where the custom panel for the part detail page is implemented. You can modify this file to change the content and behavior of the panel. -While the `npm dev` server is running, any changes you make to the frontend code will be automatically reloaded allowing for rapid development and testing of your plugin's frontend features. This avoids the need to rebuild the frontend code every time you make a change. +While the `npm dev` server is running, any changes to the frontend are reflected in the browser using React Fast Refresh, allowing for rapid development without rebuilding the frontend with every change. !!! info "Page Reload" - Due to the way the InvenTree frontend is structured, you will need to manually refresh the page in your browser to see changes to the frontend code. The development server will automatically reload the frontend code, but the InvenTree server needs to be aware of the changes. + All exports in plugin modules that export React components must start with a capital letter. Otherwise, React Fast Refresh will fall back to a full page reload instead of performing a component-level update. Additionally, any render functions referenced from Python must also be capitalized. ## Build Plugin diff --git a/docs/docs/plugins/develop.md b/docs/docs/plugins/develop.md index fb6bfbec57..4bbfccb7cb 100644 --- a/docs/docs/plugins/develop.md +++ b/docs/docs/plugins/develop.md @@ -113,10 +113,10 @@ Refer to the [sample plugins]({{ sourcedir("src/backend/InvenTree/plugin/samples A *PluginConfig* database entry will be created for each plugin "discovered" when the server launches. This configuration entry is used to determine if a particular plugin is enabled. -The configuration entries must be enabled via the [InvenTree admin interface](../settings/admin.md). +The configuration entries must be enabled via the [Admin Center](../settings/admin.md#admin-center). !!! warning "Disabled by Default" - Newly discovered plugins are disabled by default, and must be manually enabled (in the admin interface) by a user with staff privileges. + Newly discovered plugins are disabled by default, and must be manually enabled (in the Admin Center) by a user with staff privileges. ## Plugin Mixins diff --git a/docs/docs/plugins/mixins/barcode.md b/docs/docs/plugins/mixins/barcode.md index 962e36da31..3985990141 100644 --- a/docs/docs/plugins/mixins/barcode.md +++ b/docs/docs/plugins/mixins/barcode.md @@ -54,14 +54,14 @@ class InvenTreeBarcodePlugin(BarcodeMixin, InvenTreePlugin): VERSION = "0.0.1" AUTHOR = "Michael" - def scan(self, barcode_data): + def scan(self, barcode_data, user, **kwargs): if barcode_data.startswith("PART-"): try: pk = int(barcode_data.split("PART-")[1]) instance = Part.objects.get(pk=pk) label = Part.barcode_model_type() - return {label: instance.format_matched_response()} + return {label: instance.format_matched_response(user=user)} except Part.DoesNotExist: pass ``` diff --git a/docs/docs/plugins/mixins/report.md b/docs/docs/plugins/mixins/report.md index 09e6e9d89a..d424ce7155 100644 --- a/docs/docs/plugins/mixins/report.md +++ b/docs/docs/plugins/mixins/report.md @@ -4,15 +4,57 @@ title: Report Mixin ## ReportMixin -The `ReportMixin` class provides a plugin with the ability to extend the functionality of custom [report templates](../../report/report.md). A plugin which implements the ReportMixin mixin class can add custom context data to a report template for rendering. +The `ReportMixin` class provides a plugin with the ability to extend the functionality of custom [report templates](../../report/report.md). A plugin which implements the ReportMixin mixin class can add custom context data to a report template for rendering, and can also receive a callback when a report is generated. ### Add Report Context A plugin which implements the ReportMixin mixin can define the `add_report_context` method, allowing custom context data to be added to a report template at time of printing. +This method is called each time a report is generated, and is passed the following arguments: + +| Argument | Description | +| --- | --- | +| `report_instance` | The report template instance which is being rendered | +| `model_instance` | The model instance against which the report is being generated | +| `user` | The user who initiated the report generation | +| `context` | The context dictionary, which can be modified in-place | + +Any data added to the provided `context` dictionary is made available to the report template, and can be rendered using standard django template syntax: + +```python +def add_report_context(self, report_instance, model_instance, user, context): + """Add extra context data to the report template.""" + context['my_custom_data'] = self.calculate_custom_data(model_instance) +``` + ### Add Label Context -Additionally the `add_label_context` method, allowing custom context data to be added to a label template at time of printing. +Similarly, the `add_label_context` method allows custom context data to be added to a label template at time of printing: + +| Argument | Description | +| --- | --- | +| `label_instance` | The label template instance which is being rendered | +| `model_instance` | The model instance against which the label is being generated | +| `user` | The user who initiated the label generation | +| `context` | The context dictionary, which can be modified in-place | + +### Report Callback + +The `report_callback` method is called after a report has been generated, and allows the plugin to perform custom actions with the generated report - for example, forwarding the report to an external system, or performing custom post-processing. + +| Argument | Description | +| --- | --- | +| `template` | The report template instance which was used to generate the report | +| `instance` | The model instance against which the report was generated | +| `report` | The generated report (PDF file data) | +| `user` | The user who initiated the report generation | + +```python +def report_callback(self, template, instance, report, user, **kwargs): + """Custom callback function - called after a report is generated.""" + # For example, forward the generated report to an external service + self.upload_to_external_service(report) +``` ### Sample Plugin diff --git a/docs/docs/plugins/walkthrough.md b/docs/docs/plugins/walkthrough.md index af2d75885e..863e02a39b 100644 --- a/docs/docs/plugins/walkthrough.md +++ b/docs/docs/plugins/walkthrough.md @@ -74,7 +74,7 @@ npm install npm run build ``` -Copy the built `attachment_carousel` directory to the `inventree-data/plugins` directory and enable it via the admin interface. +Copy the built `attachment_carousel` directory to the `inventree-data/plugins` directory and enable it via the [Admin Center](../settings/admin.md#admin-center). ![Attachment Carousel in Inventree panel screenshot](../assets/images/plugin/plugin_walkthrough_default.png "Attachment Carousel in Inventree panel screenshot") @@ -119,7 +119,7 @@ function AttachmentCarouselPanel({context}: {context: InvenTreePluginContext;}) } // This is the function which is called by InvenTree to render the actual panel component -export function renderAttachmentCarouselPanel(context: InvenTreePluginContext) { +export function RenderAttachmentCarouselPanel(context: InvenTreePluginContext) { checkPluginVersion(context); return ; } @@ -300,7 +300,7 @@ Back to the walkthrough, open `core.py` in the `attachment_carousel` folder and 'title': 'Attachment Carousel', 'description': 'Custom panel description', 'icon': 'ti:carousel-horizontal:outline', - 'source': self.plugin_static_file('Panel.js:renderAttachmentCarouselPanel'), + 'source': self.plugin_static_file('Panel.js:RenderAttachmentCarouselPanel'), 'context': { # Provide additional context data to the panel 'settings': self.get_settings_dict(), @@ -385,7 +385,7 @@ panels.append({ 'description': 'Custom panel description', - 'icon': 'ti:mood-smile:outline', + 'icon': 'ti:carousel-horizontal:outline', - 'source': self.plugin_static_file('Panel.js:renderAttachmentCarouselPanel'), + 'source': self.plugin_static_file('Panel.js:RenderAttachmentCarouselPanel'), 'context': { # Provide additional context data to the panel 'settings': self.get_settings_dict(), @@ -519,7 +519,7 @@ panels.append({ 'title': 'Attachment Carousel', 'description': 'Custom panel description', 'icon': 'ti:carousel-horizontal:outline', - 'source': self.plugin_static_file('Panel.js:renderAttachmentCarouselPanel'), + 'source': self.plugin_static_file('Panel.js:RenderAttachmentCarouselPanel'), 'context': { # Provide additional context data to the panel 'settings': self.get_settings_dict(), diff --git a/docs/docs/project/resources.md b/docs/docs/project/sponsored_resources.md similarity index 83% rename from docs/docs/project/resources.md rename to docs/docs/project/sponsored_resources.md index 9074d17818..4c206bcc06 100644 --- a/docs/docs/project/resources.md +++ b/docs/docs/project/sponsored_resources.md @@ -1,5 +1,5 @@ --- -title: Resources InvenTree receives +title: Sponsored Resources --- The InvenTree project is grateful to receive resources from various vendors free of charge. @@ -14,9 +14,12 @@ Individuals and companies can also support via [GitHub sponsors](https://github. - [Codecov](https://codecov.io) - Code coverage as a service, used to track the code coverage of the various components - [Netlify](https://www.netlify.com/) - Static site hosting provider, used to test deploy the frontend and website - [Depot](https://depot.dev/?utm_source=inventree) - Docker build accelerator, used to build the multi-arch images for the InvenTree docker image + - [CodSpeed](https://codspeed.io/) - Performance testing platform, used to track the performance of a few performance benchmarks +- [Flakiness](https://flakiness.io/) - Frontend test flakiness detection, used to track the flakiness of the various test harnesses ## Past Supporters Non comprehensive list of past supporters. The project stops consuming resources for various reasons, this does not mean they are not good resources. + - [Coveralls](https://coveralls.io/) - Code coverage as a service - [Deepsource](https://deepsource.io/) - Code quality and security analysis diff --git a/docs/docs/purchasing/purchase_order.md b/docs/docs/purchasing/purchase_order.md index 89d6a9194c..e7654e7159 100644 --- a/docs/docs/purchasing/purchase_order.md +++ b/docs/docs/purchasing/purchase_order.md @@ -92,6 +92,12 @@ Once the "Add Line Item" form opens, select a supplier part in the list. Fill out the rest of the form then click on Submit +!!! info "Auto Pricing" + Enable the *Auto Pricing* option to automatically calculate the line item's *Unit Price* from the [supplier part pricing data](../part/pricing.md#supplier-pricing), based on the line item quantity. While enabled, the *Unit Price* field is calculated automatically and cannot be edited manually. This option is disabled by default. + +!!! info "Discount" + An optional [discount](../concepts/pricing.md#line-item-discount) percentage can be applied to each line item. + #### Upload File It is possible to upload an exported purchase order from the supplier instead of manually entering each line item. To start the process, click on {{ icon("upload") }} Upload File button next to the {{ icon("plus-circle") }} Add Line Item button and follow the steps. @@ -99,6 +105,10 @@ It is possible to upload an exported purchase order from the supplier instead of !!! info "Supported Formats" This process only supports tabular data and the following formats are supported: CSV, TSV, XLS, XLSX, JSON and YAML +### Extra Line Items + +While [line items](#add-line-items) must reference a particular supplier part, extra line items are available for any other itemized information that needs to be conveyed with the order - for example freight charges or service fees. Extra line items support an optional [discount](../concepts/pricing.md#line-item-discount) percentage, the same as regular line items. + ## Issue Order Once all the line items were added, click on the {{ icon("send", title="Issue") }} button on the main purchase order detail panel and confirm the order has been submitted. @@ -129,12 +139,34 @@ Each item marked as "received" is automatically converted into a stock item. To see the list of stock items created from the purchase order, click on the {{ icon("arrow-right") }} Received Items tab. +### Serial Numbers + +If the part being received is [trackable](../part/trackable.md), serial numbers can optionally be entered at the point of receipt. If provided, an individual (serialized) stock item is created for each unit received. + +Serial numbers are *not* required to receive a trackable part - if left blank, a single (non-serialized) stock item is created for the received quantity. This is useful, for example, when receiving a batch of units against an [external build order](../manufacturing/external.md) which will be [serialized later](../part/trackable.md#build-outputs-without-serial-numbers) in the manufacturing process. + ### Item Value Currency The unit cost of the purchase order line item is transferred across to the created stock item. By default, the same currency is used for the stock item as was used for the purchase order line item. However, if the [Convert Currency](#purchase-order-settings) setting is enabled, the currency of the stock item will be converted to the [default currency](../concepts/pricing.md#default-currency) of the system. This may be useful when ordering stock in a different currency, to ensure that the unit cost of the stock item is converted to the base currency at the time of receipt. +## Bundled Items + +Some suppliers only sell a group of components as a single bundled or "kit" product, rather than as individual purchasable line items - for example, a fastener kit containing an assortment of different screws, or a "starter kit" containing several components required for a particular use case. + +Rather than receiving the bundle as a single opaque stock quantity, InvenTree allows the bundle to be modelled as an assembly, so that it can be broken apart into its individual components once required: + +1. Create a part to represent the bundle itself, and mark it as an [assembly](../part/index.md#assembly) +2. Link a [supplier part](./supplier.md#supplier-parts) to the bundle part, representing how it is purchased from the supplier +3. Define a [Bill of Materials](../manufacturing/bom.md) for the bundle part, listing each of the individual components and the quantity contained within a single bundle +4. Create and receive a purchase order against the bundle's supplier part, as normal - a single stock item is created for the bundle, retaining the purchase price and source purchase order of the order as a whole + +Once the individual components are actually required, the received bundle stock item can be [disassembled](../stock/disassemble.md) into its component parts. The purchase price and traceability data (batch code, source purchase order) of the original bundle are automatically apportioned across the newly generated component stock items. + +!!! tip "Pack Size vs Bundled Items" + A supplier part with a [pack size](./supplier.md#supplier-part-pack-size) greater than one still represents multiple units of the *same* part - the pack size simply determines how many physical units are added to stock per unit ordered. A *bundled* item is different: a single supplier part represents an assortment of *different* components, which must be disassembled before the individual components can be used or sold separately. + ## Complete Order Once the quantity of all __received__ items is equal or above the quantity of all line items, the order will be automatically marked as __complete__. @@ -199,3 +231,4 @@ The following [global settings](../settings/global.md) are available for purchas {{ globalsetting("PURCHASEORDER_CONVERT_CURRENCY") }} {{ globalsetting("PURCHASEORDER_EDIT_COMPLETED_ORDERS") }} {{ globalsetting("PURCHASEORDER_AUTO_COMPLETE") }} +{{ globalsetting("PURCHASEORDER_MERGE_LINE_ITEMS") }} diff --git a/docs/docs/purchasing/supplier.md b/docs/docs/purchasing/supplier.md index 14808d492d..57d209d77a 100644 --- a/docs/docs/purchasing/supplier.md +++ b/docs/docs/purchasing/supplier.md @@ -89,3 +89,6 @@ Supplier parts can have a pack size defined. This value is defined when creating When buying parts, they are bought in packs. This is taken into account in Purchase Orders: if a supplier part with a pack size of 5 is bought in a quantity of 4, 20 parts will be added to stock when the parts are received. When adding stock manually, the supplier part can be added in packs or in individual parts. This is to allow the addition of items in opened packages. Set the flag "Use pack size" (`use_pack_size` in the API) to True in order to add parts in packs. + +!!! tip "Bundled Items" + A pack size only ever represents multiple units of the *same* part. If a supplier instead sells a kit or assortment of *different* components as a single purchasable item, refer to the [bundled items](./purchase_order.md#bundled-items) documentation instead. diff --git a/docs/docs/report/assets.md b/docs/docs/report/assets.md new file mode 100644 index 0000000000..176209634a --- /dev/null +++ b/docs/docs/report/assets.md @@ -0,0 +1,45 @@ +--- +title: Report Assets +--- + +## Report Assets + +Users can upload asset files (e.g. images) which can be used when generating reports. For example, you may wish to generate a report with your company logo in the header. + +Asset files are managed from the [Admin Center](../settings/admin.md#admin-center), via the *Report Assets* panel. Staff users can upload new asset files, and remove assets which are no longer required. + +Asset files can be rendered directly into the template as follows + +```html +{% raw %} + +{% load report %} + + + + + + + + + + + + + + + +{% endraw %} +``` + +!!! warning "Asset Naming" + If the requested asset name does not match the name of an uploaded asset, the template will continue without loading the image. + +!!! info "Assets location" + Upload new assets via the *Report Assets* panel in the [Admin Center](../settings/admin.md#admin-center) to ensure they are uploaded to the correct location on the server. + +There are various [helper functions](./helpers.md#report-assets) available to assist with embedding assets into templates. diff --git a/docs/docs/report/context_variables.md b/docs/docs/report/context_variables.md index af38d594dc..5d13e225c3 100644 --- a/docs/docs/report/context_variables.md +++ b/docs/docs/report/context_variables.md @@ -1,9 +1,9 @@ --- -title: Context Variables +title: Report Context --- -## Context Variables +## Report Context Variables Context variables are provided to each template when it is rendered. The available context variables depend on the model type for which the template is being rendered. @@ -13,9 +13,6 @@ In addition to the model-specific context variables, the following global contex {{ report_context("base", "global") }} -::: report.models.ReportTemplateBase.base_context - options: - show_source: True ### Report Context @@ -23,7 +20,7 @@ In addition to the [global context](#global-context), all *report* templates hav {{ report_context("base", "report") }} -When using the `merge` context variable, the selected items are available in the `instances` list. {{ templatefile("report/inventree_stock_report_merge.html") }} shows a complete example. To access individual item attributes, you can either loop through the `instances` or access them by index like `instance.0.name`. +When using the `merge` context variable, the selected items are available in the `instances` list. To access individual item attributes, you can either loop through the `instances` or access them by index like `instance.0.name`. Below is an example template that generates a single report for some selected parts. Each part occupies a row in the table @@ -69,12 +66,14 @@ Templates (whether for generating [reports](./report.md) or [labels](./labels.md | Model Type | Description | | --- | --- | -| company | A Company instance | +| [company](#company) | A Company instance | | [build](#build-order) | A [Build Order](../manufacturing/build.md) instance | | [buildline](#build-line) | A [Build Order Line Item](../manufacturing/build.md) instance | | [salesorder](#sales-order) | A [Sales Order](../sales/sales_order.md) instance | +| [salesordershipment](#sales-order-shipment) | A [Sales Order Shipment](../sales/sales_order.md#sales-order-shipments) instance | | [returnorder](#return-order) | A [Return Order](../sales/return_order.md) instance | | [purchaseorder](#purchase-order) | A [Purchase Order](../purchasing/purchase_order.md) instance | +| [transferorder](#transfer-order) | A [Transfer Order](../stock/transfer_order.md) instance | | [stockitem](#stock-item) | A [StockItem](../stock/index.md#stock-item) instance | | [stocklocation](#stock-location) | A [StockLocation](../stock/index.md#stock-location) instance | | [part](#part) | A [Part](../part/index.md) instance | @@ -85,9 +84,8 @@ When printing a report or label against a Company instance, the following contex {{ report_context("models", "company") }} -::: company.models.Company.report_context - options: - show_source: True +For the fields and properties available on the underlying `Company` instance, refer to the [Model Context](model_context.md#company) page. + ### Build Order @@ -95,9 +93,8 @@ When printing a report or label against a [Build Order](../manufacturing/build.m {{ report_context("models", "build") }} -::: build.models.Build.report_context - options: - show_source: True +For the fields and properties available on the underlying `Build` instance, refer to the [Model Context](model_context.md#build-order) page. + ### Build Line @@ -105,9 +102,7 @@ When printing a report or label against a [BuildOrderLineItem](../manufacturing/ {{ report_context("models", "buildline") }} -::: build.models.BuildLine.report_context - options: - show_source: True +For the fields and properties available on the underlying `BuildLine` instance, refer to the [Model Context](model_context.md#build-order-line-item) page. ### Sales Order @@ -115,9 +110,7 @@ When printing a report or label against a [SalesOrder](../sales/sales_order.md) {{ report_context("models", "salesorder") }} -::: order.models.Order.report_context - options: - show_source: True +For the fields and properties available on the underlying `SalesOrder` instance, refer to the [Model Context](model_context.md#sales-order) page. ### Sales Order Shipment @@ -125,9 +118,7 @@ When printing a report or label against a [SalesOrderShipment](../sales/sales_or {{ report_context("models", "salesordershipment") }} -::: order.models.SalesOrderShipment.report_context - options: - show_source: True +For the fields and properties available on the underlying `SalesOrderShipment` instance, refer to the [Model Context](model_context.md#sales-order-shipment) page. ### Return Order @@ -135,21 +126,31 @@ When printing a report or label against a [ReturnOrder](../sales/return_order.md {{ report_context("models", "returnorder") }} +For the fields and properties available on the underlying `ReturnOrder` instance, refer to the [Model Context](model_context.md#return-order) page. + ### Purchase Order When printing a report or label against a [PurchaseOrder](../purchasing/purchase_order.md) object, the following context variables are available: {{ report_context("models", "purchaseorder") }} +For the fields and properties available on the underlying `PurchaseOrder` instance, refer to the [Model Context](model_context.md#purchase-order) page. + +### Transfer Order + +When printing a report or label against a [TransferOrder](../stock/transfer_order.md) object, the following context variables are available: + +{{ report_context("models", "transferorder") }} + +For the fields and properties available on the underlying `TransferOrder` instance, refer to the [Model Context](model_context.md#transfer-order) page. + ### Stock Item When printing a report or label against a [StockItem](../stock/index.md#stock-item) object, the following context variables are available: {{ report_context("models", "stockitem") }} -::: stock.models.StockItem.report_context - options: - show_source: True +For the fields and properties available on the underlying `StockItem` instance, refer to the [Model Context](model_context.md#stock-item) page. ### Stock Location @@ -157,9 +158,7 @@ When printing a report or label against a [StockLocation](../stock/index.md#stoc {{ report_context("models", "stocklocation") }} -::: stock.models.StockLocation.report_context - options: - show_source: True +For the fields and properties available on the underlying `StockLocation` instance, refer to the [Model Context](model_context.md#stock-location) page. ### Part @@ -167,195 +166,9 @@ When printing a report or label against a [Part](../part/index.md) object, the f {{ report_context("models", "part") }} -::: part.models.Part.report_context - options: - show_source: True - -## Model Variables - -Additional to the context variables provided directly to each template, each model type has a number of attributes and methods which can be accessedd via the template. - -For each model type, a subset of the most commonly used attributes are listed below. For a full list of attributes and methods, refer to the source code for the particular model type. - -### Parts - -#### Part - -Each part object has access to a lot of context variables about the part. The following context variables are provided when accessing a `Part` object from within the template. - -| Variable | Description | -|----------|-------------| -| name | Brief name for this part | -| full_name | Full name for this part (including IPN, if not null and including variant, if not null) | -| variant | Optional variant number for this part - Must be unique for the part name -| category | The [PartCategory](#part-category) object to which this part belongs -| description | Longer form description of the part -| keywords | Optional keywords for improving part search results -| IPN | Internal part number (optional) -| revision | Part revision -| is_template | If True, this part is a 'template' part -| link | Link to an external page with more information about this part (e.g. internal Wiki) -| image | Image of this part -| default_location | The default [StockLocation](#stock-location) object where the item is normally stored (may be null) -| default_supplier | The default [SupplierPart](#supplierpart) which should be used to procure and stock this part -| default_expiry | The default expiry duration for any StockItem instances of this part -| minimum_stock | Minimum preferred quantity to keep in stock -| units | Units of measure for this part (default='pcs') -| salable | Can this part be sold to customers? -| assembly | Can this part be build from other parts? -| component | Can this part be used to make other parts? -| purchaseable | Can this part be purchased from suppliers? -| trackable | Trackable parts can have unique serial numbers assigned, etc, etc -| active | Is this part active? Parts are deactivated instead of being deleted -| virtual | Is this part "virtual"? e.g. a software product or similar -| notes | Additional notes field for this part -| creation_date | Date that this part was added to the database -| creation_user | User who added this part to the database -| responsible | User who is responsible for this part (optional) -| starred | Whether the part is starred or not | -| disabled | Whether the part is disabled or not | -| total_stock | The total amount in stock | -| quantity_being_built | The amount being built | -| required_build_order_quantity | The amount required for build orders | -| allocated_build_order_quantity | The amount allocated for build orders | -| build_order_allocations | Query set with all build order allocations for that part | -| required_sales_order_quantity | The amount required for sales orders | -| allocated_sales_order_quantity | The amount allocated for sales orders | -| available | Whether the part is available or not | -| on_order | The amount that are on order | -| required | The total amount required for build orders and sales orders | -| allocated | The total amount allocated for build orders and sales orders | - -#### Part Category +For the fields and properties available on the underlying `Part` instance, refer to the [Model Context](model_context.md#part) page. -| Variable | Description | -|----------|-------------| -| name | Name of this category | -| parent | Parent category | -| default_location | Default [StockLocation](#stock-location) object for parts in this category or child categories | -| default_keywords | Default keywords for parts created in this category | +## Model Context -### Stock - -#### StockItem - - -| Variable | Description | -|----------|-------------| -| parent | Link to another [StockItem](#stock-item) from which this StockItem was created | -| uid | Field containing a unique-id which is mapped to a third-party identifier (e.g. a barcode) | -| part | Link to the master abstract [Part](#part) that this [StockItem](#stock-item) is an instance of | -| supplier_part | Link to a specific [SupplierPart](#supplierpart) (optional) | -| location | The [StockLocation](#stock-location) Where this [StockItem](#stock-item) is located | -| quantity | Number of stocked units | -| batch | Batch number for this [StockItem](#stock-item) | -| serial | Unique serial number for this [StockItem](#stock-item) | -| link | Optional URL to link to external resource | -| updated | Date that this stock item was last updated (auto) | -| expiry_date | Expiry date of the [StockItem](#stock-item) (optional) | -| stocktake_date | Date of last stocktake for this item | -| stocktake_user | User that performed the most recent stocktake | -| review_needed | Flag if [StockItem](#stock-item) needs review | -| delete_on_deplete | If True, [StockItem](#stock-item) will be deleted when the stock level gets to zero | -| status | Status of this [StockItem](#stock-item) (ref: InvenTree.status_codes.StockStatus) | -| status_label | Textual representation of the status e.g. "OK" | -| notes | Extra notes field | -| build | Link to a Build (if this stock item was created from a build) | -| is_building | Boolean field indicating if this stock item is currently being built (or is "in production") | -| purchase_order | Link to a [PurchaseOrder](#purchase-order) (if this stock item was created from a PurchaseOrder) | -| infinite | If True this [StockItem](#stock-item) can never be exhausted | -| sales_order | Link to a [SalesOrder](#sales-order) object (if the StockItem has been assigned to a SalesOrder) | -| purchase_price | The unit purchase price for this [StockItem](#stock-item) - this is the unit price at time of purchase (if this item was purchased from an external supplier) | -| packaging | Description of how the StockItem is packaged (e.g. "reel", "loose", "tape" etc) | - -#### StockLocation - -| Variable | Description | -|----------|-------------| -| barcode | Brief payload data (e.g. for labels). Example: `{"stocklocation": 826}` where 826 is the primary key| -| description | The description of the location | -| icon | The name of the icon if set, e.g. fas fa-warehouse | -| item_count | Simply returns the number of stock items in this location | -| name | The name of the location. This is only the name of this location, not the path | -| owner | The owner of the location if it has one. The owner can only be assigned in the admin interface | -| parent | The parent location. Returns None if it is already the top most one | -| path | A queryset of locations that contains the hierarchy starting from the top most parent | -| pathstring | A string that contains all names of the path separated by slashes e.g. A/B/C | -| structural | True if the location is structural | - -### Suppliers - -#### Company - - -| Variable | Description | -|----------|-------------| -| name | Name of the company | -| description | Longer form description | -| website | URL for the company website | -| primary_address | [Address](#address) object that is marked as primary address | -| address | String format of the primary address | -| contact | Contact Name | -| phone | Contact phone number | -| email | Contact email address | -| link | A second URL to the company (Actually only accessible in the admin interface) | -| notes | Extra notes about the company (Actually only accessible in the admin interface) | -| is_customer | Boolean value, is this company a customer | -| is_supplier | Boolean value, is this company a supplier | -| is_manufacturer | Boolean value, is this company a manufacturer | -| currency_code | Default currency for the company | -| parts | Query set with all parts that the company supplies | - -#### Address - - -| Variable | Description | -|----------|-------------| -| line1 | First line of the postal address | -| line2 | Second line of the postal address | -| postal_code | ZIP code of the city | -| postal_city | City name | -| country | Country name | - -#### Contact - -| Variable | Description | -|----------|-------------| -| company | Company object where the contact belongs to | -| name | First and second name of the contact | -| phone | Phone number | -| email | Email address | -| role | Role of the contact | - -#### SupplierPart - - -| Variable | Description | -|----------|-------------| -| part | Link to the master Part (Obsolete) | -| source_item | The sourcing [StockItem](#stock-item) linked to this [SupplierPart](#supplierpart) instance | -| supplier | [Company](#company) that supplies this part | -| SKU | Stock keeping unit (supplier part number) | -| link | Link to external website for this supplier part | -| description | Descriptive notes field | -| note | Longer form note field | -| base_cost | Base charge added to order independent of quantity e.g. "Reeling Fee" | -| multiple | Multiple that the part is provided in | -| lead_time | Supplier lead time | -| packaging | packaging that the part is supplied in, e.g. "Reel" | -| pretty_name | The IPN, supplier name, supplier SKU and (if not null) manufacturer string joined by `|`. Ex. `P00037 | Company | 000021` | -| unit_pricing | The price for one unit. | -| price_breaks | Return the associated price breaks in the correct order | -| has_price_breaks | Whether this [SupplierPart](#supplierpart) has price breaks | -| manufacturer_string | Format a MPN string for this [SupplierPart](#supplierpart). Concatenates manufacture name and part number. | - -### User - -| Variable | Description | -|----------|-------------| -| username | the username of the user | -| fist_name | The first name of the user | -| last_name | The last name of the user | -| email | The email address of the user | -| pk | The primary key of the user | +For the underlying fields and properties available on each of the model instances above (plus related model types such as `Address` or `SupplierPart`), refer to the [Model Context](model_context.md) page. diff --git a/docs/docs/report/helpers.md b/docs/docs/report/helpers.md index c8811f561c..dbbe7306ad 100644 --- a/docs/docs/report/helpers.md +++ b/docs/docs/report/helpers.md @@ -320,15 +320,86 @@ The helper function `format_number` allows for some common number formatting opt show_docstring_description: false show_source: False -#### Example +#### Examples ```html {% raw %} {% load report %} -{% format_number 3.14159265359 decimal_places=5, leading=3 %} - + + +{% format_number 3.14159265359 decimal_places=5 %} + + + +{% format_number 3.14159265359 decimal_places=5 leading=3 %} + + + {% format_number 3.14159265359 integer=True %} + + +{% format_number 9988776.5 decimal_places=2 separator=True %} + + + +{% format_number 9988776.5 decimal_places=2 separator=True locale='de-de' %} + + + +{% format_number 0.175 multiplier=100 decimal_places=1 %} + + + +{% format_number 1234.5 decimal_places=2 max_decimal_places=6 %} + + +{% endraw %} +``` + +#### Custom Format Strings + +The `fmt` argument accepts a [Unicode number pattern](https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns) string (the same syntax used by [Babel](https://babel.pocoo.org/en/latest/numbers.html)). When `fmt` is provided it takes complete priority over the `decimal_places`, `max_decimal_places`, `leading`, and `separator` arguments — those arguments are silently ignored. + +The `integer` and `multiplier` arguments **are** still applied to the number before the format string is used. + +| Symbol | Meaning | +| --- | --- | +| `0` | Required digit — always rendered, even if zero | +| `#` | Optional digit — suppressed when not significant | +| `,` | Grouping separator (position defines group size) | +| `.` | Decimal separator | + +Common patterns: + +| Pattern | Example output | +| --- | --- | +| `0` | `1235` | +| `#,##0` | `1,235` | +| `0.00` | `1234.57` | +| `#,##0.00` | `1,234.57` | +| `000` | `007` | + +```html +{% raw %} +{% load report %} + + +{% format_number 1234.5678 fmt='0.00' %} + + + +{% format_number 1234.5678 fmt='#,##0.00' %} + + + +{% format_number 1234.5678 fmt='#,##0.00' locale='de-de' %} + + + +{% format_number 9988776655.4321 fmt='#,##0' integer=True %} + + {% endraw %} ``` @@ -336,6 +407,25 @@ The helper function `format_number` allows for some common number formatting opt For rendering date and datetime information, the following helper functions are available: +Both functions resolve their output using the following priority order: + +1. **`fmt=` argument** — a [strftime format string](https://docs.python.org/3/library/datetime.html#format-codes). When provided, this takes full priority; `locale` and `date_format` are ignored. +2. **`locale=` argument** — when no `fmt` is given, Babel formats the value using the style set by `date_format` (default `medium`). +3. **Server `LANGUAGE_CODE`** — used as the locale when no `locale=` argument is supplied. + +#### Date Format Styles + +The `date_format` argument controls how Babel renders the date when locale-aware formatting is used. The four named styles are: + +| Style | `format_date` example (en-us, 2025-01-12) | `format_datetime` example (en-us, 2025-01-12 14:30) | +| --- | --- | --- | +| `full` | `Sunday, January 12, 2025` | `Sunday, January 12, 2025 at 2:30:00 PM UTC` | +| `long` | `January 12, 2025` | `January 12, 2025 at 2:30:00 PM UTC` | +| `medium` *(default)* | `Jan 12, 2025` | `Jan 12, 2025, 2:30:00 PM` | +| `short` | `1/12/25` | `1/12/25, 2:30 PM` | + +The exact output varies by locale — the table above uses `en-us`. + ### format_date ::: report.templatetags.report.format_date @@ -343,6 +433,35 @@ For rendering date and datetime information, the following helper functions are show_docstring_description: false show_source: False +#### Examples + +```html +{% raw %} +{% load report %} + + +{% format_date my_date %} + + + +{% format_date my_date fmt="%d/%m/%Y" %} + + + +{% format_date my_date locale='en-us' %} + + + +{% format_date my_date locale='en-us' date_format='short' %} + + + +{% format_date my_date locale='en-us' date_format='full' %} + + +{% endraw %} +``` + ### format_datetime ::: report.templatetags.report.format_datetime @@ -350,20 +469,31 @@ For rendering date and datetime information, the following helper functions are show_docstring_description: false show_source: False -### Date Formatting - -If not specified, these methods return a result which uses ISO formatting. Refer to the [datetime format codes](https://docs.python.org/3/library/datetime.html#format-codes) for more information! | - - -### Example - -A simple example of using the date formatting helper functions: +#### Examples ```html {% raw %} {% load report %} -Date: {% format_date my_date timezone="Australia/Sydney" %} -Datetime: {% format_datetime my_datetime format="%d-%m-%Y %H:%M%S" %} + + +{% format_datetime my_datetime %} + + + +{% format_datetime my_datetime fmt="%d-%m-%Y %H:%M" %} + + + +{% format_datetime my_datetime locale='en-us' %} + + + +{% format_datetime my_datetime locale='de-de' date_format='short' %} + + + +{% format_datetime my_datetime timezone="Australia/Sydney" locale='en-au' %} + {% endraw %} ``` @@ -373,11 +503,115 @@ Datetime: {% format_datetime my_datetime format="%d-%m-%Y %H:%M%S" %} The helper function `render_currency` allows for simple rendering of currency data. This function can also convert the specified amount of currency into a different target currency: -::: InvenTree.helpers_model.render_currency +::: report.templatetags.report.render_currency options: show_docstring_description: false show_source: False +#### Decimal Places + +When no decimal place arguments are provided, the locale/currency standard is used (e.g. 2 places for USD, 0 for JPY). + +`decimal_places` and `max_decimal_places` work the same way as in [`format_number`](#format_number): + +| Argument | Effect | +| --- | --- | +| `decimal_places=N` | Forces exactly N decimal digits (zero-padded) | +| `max_decimal_places=M` | Allows up to M decimal digits, suppressing trailing zeros beyond `decimal_places` | +| Both set | Forced minimum of `decimal_places`, optional up to `max_decimal_places` | +| Neither set | Locale/currency default (e.g. 2 for USD) | + +```html +{% raw %} +{% load report %} + + +{% render_currency order.total_price currency='USD' %} + + + +{% render_currency order.total_price currency='USD' decimal_places=3 %} + + + +{% render_currency order.total_price currency='USD' decimal_places=2 max_decimal_places=4 %} + + +{% endraw %} +``` + +#### Locale and Symbol Rendering + +The locale controls how the currency symbol and separators are rendered. For example, `USD 1234.56` with various locales: + +| Locale | Output | +| --- | --- | +| `en-us` | `$1,234.56` | +| `en-gb` | `US$1,234.56` | +| `en-au` | `USD1,234.56` | +| `de-de` | `1.234,56 $` | + +The locale is resolved in the following priority order: + +1. **Explicit `locale=` argument** — highest priority, always wins +2. **Server `LANGUAGE_CODE`** — fallback + +#### Leading Digits + +The `leading` argument specifies the minimum number of digits to render before the decimal point (zero-padded). This works identically to `leading` in [`format_number`](#format_number): + +```html +{% raw %} +{% load report %} + + +{% render_currency order.total_price currency='USD' %} + + + +{% render_currency order.total_price currency='USD' leading=4 %} + + +{% endraw %} +``` + +#### Custom Format Strings + +The `fmt` argument accepts a [Unicode number pattern](https://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns) string (same syntax as [`format_number`](#custom-format-strings)). **When `fmt` is provided, it takes complete priority over `decimal_places`, `max_decimal_places`, and `leading`** — those arguments are ignored. + +The `locale`, `currency`, `multiplier`, and `include_symbol` arguments are still applied when `fmt` is set. + +To include the currency symbol in a `fmt` pattern, use the `¤` placeholder. Without it, no symbol appears regardless of `include_symbol`. + +| Pattern | Example output (en-us, USD) | +| --- | --- | +| `#,##0.00` | `1,234.56` (no symbol) | +| `¤#,##0.00` | `$1,234.56` | +| `¤#,##0.0000` | `$1,234.5600` | +| `¤ #,##0.00` | `$ 1,234.56` | + +```html +{% raw %} +{% load report %} + + +{% render_currency order.total_price currency='USD' fmt='#,##0.00' %} + + + +{% render_currency order.total_price currency='USD' fmt='¤#,##0.0000' locale='en-us' %} + + + +{% render_currency order.total_price currency='USD' fmt='#,##0.00' locale='de-de' %} + + + +{% render_currency order.total_price currency='USD' fmt='0.0000' decimal_places=2 %} + + +{% endraw %} +``` #### Example @@ -392,8 +626,12 @@ The helper function `render_currency` allows for simple rendering of currency da {% endfor %} + Total Price: {% render_currency order.total_price currency='NZD' decimal_places=2 %} + +Total Price: {% render_currency order.total_price currency='USD' locale='en-us' %} + {% endraw %} ``` @@ -669,7 +907,7 @@ If you have a custom logo, but explicitly wish to load the InvenTree logo itself ## Report Assets -[Report Assets](./index.md#report-assets) are files specifically uploaded by the user for inclusion in generated reports and labels. +[Report Assets](./assets.md) are files specifically uploaded by the user for inclusion in generated reports and labels. You can add asset images to the reports and labels by using the `{% raw %}{% asset ... %}{% endraw %}` template tag: diff --git a/docs/docs/report/index.md b/docs/docs/report/index.md index 7190757fd8..0d6e3cba3f 100644 --- a/docs/docs/report/index.md +++ b/docs/docs/report/index.md @@ -53,37 +53,64 @@ To read more about the capabilities of the report templating engine, and how to ## Creating Templates -Report and label templates can be created (and edited) via the [admin interface](../settings/admin.md), under the *Report* section. +Report and label templates are managed from the [Admin Center](../settings/admin.md#admin-center), which provides dedicated panels (under the *Reporting* group) for each template type: -Select the type of template you are wanting to create (a *Report Template* or *Label Template*) and press the *Add* button in the top right corner: +- **Label Templates** - Create and edit [label templates](./labels.md) +- **Report Templates** - Create and edit [report templates](./report.md) +- **Report Snippets** - Manage reusable [snippet](#report-snippets) files +- **Report Assets** - Manage uploaded [asset](#report-assets) files -{{ image("report/report_template_admin.png", "Report template admin") }} +Label and report templates are created and edited using the built-in [template editor](./template_editor.md), which allows templates to be written directly within the browser, with a live preview of the rendered output. !!! tip "Staff Access Only" - Only users with staff access can upload or edit report template files. + Only users with staff access can create, upload or edit templates, snippets and assets. -!!! info "Editing Reports" - Existing reports can be edited from the admin interface, in the same location as described above. To change the contents of the template, re-upload a template file, to override the existing template data. - -!!! tip "Template Editor" - InvenTree also provides a powerful [template editor](./template_editor.md) which allows for the creation and editing of report templates directly within the browser. +!!! info "Database Admin Interface" + Templates can also be managed at a lower level via the [Database Admin interface](../settings/db_admin.md), under the *Report* section. This is recommended for advanced users only. ### Name and Description Each report template requires a name and description, which identify and describe the report template. +### Revision + +Each template has a revision number, which is automatically incremented each time the template is updated. This provides a simple mechanism for tracking changes to a template over time. The revision number is read-only, and cannot be edited directly. + +!!! info "Template Revision Context" + The revision number of the template is made available when rendering, via the `template_revision` [context variable](./context_variables.md#global-context). + ### Enabled Status Boolean field which determines if the specific report template is enabled, and available for use. Reports can be disabled to remove them from the list of available templates, but without deleting them from the database. +### Attach to Model + +If the *Attach to Model on Print* option is enabled, a copy of the generated report is automatically saved as a file attachment against the item (model instance) for which it was generated, each time the template is printed. + +!!! warning "Attachment Support" + The report output is only attached if the target model type supports file attachments. + ### Filename Pattern The filename pattern used to generate the output `.pdf` file. Defaults to "report.pdf". -The filename pattern allows custom rendering with any context variables which are available to the report. For example, a test report for a particular [Stock Item](../stock/index.md#stock-item) can use the part name and serial number of the stock item when generating the report name: +The filename pattern is rendered using the same Django template syntax (`{% raw %}{{ ... }}{% endraw %}`) as the report body, using the same context data - see the [context variables](./context_variables.md) and [model context](./model_context.md) documentation for the full list of variables available to a particular template type. + +!!! info "Filename Pattern Context" + The filename pattern has access to the *entire* context available to the report or label being generated - not a reduced subset. + +For example, a test report for a particular [Stock Item](../stock/index.md#stock-item) can use the part name and serial number of the stock item when generating the report name: {{ image("report/filename_pattern.png", "Report filename pattern") }} +Some further examples: + +| Filename Pattern | Description | +| --- | --- | +| `{% raw %}{{ part.full_name }}-{{ serial }}.pdf{% endraw %}` | Combines the [Part](./model_context.md#part) name with the stock item serial number | +| `{% raw %}PurchaseOrder-{{ reference }}.pdf{% endraw %}` | Uses the purchase order reference (this is the default pattern for the built-in Purchase Order report) | +| `{% raw %}SalesOrder-{{ reference }}-{{ date }}.pdf{% endraw %}` | Combines the sales order reference with the current date | + ### Template Filters @@ -147,86 +174,44 @@ Setting the *Debug Mode* option renders the template as raw HTML instead of PDF, ## Report Assets -User can upload asset files (e.g. images) which can be used when generating reports. For example, you may wish to generate a report with your company logo in the header. Asset files are uploaded via the admin interface. - -Asset files can be rendered directly into the template as follows - -```html -{% raw %} - -{% load report %} - - - - - - - - - - - - - - - -{% endraw %} -``` - -!!! warning "Asset Naming" - If the requested asset name does not match the name of an uploaded asset, the template will continue without loading the image. - -!!! info "Assets location" - Upload new assets via the [admin interface](../settings/admin.md) to ensure they are uploaded to the correct location on the server. +User can upload asset files (e.g. images) which can be used when generating reports. For example, you may wish to generate a report with your company logo in the header. +Refer to the [report assets](./assets.md) documentation for further information. ## Report Snippets -A powerful feature provided by the django / WeasyPrint templating framework is the ability to include external template files. This allows commonly used template features to be broken out into separate files and reused across multiple templates. +InvenTree provides report "snippets" - reusable template files which cannot be rendered by themselves, but can be included in other templates. -To support this, InvenTree provides report "snippets" - short (or not so short) template files which cannot be rendered by themselves, but can be called from other templates. +Refer to the [report snippets](./snippets.md) documentation for further information. -Similar to assets files, snippet template files are uploaded via the admin interface. +## Security -Snippets are included in a template as follows: +Report templates are powerful by design — they have access to the full Django template language and to model data across the InvenTree database. For this reason, **template upload is restricted to staff users only**. -``` -{% raw %}{% include 'snippets/' %}{% endraw %} -``` +### URL Fetching -For example, consider a custom stocktake report for a particular stock location, where we wish to render a table with a row for each item in that location. +When WeasyPrint renders a template to PDF it can make outbound requests to load images, stylesheets, and fonts referenced in the HTML. InvenTree restricts this through a custom URL fetcher with the following rules: -```html -{% raw %} +| URL Type | Behavior | +|---|---| +| `data:` URIs | Always permitted — self-contained, no network access | +| `file://` | Always blocked — assets and images must be inlined as `data:` URIs before reaching WeasyPrint | +| `http` / `https` | Disabled by default, but can be enabled - see *Remote URL Fetching* below | +| Any other scheme | Always blocked | - - - - - - {% for item in location.stock_items %} - {% include 'snippets/stock_row.html' with item=item %} - {% endfor %} - +HTTP redirects are also disabled: a URL that passes validation cannot redirect to an internal address. -{% endraw %} -``` +### Remote URL Fetching -!!! info "Snippet Arguments" - Note above that named argument variables can be passed through to the snippet! +The **Report URL Fetching** system setting (`REPORT_FETCH_URLS`) controls whether `http://` and `https://` URLs in templates are permitted. It defaults to **disabled**. -And the snippet file `stock_row.html` may be written as follows: +When enabled, URLs are still validated against private, loopback, link-local, and reserved IP ranges before the request is made, preventing templates from being used as a vector for [Server-Side Request Forgery (SSRF)](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery) attacks against internal network services. -```html -{% raw %} - - - - - -{% endraw %} -``` +!!! warning "Enable with care" + Enabling remote URL fetching allows report templates to trigger outbound HTTP requests from the InvenTree server. Only enable this if your templates genuinely require it, and ensure that templates are reviewed before deployment. + +### Asset Files + +[Asset files](./assets.md) uploaded through the admin interface are embedded directly into the rendered PDF as base64 `data:` URIs — they are read via the Django storage API and never loaded through WeasyPrint's URL fetcher. This means assets work correctly regardless of whether remote URL fetching is enabled, and also work with remote storage backends such as S3. + +There are various [helper functions](./helpers.md#report-assets) available to assist with embedding assets into templates. diff --git a/docs/docs/report/labels.md b/docs/docs/report/labels.md index 7b4ac1b768..cdaf7136d2 100644 --- a/docs/docs/report/labels.md +++ b/docs/docs/report/labels.md @@ -128,6 +128,25 @@ As an example, consider a label template for a StockItem. A user may wish to def To restrict the label accordingly, we could set the *filters* value to `part__IPN=IPN123`. +## Printing Labels + +Labels are printed directly from the web interface, from the pages where the target items are displayed. To print labels against one or more items: + +1. Select the items to print - either from a table (using the row checkboxes), or by viewing the detail page of a single item +2. Select the *Print* action, and choose the *Print Label* option +3. Select the desired label template - only *enabled* templates which match the selected model type (and pass any template filters) are available for selection +4. Select the *printer* (plugin) to use for printing the labels + +### Label Printing Plugins + +The actual printing of labels is handled by a [label printing plugin](../plugins/mixins/label.md). InvenTree provides a number of built-in printing plugins: + +- The default [InvenTree Label Printer](../plugins/builtin/inventree_label.md) plugin generates a PDF file, which is then made available for download. +- The [Label Sheet](../plugins/builtin/inventree_label_sheet.md) plugin arranges multiple labels onto a single sheet for printing. +- The [Label Machine](../plugins/builtin/inventree_label_machine.md) plugin sends the label to an external [label printer machine](../plugins/machines/label_printer.md). + +Custom label printing plugins (e.g. for driving a specific hardware printer) can be installed to extend this list - refer to the [label mixin documentation](../plugins/mixins/label.md) for further information. + ## Built-In Templates The InvenTree installation provides a number of simple *default* templates which can be used as a starting point for creating custom labels. These built-in templates can be disabled if they are not required. diff --git a/docs/docs/report/model_context.md b/docs/docs/report/model_context.md new file mode 100644 index 0000000000..01bf2ccd51 --- /dev/null +++ b/docs/docs/report/model_context.md @@ -0,0 +1,24 @@ +--- +title: Model Context +--- + +## Model Context Variables + +Each [report context](./context_variables.md) exposes one or more underlying model instances to the template (e.g. `order`, `part`, `item`). In addition to the explicit context variables documented on that page, templates can access any field or property of these model instances directly. + +This page documents, for each reportable model type, the available: + +- **Fields**: Database fields defined on the model (including those inherited from mixins / abstract base classes) +- **Properties**: `@property` attributes which have been explicitly marked with the `@report_attribute` decorator, making them discoverable here + +Not every attribute or method available on a model instance is listed here - only database fields, and properties explicitly marked for discovery. For a full list of attributes and methods, refer to the source code for the particular model type. + +{{ reportable_model_context() }} + +## Related Model Types + +Some *related* model types are not themselves directly reportable, but are referenced by a field or `@report_attribute` property on a reportable model (e.g. `PartCategory` via `part.category`, `SupplierPart` via `part.default_supplier` or `stockitem.supplier_part`). + +These are discovered automatically - there is no manually-maintained list of related models here. If a reportable model gains a new field or `@report_attribute` property pointing at another model, that model will automatically appear in this section. + +{{ related_model_context() }} diff --git a/docs/docs/report/report.md b/docs/docs/report/report.md index c28b1c1874..47556e08ef 100644 --- a/docs/docs/report/report.md +++ b/docs/docs/report/report.md @@ -1,53 +1,51 @@ --- -title: Report and LabelGeneration +title: Report Templates --- -## Custom Reports +## Report Templates -InvenTree supports a customizable reporting ecosystem, allowing the user to develop document templates that meet their particular needs. +Report templates are used to generate formal PDF documents - such as order reports, packing lists, or test reports - rendered against a particular database item (or list of items). -PDF files are generated from custom HTML template files which are written by the user. +Like all InvenTree templates, report templates are written using a mixture of HTML / CSS and the django template language, and are rendered to a PDF file using the WeasyPrint engine: -Templates can be used to generate *reports* or *labels* which can be used in a variety of situations to format data in a friendly format for printing, distribution, conformance and testing. +- Refer to the [template overview](./index.md) for information on creating and managing templates. +- Refer to the [template rendering documentation](./weasyprint.md) for information on the WeasyPrint engine and the django template language. +- Refer to the [context variables documentation](./context_variables.md) for the variables available when rendering a template. -In addition to providing the ability for end-users to provide their own reporting templates, some report types offer "built-in" report templates ready for use. +## Report Options -### WeasyPrint Templates +In addition to the [options common to all templates](./index.md#creating-templates), each report template provides the following options: -InvenTree report templates utilize the powerful [WeasyPrint](https://weasyprint.org/) PDF generation engine. +### Page Size -!!! info "WeasyPrint" - WeasyPrint is an extremely powerful and flexible reporting library. Refer to the [WeasyPrint docs](https://doc.courtbouillon.org/weasyprint/stable/) for further information. +The page size (e.g. `A4` or `Letter`) used when rendering the report to a PDF file. When a new report template is created, this value defaults to the [default page size](./index.md#default-page-size) specified in the global settings. -### Stylesheets +### Landscape -Templates are rendered using standard HTML / CSS - if you are familiar with web page layout, you're ready to go! +If enabled, the report is rendered in landscape orientation, rather than the default portrait orientation. -### Template Language +### Merge -Uploaded report template files are passed through the [django template rendering framework]({% include "django.html" %}/topics/templates/), and as such accept the same variable template strings as any other django template file. Different variables are passed to the report template (based on the context of the report) and can be used to customize the contents of the generated PDF. +If enabled, a single report document is generated for all selected items, rather than a separate document for each item. Refer to the [merging reports](#merging-reports) section below for further information. -### Variables +!!! info "Context Variables" + The `page_size`, `landscape` and `merge` values are also made available to the template as [context variables](./context_variables.md#report-context). -Each report template is provided a set of *context variables* which can be used when rendering the template. +## Generating Reports -For example, rendering the name of a part (which is available in the particular template context as `part`) is as follows: +Reports are generated directly from the web interface, from the pages where the target items are displayed. To generate a report against one or more items: -```html -{% raw %} +1. Select the items to print - either from a table (using the row checkboxes), or by viewing the detail page of a single item +2. Select the *Print* action, and choose the *Print Report* option +3. Select the desired report template - only *enabled* templates which match the selected model type (and pass any [template filters](./index.md#template-filters)) are available for selection +4. The report is generated by the server, and the resulting PDF file is made available for download - -

    Part: {{ part.name }}

    -

    - Description:
    - {{ part.description }} -

    -{% endraw %} -``` +!!! info "Enable Reports" + Report generation must be [enabled in the global settings](./index.md#enable-reports) before reports can be generated. ## Merging Reports -When rendering reports for multiple items, the default behaviour is that each item is rendered as a separate report. The chosen templeate is rendered multiple times, once for each item selected, and expects a single item in the context variable. +When rendering reports for multiple items, the default behaviour is that each item is rendered as a separate report. The chosen template is rendered multiple times, once for each item selected, and expects a single item in the context variable. However, it is possible to merge multiple items into a single report document. This is achieved by enabling the `merge` attribute of the report template: diff --git a/docs/docs/report/samples.md b/docs/docs/report/samples.md index 0489e3b92c..7fed4424ac 100644 --- a/docs/docs/report/samples.md +++ b/docs/docs/report/samples.md @@ -22,6 +22,7 @@ The following report templates are provided "out of the box" and can be used as | [Sales Order Shipment](#sales-order-shipment) | [SalesOrderShipment](../sales/sales_order.md) | Sales Order Shipment report | | [Stock Location](#stock-location) | [StockLocation](../stock/index.md#stock-location) | Stock Location report | | [Test Report](#test-report) | [StockItem](../stock/index.md#stock-item) | Test Report | +| [Transfer Order](#transfer-order) | [TransferOrder](../stock/transfer_order.md) | Transfer Order report | | [Selected Stock Items Report](#selected-stock-items-report) | [StockItem](../stock/index.md#stock-item) | Selected Stock Items report | @@ -57,6 +58,10 @@ The following report templates are provided "out of the box" and can be used as {{ templatefile("report/inventree_test_report.html") }} +### Transfer Order + +{{ templatefile("report/inventree_transfer_order_report.html") }} + ### Selected Stock Items Report {{ templatefile("report/inventree_stock_report_merge.html") }} @@ -68,9 +73,11 @@ The following label templates are provided "out of the box" and can be used as a | Template | Model Type | Description | | --- | --- | --- | | [Build Line](#build-line-label) | [Build line item](../manufacturing/build.md) | Build Line label | -| [Part](#part-label) | [Part](../part/index.md) | Part label | +| [Part](#part-label) | [Part](../part/index.md) | Part label (QR code and part name) | +| [Part (Code128)](#part-label-code128) | [Part](../part/index.md) | Part label (Code128 barcode) | | [Stock Item](#stock-item-label) | [StockItem](../stock/index.md#stock-item) | Stock Item label | -| [Stock Location](#stock-location-label) | [StockLocation](../stock/index.md#stock-location) | Stock Location label | +| [Stock Location](#stock-location-label) | [StockLocation](../stock/index.md#stock-location) | Stock Location label (QR code) | +| [Stock Location (with text)](#stock-location-label-with-text) | [StockLocation](../stock/index.md#stock-location) | Stock Location label (QR code and location details) | ### Build Line Label @@ -78,6 +85,10 @@ The following label templates are provided "out of the box" and can be used as a ### Part Label +{{ templatefile("label/part_label.html") }} + +### Part Label (Code128) + {{ templatefile("label/part_label_code128.html") }} ### Stock Item Label @@ -86,4 +97,8 @@ The following label templates are provided "out of the box" and can be used as a ### Stock Location Label +{{ templatefile("label/stocklocation_qr.html") }} + +### Stock Location Label (with text) + {{ templatefile("label/stocklocation_qr_and_text.html") }} diff --git a/docs/docs/report/snippets.md b/docs/docs/report/snippets.md new file mode 100644 index 0000000000..6acf3f5eaa --- /dev/null +++ b/docs/docs/report/snippets.md @@ -0,0 +1,52 @@ +--- +title: Report Snippets +--- + +## Report Snippets + +A powerful feature provided by the django / WeasyPrint templating framework is the ability to include external template files. This allows commonly used template features to be broken out into separate files and reused across multiple templates. + +To support this, InvenTree provides report "snippets" - short (or not so short) template files which cannot be rendered by themselves, but can be called from other templates. + +Snippet files are managed from the [Admin Center](../settings/admin.md#admin-center), via the *Report Snippets* panel. Staff users can upload new snippet files, and edit or remove existing snippets. + +Additionally, the content of an existing snippet can be modified directly within the browser - simply select a snippet from the table to open it in the built-in [template editor](./template_editor.md#editing-snippets). + +Snippets are included in a template as follows: + +``` +{% raw %}{% include 'snippets/' %}{% endraw %} +``` + +For example, consider a custom stocktake report for a particular stock location, where we wish to render a table with a row for each item in that location. + +```html +{% raw %} + +
    {{ item.part.full_name }}{{ item.quantity }}
    + + + + + {% for item in location.stock_items %} + {% include 'snippets/stock_row.html' with item=item %} + {% endfor %} + + +{% endraw %} +``` + +!!! info "Snippet Arguments" + Note above that named argument variables can be passed through to the snippet! + +And the snippet file `stock_row.html` may be written as follows: + +```html +{% raw %} + + + + + +{% endraw %} +``` diff --git a/docs/docs/report/template_editor.md b/docs/docs/report/template_editor.md index b4fbddbf04..3008434944 100644 --- a/docs/docs/report/template_editor.md +++ b/docs/docs/report/template_editor.md @@ -4,11 +4,11 @@ title: Template editor ## Template editor -The Template Editor is integrated into the [Admin Center](../settings//admin.md#admin-center) of the Web UI. It allows users to create and edit label and report templates directly with a side by side preview for a more productive workflow. +The Template Editor is integrated into the [Admin Center](../settings/admin.md#admin-center) of the Web UI. It allows users to create and edit label and report templates directly with a side by side preview for a more productive workflow. ![Template Table](../assets/images/report/template-table.png) -On the left side (1) are all possible possible template types for labels and reports listed. With the "+" button (2), above the template table (3), new templates for the selected type can be created. To switch to the template editor click on a template. +On the left side (1) are all possible template types for labels and reports listed. With the "+" button (2), above the template table (3), new templates for the selected type can be created. To switch to the template editor click on a template. ### Editing Templates @@ -31,3 +31,10 @@ If you don't want to override the template, but just render a preview for a temp #### Edit template metadata Editing metadata such as name, description, filters and even width/height for labels and orientation/page size for reports can be done from the edit modal accessible when clicking on the three dots (4) and select "Edit" in the dropdown menu. + +### Editing Snippets + +[Report snippets](./index.md#report-snippets) can also be edited directly within the browser, from the *Report Snippets* panel in the Admin Center. Selecting a snippet from the table opens it in the same code editor as used for report and label templates. + +!!! info "No Preview" + As snippets cannot be rendered by themselves (they must be included in a report or label template), no preview area is available when editing a snippet. diff --git a/docs/docs/sales/return_order.md b/docs/docs/sales/return_order.md index d57dcc562a..b78b3fe3e4 100644 --- a/docs/docs/sales/return_order.md +++ b/docs/docs/sales/return_order.md @@ -117,9 +117,88 @@ Return Order line items can be added while the [status](#return-order-status-cod !!! info "Serialized Stock Only" Only stock items which are serialized can be selected for return from the customer +!!! info "Discount" + An optional [discount](../concepts/pricing.md#line-item-discount) percentage can be applied to each line item. + +Each line item tracks a *Cost* (the cost associated with the return, repair, or replacement of the item) in addition to the quantity, [target date](#order-scheduling) and notes fields common to other order types. This cost is purely informational - it is not linked to any accounting or invoicing system. + +#### Line Item Outcome + +Each line item has an *Outcome*, which records the disposition decided for the returned item: + +| Outcome | Description | +| --- | --- | +| Pending | No outcome has been decided yet (default value for a new line item) | +| Return | The item is to be returned to the customer, with no further action | +| Repair | The item is to be repaired, and returned to the customer | +| Replace | The item is to be replaced with a new item | +| Refund | The item cannot be repaired, and a refund is to be issued | +| Reject | The return is rejected | + +The *Outcome* is not available when a line item is first created - it can only be set afterwards, by editing the line item. Selecting an outcome is a manual, record-keeping step only: InvenTree does not automatically create a replacement order, issue a refund, or link to a [repair](../manufacturing/index.md) process based on the selected outcome. Any follow-up action (raising a new [Sales Order](./sales_order.md) for a replacement, processing a refund, or tracking a repair) must currently be actioned separately. + +Return Order Line Item outcome supports [custom states](../concepts/custom_states.md). + ### Extra Line Items -While [line items](#line-items) must reference a particular stock item, extra line items are available for any other itemized information that needs to be conveyed with the order. +While [line items](#line-items) must reference a particular stock item, extra line items are available for any other itemized information that needs to be conveyed with the order - for example freight charges or service fees. Extra line items support an optional [discount](../concepts/pricing.md#line-item-discount) percentage, the same as regular line items. + +## Issue Order + +Once all line items have been added, click on the {{ icon("send", title="Issue") }} button on the main return order detail panel and confirm the order has been issued to the customer. This moves the order into the *In Progress* state, and allows [line items to be received](#receive-line-items). + +## Receive Line Items + +As returned items arrive from the customer, they can be marked as "received" against the return order. This is the point at which the return order actually affects stock. + +To receive one or more line items: + +* either individually: click on the {{ icon("square-arrow-right") }} *Receive Item* button on the row for a specific line item +* or in bulk: select multiple unreceived rows in the line item table, then click on the {{ icon("square-arrow-right") }} *Receive selected items* button above the table + +!!! note "Permissions" + Marking line items as received requires the "Return order" ADD permission. + +!!! note "Order Status" + Line items can only be received while the order [status](#return-order-status-codes) is *In Progress*. + +In the "Receive Items" form, a destination *Location* must be selected - this is where the returned stock will be placed. An optional per-item *Status* can also be set for each item being received (for example, to mark an item as damaged or destroyed on arrival); if left unset, received items default to a *Quarantined* stock status, since they have not yet been inspected. + +Receiving a line item performs the following actions on the underlying stock item: + +* Transfers the stock item to the selected destination location +* Sets the stock item status (defaulting to *Quarantined*) +* Removes the *Customer* reference from the stock item +* Clears any outstanding sales order allocations against the stock item +* Adds a tracking entry recording the return + +!!! info "Partial Returns" + If a customer returns less than the full quantity of a non-serialized stock item, InvenTree automatically splits the returned quantity into a new stock item, leaving the remainder of the original stock item untouched (e.g. still recorded as sold to the customer). + +Once received, a line item's *Outcome* can be set - see [Line Item Outcome](#line-item-outcome) above. + +## Complete Order + +Once all returned items have been received and any outcomes have been actioned, click on the {{ icon("circle-check", color="green") }} button on the main return order detail panel and confirm the order as complete. + +It is not necessary for every line item to be marked as *received* before an order can be completed - this allows an order to be closed out even if some items were never returned by the customer. + +## Cancel Order + +If the return will not be processed, the order can be cancelled instead. Click on the {{ icon("circle-x", color="red") }} *Cancel order* option under the {{ icon("tools") }} order actions menu, and confirm the return order has been cancelled. + +## Hold Order + +An open order (*Pending* or *In Progress*) can be placed *On Hold*, to indicate that it is temporarily paused without being cancelled. Click on the {{ icon("hand-stop", title="Hold") }} *Hold order* option under the {{ icon("tools") }} order actions menu to place the order on hold. A held order can subsequently be [issued](#issue-order) again to resume progress. + +## Duplicate Return Order + +Duplicating a Return Order allows the user to quickly create a new *copy* of an existing order, using the same customer information. + +To duplicate an existing order, select the *Duplicate order* action from the menu in the top-right of the screen. + +!!! info "Line Items Not Copied" + Unlike Purchase Orders and Sales Orders, Return Order line items are *not* copied when duplicating an order - each line item is tied to a specific physical stock item being returned, so this information cannot be sensibly duplicated. Extra line items and parameters can optionally be copied. ## Return Order Reports diff --git a/docs/docs/sales/sales_order.md b/docs/docs/sales/sales_order.md index d1c8a790ff..bfb3a7b9db 100644 --- a/docs/docs/sales/sales_order.md +++ b/docs/docs/sales/sales_order.md @@ -90,6 +90,13 @@ Once the "Add Line Item" form opens, select a part in the list. Fill out the rest of the form then click on Submit +!!! info "Discount" + An optional [discount](../concepts/pricing.md#line-item-discount) percentage can be applied to each line item. + +### Extra Line Items + +While [line items](#add-line-items) must reference a particular part, extra line items are available for any other itemized information that needs to be conveyed with the order - for example freight charges or service fees. Extra line items support an optional [discount](../concepts/pricing.md#line-item-discount) percentage, the same as regular line items. + ## Shipments After all line items were added to the sales order, user needs to create one or more [shipments](#sales-order-shipments) in order to allocate stock for those parts. @@ -110,6 +117,79 @@ After shipments were created, user can either: During the allocation process, user is required to select the desired shipment that will contain the stock items. +### Auto Allocate Stock + +To speed up the allocation process, use the *Auto Allocate Stock* button ({{ icon("wand") }}) available in the *Line Items* tab. This automatically finds available stock and creates the required allocations with minimal user interaction. + +!!! info "Background Task" + Auto-allocation runs as a background task. The UI will display a progress indicator while the task is running. + +#### Selecting Lines to Allocate + +By default, auto-allocation processes **all unallocated line items** on the order. To restrict allocation to a subset of lines, select the desired rows in the *Line Items* table before pressing the button — the dialog will indicate how many lines are selected. + +#### Auto Allocation Options + +The auto-allocation dialog provides the following options: + +**Source Location** + +Restrict stock to a specific location (and all of its sub-locations). Leave blank to consider stock from any location. + +**Exclude Location** + +Exclude stock from a specific location (and all of its sub-locations). Useful for reserving stock in a particular area. + +**Shipment** + +Optionally assign all new allocations to a specific pending shipment. Only shipments that have not yet been completed are shown. + +**Interchangeable Stock** + +When enabled (default), stock may be drawn from multiple stock items or locations to fulfil a single line item. When disabled, a line item is only allocated if a single stock item can cover the entire remaining quantity. + +!!! warning "Take Care" + Enabling *Interchangeable Stock* means the auto-allocation routine will combine stock from different batches or locations. Review the resulting allocations if traceability is important. + +**Stock Priority** + +Controls the order in which matching stock items are consumed: + +| Option | Description | +| --- | --- | +| Oldest stock first (FIFO) | Stock items updated least recently are consumed first *(default)* | +| Newest stock first (LIFO) | Stock items updated most recently are consumed first | +| Smallest quantity first | Stock items with the lowest available quantity are consumed first | +| Largest quantity first | Stock items with the highest available quantity are consumed first | +| Soonest expiry date first | Stock items expiring earliest are consumed first; items with no expiry date are used last | + +**Serialized Stock** + +Controls whether serialized stock items are included in the auto-allocation: + +| Option | Description | +| --- | --- | +| Allow any stock | Both serialized and unserialized stock items are considered *(default)* | +| Serialized stock only | Only stock items that carry a serial number are allocated | +| Unserialized stock only | Only stock items without a serial number are allocated | + +#### Allocation Behaviour + +The auto-allocation routine performs the following steps for each eligible line item: + +1. Skips line items for *virtual* parts. +2. Skips line items that are already fully allocated. +3. Queries available stock for the line's part, applying any location and serialized-stock filters. +4. Sorts the candidates according to the chosen *Stock Priority*. +5. Greedily allocates from each stock item in turn until the remaining quantity for the line is satisfied. + +#### Removing Allocations + +Individual or multiple allocations can be removed from the *Allocated Stock* tab. Select the allocations to remove and use the *Delete* action. + +!!! warning "Shipped Allocations Protected" + Allocations that belong to a completed (shipped) shipment cannot be deleted. + ### Check Shipment Shipments can be marked as "checked" to indicate that the items in the shipment has been verified. To mark a shipment as "checked", open the shipment actions menu, and select the "Check" action: diff --git a/docs/docs/security.md b/docs/docs/security.md index d5a34403f5..6a3be12052 100644 --- a/docs/docs/security.md +++ b/docs/docs/security.md @@ -6,24 +6,24 @@ The InvenTree project is committed to providing a secure and safe environment fo To that end, we have implemented a number of security measures over the years, which we will outline in this document. -## Organisational measures +## Organizational Measures The InvenTree project is managed by a small team of developers, who are responsible for the ongoing development and maintenance of the software. Two geographically distributed users have administrative access to the InvenTree codebase. Merges are only done by one of these two users, the maintainer Oliver. Read the Project [Governance](./project/governance.md) document for more information. -InvenTree is open-source, and we welcome contributions from the community. However, all contributions are reviewed and scrutinised before being merged into the codebase. +InvenTree is open-source, and we welcome contributions from the community. However, all contributions are reviewed and scrutinized before being merged into the codebase. ### Security Policy The official [Security Policy]({{ sourcefile("SECURITY.md") }}) is available in the code repository. -We provide this document in our main repo to increase discoverabiltity to ensure that all security issues are handled in a timely manner. +We provide this document in our main repo to increase discoverability to ensure that all security issues are handled in a timely manner. ### Past Reports If we become aware of a security issue, we will take immediate action to address the issue, and will provide a public disclosure of the issue once it has been resolved. We support assigning CVEs to security issues where appropriate. Our [past security advisories can be found here](https://github.com/inventree/InvenTree/security/advisories). -## Technical measures +## Technical Measures -### Code hosting +### Code Hosting The InvenTree project is hosted on GitHub, and we rely on the security measures provided by GitHub to help protect the integrity of the codebase. @@ -35,24 +35,24 @@ Among those are: - (Optional but encouraged) Two-factor authentication for user accounts - (Optional but encouraged) Signed commits / actions -### Code style +### Code Style We enforce style and security checks in our CI/CD pipeline, and we have several automated tests to ensure that the codebase is secure and functional. Checks are run on every pull request, and we require that all checks pass before a pull request can be merged. -### Current versions +### Current Versions InvenTree is built using the Django framework, which has a strong focus on security. We follow best practices for Django development, and we are committed to keeping the codebase up-to-date with the latest security patches and within supported versions. -### Test coverage +### Test Coverage We run coverage tests on our codebase to ensure that we have a high level of test coverage above 90%. This is public and can be found [here](https://app.codecov.io/gh/inventree/InvenTree). -### Pinning dependencies +### Pinning Dependencies We are pinning dependencies to specific versions - aiming for complete reproducibility of builds - wherever possible. Combined with continuous OSV checks, we are able to react quickly to security issues in our dependencies. -## Best practices +## Best Practices We follow most of GitHubs community best practices, check our compliance [here](https://github.com/inventree/InvenTree/community). diff --git a/docs/docs/settings/MFA.md b/docs/docs/settings/MFA.md index feccabc87f..80d8c4c526 100644 --- a/docs/docs/settings/MFA.md +++ b/docs/docs/settings/MFA.md @@ -16,4 +16,4 @@ To make MFA mandatory for all users: ### Security Consideration -A user can lock themselves out if they lose access to both the device with their TOTP app and their backup tokens. An admin can delete their tokens from the admin pages (they exist under the 'TOTP devices' / 'static devices' models) . This should be a last resort and only done by people knowledgeable about the [admin pages](../settings/admin.md) as changes there might circumvent InvenTree's business and security logic. +A user can lock themselves out if they lose access to both the device with their TOTP app and their backup tokens. An admin can delete their tokens from the Database Admin interface (they exist under the 'TOTP devices' / 'static devices' models). This should be a last resort and only done by people knowledgeable about the [Database Admin interface](../settings/db_admin.md), as changes there might circumvent InvenTree's business and security logic. diff --git a/docs/docs/settings/SSO.md b/docs/docs/settings/SSO.md index ab7d3a539c..611df18685 100644 --- a/docs/docs/settings/SSO.md +++ b/docs/docs/settings/SSO.md @@ -18,7 +18,7 @@ The basic requirements for configuring SSO are outlined below: 1. Enable backend for each required SSO provider(s) in the [config file or environment variables](../start/config.md#single-sign-on). 1. Create an external *app* with your provider of choice -1. Add the required client configurations in the `SocialApp` app in the [admin interface](../settings/admin.md). +1. Add the required client configurations in the `SocialApp` app in the [Database Admin interface](../settings/db_admin.md). 1. Configure the *callback* URL for the external app. 1. Enable SSO for the users in the [global settings](../settings/global.md). 1. Configure [e-mail](../settings/email.md). @@ -161,4 +161,4 @@ Make sure all users with admin privileges have sufficient passwords - they can r ## Error Handling -If you encounter an error during the SSO process, the error should be logged in the InvenTree database. You can view the [error log](./logs.md) in the [admin interface](./admin.md) to see the details of the error. +If you encounter an error during the SSO process, the error should be logged in the InvenTree database. You can view the [error log](./logs.md) in the [Admin Center](./admin.md#admin-center) to see the details of the error. diff --git a/docs/docs/settings/admin.md b/docs/docs/settings/admin.md index 039ba0e026..fc922e70e7 100644 --- a/docs/docs/settings/admin.md +++ b/docs/docs/settings/admin.md @@ -4,24 +4,23 @@ title: InvenTree Admin Interfaces ## InvenTree Admin Interfaces -There are multiple administration interfaces available in InvenTree, which provide different levels of access to the underlying resources and different operational safety. +InvenTree provides multiple administration interfaces with different safety levels and intended use cases. [**Admin Center**](#admin-center): -- Main interface for managing InvenTree -- Robust verification and safety checks +- Main administration interface for day-to-day operations +- Uses API-backed flows with validation and safety checks [**System Settings**](#system-settings): -- Access to all settings -- Robust verification, requires reading the documentation +- Access to global runtime settings +- Available to staff users (or users with equivalent API scope) -[**Backend Admin Interface**](#backend-admin-interface): +[**Database Admin Interface**](./db_admin.md): -- Low level access to the database -- Few verification or safety checks -- Requires knowledge of InvenTree internals -- Recommended for advanced users only +- Low-level database administration +- Fewer safeguards than the Admin Center +- Intended for advanced users and troubleshooting scenarios ### Admin Center @@ -34,7 +33,13 @@ The Admin Center is the main interface for managing InvenTree. It provides a use - Integration with external services (via machines and plugins) - Reporting and statistics -It can be access via the *Admin Center* link in the top right user menu, the *Admin Center* quick-link in the command palette, or via the navigation menu. +#### Access Admin Center + +The Admin Center can be accessed in any of the following ways: + +- User menu in the top-right corner: *Admin Center* +- Command palette quick action: *Admin Center* +- Direct URL: `/web/settings/admin` #### Permissions @@ -44,40 +49,6 @@ Some panes can only be accessed by users with specific permissions. For example, The System Settings interface provides ordered access to all global settings in InvenTree. Users need to have _staff_ privileges enabled or the _a:staff_ scope. -### Backend Admin Interface +### Database Admin Interface -Users which have *staff* privileges have access to an Admin interface which provides extremely low level control of the database. Every item in the database is available and this interface provides a unrestricted option for directly viewing and modifying database objects. - -!!! warning "Caution" - Admin users should exercise extreme care when modifying data via the admin interface, as performing the wrong action may have unintended consequences! - -The admin interface allows *staff* users the ability to directly view / add / edit / delete database entries according to their [user permissions](./permissions.md). - -#### Access Backend Admin Interface - -To directly access the admin interface, append /admin/ to the InvenTree site URL - e.g. http://localhost:8000/admin/. - -An administration panel will be presented as shown below: - -{{ image("admin/admin.png", "Admin panel") }} - -#### View Database Objects - -Database objects can be listed and filtered directly. The image below shows an example of displaying existing part categories. - -{{ image("admin/part_cats.png", "Part categories") }} - -!!! info "Permissions" - A "staff" account does not necessarily provide access to all administration options, depending on the roles assigned to the user. - -##### Filtering - -Some admin views support filtering of results against specified criteria. For example, the list of Part objects can be filtered as follows: - -{{ image("admin/filter.png", "Filter part list") }} - -#### Edit Database Objects - -Individual database objects can be edited directly in the admin interface. The image below shows an example of editing a Part object: - -{{ image("admin/edit_part.png", "Edit part") }} +For low-level administration tasks, use the [Database Admin Interface](./db_admin.md). diff --git a/docs/docs/settings/db_admin.md b/docs/docs/settings/db_admin.md new file mode 100644 index 0000000000..fc37ee487a --- /dev/null +++ b/docs/docs/settings/db_admin.md @@ -0,0 +1,54 @@ +--- +title: InvenTree Database Admin Interface +--- + +## Database Admin Interface + +The Database Admin interface provides low-level access to InvenTree database objects. + +!!! danger "Low-Level Interface" + The Database Admin bypasses many of the application-level safety checks used in the Admin Center. + Incorrect edits can create inconsistent data, break workflows, or expose security issues. + Use this interface only if you understand the data model and operational impact. + +!!! warning "Recommended Usage" + Prefer the [Admin Center](./admin.md#admin-center) for routine administration. + Use the Database Admin only for advanced administration and troubleshooting. + +### Access Database Admin Interface + +Access to the Database Admin requires a user account with *staff* privileges. + +Use one of the following methods: + +- Append `/admin/` to the base InvenTree URL (for example: `http://localhost:8000/admin/`) +- Use the configured administrator URL from `INVENTREE_ADMIN_URL` + +{{ image("admin/admin.png", "Database Admin panel") }} + +### Permissions + +A "staff" account does not necessarily provide access to all administration options, depending on the roles assigned to the user. + +### View Database Objects + +Database objects can be listed and filtered directly. The image below shows an example of displaying existing part categories. + +{{ image("admin/part_cats.png", "Part categories") }} + +#### Filtering + +Some admin views support filtering of results against specified criteria. For example, the list of Part objects can be filtered as follows: + +{{ image("admin/filter.png", "Filter part list") }} + +### Edit Database Objects + +Individual database objects can be edited directly in the Database Admin interface. The image below shows an example of editing a Part object: + +{{ image("admin/edit_part.png", "Edit part") }} + +!!! danger "Before You Save Changes" + Verify your changes carefully before saving. + If possible, test changes in a non-production environment first. + Record what you changed so it can be reviewed and reverted if needed. diff --git a/docs/docs/settings/global.md b/docs/docs/settings/global.md index 752ef1b910..ee5820408a 100644 --- a/docs/docs/settings/global.md +++ b/docs/docs/settings/global.md @@ -33,6 +33,7 @@ Configuration of basic server settings: {{ globalsetting("DISPLAY_FULL_NAMES") }} {{ globalsetting("DISPLAY_PROFILE_INFO") }} {{ globalsetting("WEEK_STARTS_ON") }} +{{ globalsetting("CALENDAR_HORIZON_MONTHS") }} {{ globalsetting("INVENTREE_UPLOAD_MAX_SIZE") }} {{ globalsetting("INVENTREE_STRICT_URLS") }} @@ -143,6 +144,7 @@ Configuration of report generation: {{ globalsetting("REPORT_ENABLE") }} {{ globalsetting("REPORT_DEFAULT_PAGE_SIZE") }} {{ globalsetting("REPORT_DEBUG_MODE") }} +{{ globalsetting("REPORT_FETCH_URLS") }} {{ globalsetting("REPORT_LOG_ERRORS") }} ### Label Printing @@ -224,6 +226,7 @@ Configuration of stock item options {{ globalsetting("STOCK_SHOW_INSTALLED_ITEMS") }} {{ globalsetting("STOCK_ENFORCE_BOM_INSTALLATION") }} {{ globalsetting("STOCK_ALLOW_OUT_OF_STOCK_TRANSFER") }} +{{ globalsetting("STOCK_MERGE_ON_TRANSFER") }} {{ globalsetting("TEST_STATION_DATA") }} ### Build Orders diff --git a/docs/docs/settings/logs.md b/docs/docs/settings/logs.md index d161ea1fe4..9a1561b086 100644 --- a/docs/docs/settings/logs.md +++ b/docs/docs/settings/logs.md @@ -1,22 +1,19 @@ --- -title: Admin Shell +title: Error Logs --- ## Error Logs -Any critical server error logs are recorded to the database, and can be viewed by staff users using the admin interface. +Any critical server error logs are recorded to the database, and can be viewed by staff users in the [Admin Center](./admin.md#admin-center), under the *Error Reports* section: -In the admin interface, select the "Errors" view: +{{ image("admin/admin_errors_link.png", "Error Reports in the Admin Center") }} -{{ image("admin/admin_errors_link.png", "Admin errors") }} - -!!! info "URL" - Alternatively, navigate to the error list view at /admin/error_report/error/ - -A list of error logs is presented. +A list of error logs is presented. Select an entry to view the full error details, including the traceback. {{ image("admin/admin_errors.png", "Error logs") }} +!!! info "Database Admin Interface" + Error logs can also be viewed via the [Database Admin interface](./db_admin.md), at the URL `/admin/error_report/error/` !!! info "Deleting Logs" Error logs should be deleted periodically diff --git a/docs/docs/settings/permissions.md b/docs/docs/settings/permissions.md index 6e169af8f5..e40b206672 100644 --- a/docs/docs/settings/permissions.md +++ b/docs/docs/settings/permissions.md @@ -7,7 +7,7 @@ title: User Permissions InvenTree provides access control to various features and data, by assigning each *user* to one (or more) *groups* which have multiple *roles* assigned. !!! info "Superuser" - The superuser account is afforded *all* permissions across an InvenTree installation. This includes the admin interface, web interface, and API. + The superuser account is afforded *all* permissions across an InvenTree installation. This includes the [Database Admin interface](./db_admin.md), web interface, and API. ### User @@ -54,7 +54,7 @@ Within each role, there are four levels of available permissions: ## Dangerous User Flags In addition to the above permissions, there are two special flags that can be assigned to a user: -- **Staff** - A user with the *staff* flag is able to access the admin interface, and can trigger dangerous actions that might have a security impact such as changing parsable files on the server (templates / reports / plugins). Some of these actions require the *admin* role to be assigned as well. +- **Staff** - A user with the *staff* flag is able to access the [Database Admin interface](./db_admin.md), and can trigger dangerous actions that might have a security impact such as changing parsable files on the server (templates / reports / plugins). Some of these actions require the *admin* role to be assigned as well. - **Superuser** - A user with the *superuser* flag is able to access and change all data and functions of InvenTree. A superuser can modify and access all data that the InvenTree installation / server has access to - including shell access on the server OS itself. This is a very powerful flag, and should be used with caution. It is strongly recommended to register any users with staff / superuser flags with strong MFA methods to reduce the risk of unauthorized access. These accounts should be used with caution, and should not be used for day-to-day operations. @@ -62,11 +62,11 @@ It is strongly recommended to register any users with staff / superuser flags wi Practicing account tiering is strongly recommended. -## Admin Interface Permissions +## Database Admin Permissions -If a user does not have the required permissions to perform a certain action in the admin interface, those options not be displayed. +If a user does not have the required permissions to perform a certain action in the [Database Admin interface](./db_admin.md), those options will not be displayed. -If a user is expecting a certain option to be available in the admin interface, but it is not present, it is most likely the case that the user does not have those permissions assigned. +If a user is expecting a certain option to be available in the Database Admin interface, but it is not present, it is most likely the case that the user does not have those permissions assigned. ## Web Interface Permissions diff --git a/docs/docs/settings/tasks.md b/docs/docs/settings/tasks.md index fd6d30c159..3d8721f9ee 100644 --- a/docs/docs/settings/tasks.md +++ b/docs/docs/settings/tasks.md @@ -24,6 +24,6 @@ The Django Q work must run separately to the web server. This is started as a se If the worker is not running, a warning indicator is displayed in the InvenTree menu bar. -## Admin Interface +## Admin Center -Scheduled tasks can be viewed in the InvenTree admin interface. +Scheduled, pending and failed tasks can be viewed in the [Admin Center](./admin.md#admin-center), under the *Background Tasks* section. diff --git a/docs/docs/settings/user.md b/docs/docs/settings/user.md index fc8a1664cb..6bb8162269 100644 --- a/docs/docs/settings/user.md +++ b/docs/docs/settings/user.md @@ -25,10 +25,12 @@ The *Display Settings* screen shows general display configuration options: {{ usersetting("BARCODE_IN_FORM_FIELDS") }} {{ usersetting("DATE_DISPLAY_FORMAT") }} {{ usersetting("FORMS_CLOSE_USING_ESCAPE") }} +{{ usersetting("ENABLE_PREVIEW_PANEL") }} {{ usersetting("DISPLAY_STOCKTAKE_TAB") }} {{ usersetting("SHOW_FULL_CATEGORY_IN_TABLES")}} {{ usersetting("SHOW_BOM_SUBASSEMBLY_LEVELS")}} {{ usersetting("ENABLE_LAST_BREADCRUMB") }} +{{ usersetting("SHOW_EXTRA_MODEL_INFO") }} {{ usersetting("SHOW_FULL_LOCATION_IN_TABLES") }} {{ usersetting("DISPLAY_ITEMS_FINAL_LEVEL") }} @@ -41,6 +43,7 @@ Customize settings for search results: {{ usersetting("SEARCH_WHOLE") }} {{ usersetting("SEARCH_REGEX") }} {{ usersetting("SEARCH_NOTES") }} +{{ usersetting("SEARCH_RESULTS_PREVIEW_PANEL") }} {{ usersetting("SEARCH_PREVIEW_RESULTS") }} {{ usersetting("SEARCH_PREVIEW_SHOW_PARTS") }} {{ usersetting("SEARCH_HIDE_INACTIVE_PARTS") }} diff --git a/docs/docs/start/config.md b/docs/docs/start/config.md index d7b9d18297..e2c5e63fb4 100644 --- a/docs/docs/start/config.md +++ b/docs/docs/start/config.md @@ -65,7 +65,7 @@ The following basic options are available: {{ configsetting("INVENTREE_SITE_URL") }} Specify a fixed site URL | {{ configsetting("INVENTREE_TIMEZONE") }} Server timezone | {{ configsetting("INVENTREE_ADMIN_ENABLED") }} Enable the [django administrator interface]({% include "django.html" %}/ref/contrib/admin/) | -{{ configsetting("INVENTREE_ADMIN_URL") }} URL for accessing [admin interface](../settings/admin.md) | +{{ configsetting("INVENTREE_ADMIN_URL") }} URL for accessing the [Database Admin interface](../settings/db_admin.md) | {{ configsetting("INVENTREE_LANGUAGE") }} Default language | {{ configsetting("INVENTREE_AUTO_UPDATE") }} Database migrations will be run automatically | @@ -122,6 +122,9 @@ Depending on how your InvenTree installation is configured, you will need to pay !!! success "INVENTREE_SITE_URL" If you have specified the `INVENTREE_SITE_URL`, this will automatically be used as a trusted CSRF and CORS host (see below). +!!! tip "Running Behind a Reverse Proxy" + If InvenTree is served behind an existing reverse proxy (e.g. NGINX, Traefik) with SSL termination happening upstream, refer to the [worked example](./processes.md#integrating-with-existing-proxy) for the combination of `INVENTREE_TRUSTED_ORIGINS` and `INVENTREE_USE_X_FORWARDED_*` settings that setup requires. + {{ configtable() }} {{ configsetting("INVENTREE_ALLOWED_HOSTS") }} List of allowed hosts | {{ configsetting("INVENTREE_TRUSTED_ORIGINS", default="Uses the *INVENTREE_SITE_URL* parameter, if set. Otherwise, an empty list.") }} List of trusted origins. Refer to the [django documentation]({% include "django.html" %}/ref/settings/#csrf-trusted-origins) | @@ -136,7 +139,8 @@ Depending on how your InvenTree installation is configured, you will need to pay | `INVENTREE_X_FORWARDED_PROTO_NAME` | `x_forwarded_proto_name` | `HTTP_X_FORWARDED_PROTO` | Name of the header to use for forwarded protocol information | {{ configsetting("INVENTREE_SESSION_COOKIE_SECURE") }} Enforce secure session cookies | {{ configsetting("INVENTREE_COOKIE_SAMESITE") }} Session cookie mode. Must be one of `Strict | Lax | None | False`. Refer to the [mozilla developer docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) and the [django documentation]({% include "django.html" %}/ref/settings/#std-setting-SESSION_COOKIE_SAMESITE) for more information. | - +{{ configsetting("INVENTREE_THROTTLE_ANON") }} Throttle rate for anonymous users (e.g. '20/minute') | +{{ configsetting("INVENTREE_THROTTLE_USER") }} Throttle rate for authenticated users (e.g. '5/second') | ### Debug Mode @@ -256,6 +260,9 @@ The following database options can be configured: {{ configsetting("INVENTREE_DB_PASSWORD") }} Database password (if required) | {{ configsetting("INVENTREE_DB_HOST") }} Database host address (if required) | {{ configsetting("INVENTREE_DB_PORT") }} Database host port (if required) | +{{ configsetting("INVENTREE_DB_CONN_MAX_AGE") }} Database connection max age (s) | +{{ configsetting("INVENTREE_DB_CONN_HEALTH_CHECKS") }} Enable database connection health checks | + {{ configsetting("INVENTREE_DB_OPTIONS") }} Additional database options (as a JSON object) | !!! tip "Database Password" @@ -266,11 +273,12 @@ The following database options can be configured: If running with a PostgreSQL database backend, the following additional options are available: {{ configtable() }} -{{ configsetting("INVENTREE_DB_TIMEOUT", default="2") }} Database connection timeout (s) | +{{ configsetting("INVENTREE_DB_TIMEOUT", default="10") }} Database connection timeout (s) | | `INVENTREE_DB_TCP_KEEPALIVES` | database.tcp_keepalives | 1 | TCP keepalive | -| `INVENTREE_DB_TCP_KEEPALIVES_IDLE` | database.tcp_keepalives_idle | 1 | Idle TCP keepalive | -| `INVENTREE_DB_TCP_KEEPALIVES_INTERVAL` | database.tcp_keepalives_interval | 1| TCP keepalive interval | +| `INVENTREE_DB_TCP_KEEPALIVES_IDLE` | database.tcp_keepalives_idle | 5 | Idle TCP keepalive | +| `INVENTREE_DB_TCP_KEEPALIVES_INTERVAL` | database.tcp_keepalives_interval | 5 | TCP keepalive interval | | `INVENTREE_DB_TCP_KEEPALIVES_COUNT` | database.tcp_keepalives_count | 5 | TCP keepalive count | +| `INVENTREE_DB_TCP_USER_TIMEOUT` | database.tcp_user_timeout | 2000 | TCP user timeout (ms) | | `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" | ### MySQL Settings @@ -278,6 +286,7 @@ If running with a PostgreSQL database backend, the following additional options If running with a MySQL database backend, the following additional options are available: {{ configtable() }} +{{ configsetting("INVENTREE_DB_TIMEOUT", default="10") }} Database connection timeout (s) | | `INVENTREE_DB_ISOLATION_SERIALIZABLE` | database.serializable | False | Database isolation level configured to "serializable" | ### SQLite Settings @@ -549,6 +558,15 @@ To override global settings, provide a "dictionary" of settings overrides in the {{ configtable() }} {{ configsetting("INVENTREE_GLOBAL_SETTINGS") }} JSON object containing global settings overrides | +## Override Plugin Settings + +If you have plugins installed which require configuration, you can provide plugin settings overrides in the configuration file, or via an environment variable. + +{{ configtable() }} +{{ configsetting("INVENTREE_PLUGIN_SETTINGS") }} JSON object containing plugin settings overrides | + +Note that plugin settings overrides require knowledge of the plugin "slug" and the particular settings which are being overridden. You should refer to the plugin documentation for more information on available settings. If plugin overrides are specified, but no matching plugin is found, the overrides will be ignored. + ## Other Settings Other available settings, not categorized above, are detailed in the table below: diff --git a/docs/docs/start/docker.md b/docs/docs/start/docker.md index f61a4b09a6..a4cdbe3fc1 100644 --- a/docs/docs/start/docker.md +++ b/docs/docs/start/docker.md @@ -93,6 +93,9 @@ The production docker compose configuration outlined on this page uses [Caddy](h The provided `Caddyfile` configuration file is setup to enable [Automatic HTTPS](https://caddyserver.com/docs/automatic-https) by default! All you have to do is specify a `https://` URL in the `INVENTREE_SITE_URL` variable. +!!! warning "Standard Ports Required" + Automatic HTTPS requires that the Caddy container be reachable on the standard ports 80/443, so that it can complete a Let's Encrypt ACME challenge. This will not work if InvenTree is published on a non-standard port, or is running behind another reverse proxy. In those cases, terminate SSL at the external proxy instead, and run Caddy over plain HTTP - refer to [running behind an existing reverse proxy](./processes.md#integrating-with-existing-proxy). + ### Containers The example docker compose file launches the following containers: diff --git a/docs/docs/start/docker_install.md b/docs/docs/start/docker_install.md index 44f60ffba1..d36e0f084a 100644 --- a/docs/docs/start/docker_install.md +++ b/docs/docs/start/docker_install.md @@ -225,6 +225,9 @@ The provided `Caddyfile` configuration file is setup to enable [Automatic HTTPS] The [Caddy](./docker.md#ssl-certificates) container will automatically generate SSL certificates for your domain. +!!! warning "Standard Ports Required" + Automatic HTTPS relies on a Let's Encrypt ACME challenge, which requires that your server be reachable on the standard ports 80 and/or 443. If you are publishing InvenTree on a non-standard port (see [below](#web-server-bind-address)), or your host cannot be reached externally on those ports, automatic HTTPS will fail. In that case, terminate SSL at an external reverse proxy instead - refer to [running behind an existing reverse proxy](./processes.md#integrating-with-existing-proxy). + #### Persistent Files Any persistent files generated by the Caddy container (such as certificates, etc) will be stored in the `caddy` directory within the external volume. @@ -241,6 +244,20 @@ This can be adjusted using the following environment variables: These variables are combined in the [Dockerfile]({{ sourcefile("contrib/container/Dockerfile") }}) to build the bind string passed to the InvenTree server on startup. +!!! warning "Internal Port Only" + `INVENTREE_WEB_PORT` controls the port used *internally* between the `inventree-server` (gunicorn) and `inventree-proxy` (Caddy) containers. It is not the port that other machines on your network connect to, and in most cases should be left at its default value of `8000`. + +#### Proxy (External) Port + +The port that is actually published to your host - and thus reachable by other devices on your network - is controlled separately, via the `inventree-proxy` service: + +| Environment Variable | Default | +| --- | --- | +| `INVENTREE_HTTP_PORT` | 80 | +| `INVENTREE_HTTPS_PORT` | 443 | + +If you want to serve InvenTree on a non-standard port (for example, because port 80/443 is already in use by another service on the same host), set `INVENTREE_HTTP_PORT` and/or `INVENTREE_HTTPS_PORT` in your `.env` file, and update `INVENTREE_SITE_URL` to include the matching port number, e.g. `INVENTREE_SITE_URL="http://192.168.1.10:5143"`. + !!! tip "IPv6 Support" To enable IPv6/Dual Stack support, set `INVENTREE_WEB_ADDR` to `[::]` when you create/start the container. @@ -325,7 +342,7 @@ ARG INVENTREE_TAG # prebuild stage - needs a lot of build dependencies # make sure, the alpine and python version matches the version used in the inventree base image -FROM python:3.11-alpine3.18 as prebuild +FROM python:3.12-alpine3.18 as prebuild # Install whatever development dependency is needed (e.g. cups-dev, gcc, the musl-dev build tools and the pip pycups package) RUN apk add --no-cache cups-dev gcc musl-dev && \ diff --git a/docs/docs/start/processes.md b/docs/docs/start/processes.md index 591e0b407c..070d8be24a 100644 --- a/docs/docs/start/processes.md +++ b/docs/docs/start/processes.md @@ -104,9 +104,17 @@ You may wish to extend the proxy configuration to include additional features, b #### Integrating with Existing Proxy -You may wish to integrate the InvenTree web server with an existing reverse proxy server. This is possible, but requires careful configuration to ensure that the static and media files are served correctly. +You may wish to integrate the InvenTree web server with an existing reverse proxy server - for example, a single NGINX, Traefik, or Caddy instance which already terminates SSL for other services on your network (common on NAS platforms such as TrueNAS, Unraid, or Synology). This is possible, but requires careful configuration to ensure that the static and media files are served correctly, and that InvenTree trusts requests forwarded from the upstream proxy. -*Note: A custom configuration of the proxy server is outside the scope of this documentation!* +*Note: Configuration of your external proxy server itself is outside the scope of this documentation - refer to the documentation for the specific software you are using.* + +The pattern below outlines the InvenTree-side configuration that this setup always requires, regardless of which proxy software sits in front of it: + +- Leave the bundled `inventree-proxy` (Caddy) container serving plain **HTTP** - do not enable [Automatic HTTPS](./docker.md#ssl-certificates), as Caddy will not be reachable directly for the ACME challenge. SSL termination is handled entirely by your existing external proxy instead. +- Publish the `inventree-proxy` container's HTTP port (`INVENTREE_HTTP_PORT`, see [docker_install.md](./docker_install.md#proxy-external-port)) on an address/port that your external proxy can reach, and point the external proxy's upstream/backend at that address. +- Set `INVENTREE_SITE_URL` to the externally-visible URL that users and the external proxy will actually use to reach InvenTree (e.g. `https://inventree.example.com`), even though InvenTree itself is only ever served over plain HTTP internally. +- If the external proxy's public URL differs from `INVENTREE_SITE_URL` (for example, if `INVENTREE_SITE_URL` is set to an internal address rather than the public domain), explicitly add the public URL to [`INVENTREE_TRUSTED_ORIGINS`](./config.md#server-access) - otherwise, form submissions (including login) will fail CSRF validation. +- The forwarded-header settings `INVENTREE_USE_X_FORWARDED_HOST`, `INVENTREE_USE_X_FORWARDED_PORT`, and `INVENTREE_USE_X_FORWARDED_PROTO` (see [Server Access](./config.md#server-access)) are enabled by default in the provided `.env` file, so that InvenTree correctly reports its own HTTPS URL even though it only ever receives plain HTTP traffic from your external proxy. Ensure your external proxy actually sets the corresponding `X-Forwarded-*` headers when forwarding requests. ### Background Worker diff --git a/docs/docs/stock/adjust.md b/docs/docs/stock/adjust.md index 69cf5eaa2c..c536bf0670 100644 --- a/docs/docs/stock/adjust.md +++ b/docs/docs/stock/adjust.md @@ -32,6 +32,8 @@ Remove parts from a stock item record - for example taking parts from stock for Count stock items (stocktake) to record the number of items in stock at a given point of time. The quantity for each part is pre-filled with the current quantity based on stock item history. +An optional **Location** field allows all counted items to be moved to a new location in the same operation. If left blank, each item retains its current location. + {{ image("stock/stock_count.png", "Stock Count") }} ### Merge Stock diff --git a/docs/docs/stock/disassemble.md b/docs/docs/stock/disassemble.md new file mode 100644 index 0000000000..dd03877c35 --- /dev/null +++ b/docs/docs/stock/disassemble.md @@ -0,0 +1,90 @@ +--- +title: Stock Disassembly +--- + +## Stock Disassembly + +A stock item of an [assembly](../part/index.md#assembly) part can be *disassembled* back into its component parts, based on the [Bill of Materials](../manufacturing/bom.md) (BOM) for that part. This is the reverse of building an assembly - instead of consuming components to create an assembled item, the assembled item is broken back down into its constituent components. + +This is useful in a number of scenarios, for example: + +- An assembly is being reworked or scrapped, and the still-usable components need to be returned to stock +- A supplier ships a "bundled" or "kit" product as a single line item, which needs to be split apart into its individual components before the parts can be used or sold separately (see below) +- Correcting an assembly which was built or received in error + +Disassembly is only available for a stock item whose part is marked as an *assembly*, and requires that the part has at least one [BOM line item](../manufacturing/bom.md#bom-line-items) defined. + +To disassemble a stock item, navigate to the stock item detail page and select the *Disassemble* option from the actions menu. This requires that the user has the *Stock: Add* permission, and that the stock item is currently [in stock](./status.md). + +{{ image("stock/stock_options.png", "Stock Options") }} + +### Disassembly Form + +The disassembly form is pre-populated with one line per BOM line item defined for the part, based on the quantity of assemblies being disassembled. Any line item marked as [consumable](../manufacturing/bom.md#consumable-bom-line-items) (whether the BOM line itself or its underlying part is marked consumable), or which points to a [virtual](../part/index.md) part, is excluded, as these components are not expected to be tracked as physical stock. This exclusion is enforced by the API - such a BOM line cannot be submitted for disassembly, even if referenced directly. + +For each line, the following values may be adjusted: + +| Field | Description | +| --- | --- | +| Quantity | The total quantity of the component part to generate. This is automatically scaled as the top-level *Quantity* field is changed, unless the user has manually edited it | +| Location | An optional destination location for the generated stock item. If not specified, the component is placed in the same location as the disassembled item (or the default location specified at the top of the form) | +| Status | An optional [stock status](./status.md) to apply to the generated stock item. If not specified, the component is created with the default *OK* status | +| Unit Price | An optional purchase price to record against the generated stock item. If left blank, a price is calculated automatically (see below) | + +A line item can be removed from the form entirely if that particular component is not required to be split out - for example, if it is being scrapped rather than returned to stock. A line cannot be removed if it has installed items associated with it (see below). + +### Quantity + +Only the *available* quantity of a stock item can be disassembled. A [serialized](./traceability.md#serial-numbers) stock item does not have an adjustable quantity - since it represents a single physical unit, it must always be disassembled in its entirety. + +The original stock item is never deleted as a result of disassembly - its quantity is reduced by the disassembled amount, in order to preserve traceability. If a stock item is disassembled down to a zero quantity, it is retained in the database (in an *unavailable* state) rather than removed, even if the item has the [Delete on Deplete](./availability.md#delete-on-deplete) flag set. A serialized item cannot be reduced to a zero quantity, so in this case the original item is instead marked with a *Destroyed* status. + +### Accounting for Installed Items + +If the stock item being disassembled has other stock items [installed](../manufacturing/allocate.md#allocating-tracked-stock) within it (for example, tracked components that were installed during a build order), these installed items **must** be accounted for during disassembly: + +- Each installed item is matched against a BOM line item, based on the component part (including any [substitute](../manufacturing/bom.md#substitute-bom-line-items) or [variant](../part/index.md#assembly) parts allowed for that line) +- Matched installed items are *uninstalled* directly, rather than being discarded and re-created - this preserves the original stock item, including its own tracking history, batch code, and purchase price +- The quantity requested for the matching BOM line is reduced by the quantity already covered by the installed item(s). A new stock item is only created for any remaining quantity - if the installed items fully cover the required quantity, no new stock item is created for that line +- Any installed item which does *not* match one of the selected BOM lines is still uninstalled (it cannot be left "installed" inside a smaller or non-existent parent), but its quantity is **not** subtracted from any line + +Because installed items cannot be partially accounted for, **a stock item with any installed items must be disassembled in its entirety** - a partial disassembly (disassembling less than the full available quantity) is rejected if any items are currently installed. + +The disassembly form displays a count of installed items against each matching BOM line, and lists any "leftover" installed items (which do not match a BOM line) in a separate warning panel. + +### Automatic Cost Allocation + +If the original stock item has a recorded purchase price, and no explicit *Unit Price* has been entered for the generated lines, InvenTree attempts to automatically apportion that cost across the newly generated components: + +- The total cost (unit purchase price × disassembled quantity) is split across the lines, weighted by the existing [pricing](../part/pricing.md) data (average of minimum and maximum overall price) for each component part +- If pricing data is not available for *every* line, the cost is instead split evenly on a per-unit basis across all generated units +- Cost is only allocated across newly *created* stock items - any matched installed items retain their own existing purchase price, and are excluded from the cost split entirely +- If any line has an explicit *Unit Price* provided by the user, automatic cost allocation is skipped entirely, and prices are only applied where explicitly set + +### Traceability + +Disassembling a stock item generates a full audit trail: + +- A `Disassembled into components` entry is added to the tracking history of the original stock item +- Each newly created component stock item receives a `Created from disassembly` tracking entry, referencing the original stock item +- The *batch code* and source *purchase order* of the original stock item are copied directly to each generated component +- If the original stock item was generated by a build order, that build order cannot be directly copied to the new component (since the component was not actually built by that order) - instead, it is recorded as a reference within the `Created from disassembly` tracking entry + +### Purchasing Bundled Items + +Some suppliers only sell a group of components as a single bundled or "kit" product, rather than as individual purchasable line items. Such a bundle can be modelled as an assembly part, purchased and received as a single stock item, and later disassembled into its individual components - with purchase price and traceability data automatically apportioned across the generated components, as described above. + +Refer to the [Bundled Items](../purchasing/purchase_order.md#bundled-items) documentation for a full description of how to set this up. + +### Enforced Limitations + +The following limitations are enforced when disassembling a stock item: + +- The part associated with the stock item must be marked as an *assembly* +- The stock item must currently be [in stock](./status.md) - for example, it cannot be allocated to a sales order, installed in another assembly, or already fully consumed +- At least one BOM line item must be selected for disassembly +- The disassembly quantity cannot exceed the available quantity of the stock item +- A serialized stock item must be disassembled in its entirety (its quantity cannot be partially reduced) +- Each BOM line may only be referenced once per disassembly operation +- A selected BOM line must be a valid line item for the part associated with the stock item +- If the stock item has any installed items, it must be disassembled in its entirety diff --git a/docs/docs/stock/tracking.md b/docs/docs/stock/tracking.md index 309c682ba7..6ece3f08aa 100644 --- a/docs/docs/stock/tracking.md +++ b/docs/docs/stock/tracking.md @@ -40,6 +40,31 @@ This view displays all tracking entries associated with any stock item linked to !!! info "Deleted Stock Items" Even if a stock item is deleted from the system, the associated stock tracking entries are retained for historical reference. They will be visible in the part tracking history, but not in the stock item tracking history (as the stock item itself has been deleted). +## Installed Stock Items + +A stock item can be *installed* inside another stock item, forming a parent/child relationship between the two. This is used to represent physical assembly - for example, a serialized PCB assembly which has been fitted with a tracked sub-component, such as a wireless module or a pre-programmed IC. + +An installed stock item is no longer available for regular stock actions (it cannot be moved, allocated to an order, or built into another assembly) while it remains installed - it is only accessible "through" its parent item. + +### How Items Become Installed + +There are two ways that a stock item can become installed inside another: + +- **Tracked build allocation** - when a [tracked BOM item](../manufacturing/allocate.md#allocating-tracked-stock) is allocated to a build order and the build output is completed, the allocated stock item is automatically installed into the completed build output +- **Manual installation** - from the *Stock Item Detail* page, a user can manually install one stock item into another, using the *Install Item* action. By default, the selected item's part must appear in the [Bill of Materials](../manufacturing/bom.md) of the parent item's part - this check can be disabled using the {{ globalsetting("STOCK_ENFORCE_BOM_INSTALLATION", short=True) }} setting + +### Viewing Installed Items + +Any stock items installed within a particular stock item are displayed on the *Installed Items* tab of the *Stock Item Detail* page. + +By default, installed stock items are hidden from general stock item tables (as they are not directly available for use) - this can be changed using the {{ globalsetting("STOCK_SHOW_INSTALLED_ITEMS", short=True) }} setting. + +### Removing Installed Items + +An installed stock item can be removed (uninstalled) from its parent using the *Uninstall Item* action, which returns the item to a selected stock location and makes it available for regular stock actions once more. + +Additionally, installed items are automatically uninstalled when the parent item is [disassembled](./disassemble.md#accounting-for-installed-items) into its component parts - refer to that page for a detailed description of how installed items are matched against Bill of Materials line items during disassembly. + ## Stock Tracking Settings There are a number of configuration options available for controlling the behavior of stock tracking functionality in the [system settings view](../settings/global.md): diff --git a/docs/docs/stock/transfer_order.md b/docs/docs/stock/transfer_order.md index 12381255e5..b5648f4505 100644 --- a/docs/docs/stock/transfer_order.md +++ b/docs/docs/stock/transfer_order.md @@ -148,3 +148,4 @@ The following [global settings](../settings/global.md) are available for transfe {{ globalsetting("TRANSFERORDER_ENABLED") }} {{ globalsetting("TRANSFERORDER_REFERENCE_PATTERN") }} {{ globalsetting("TRANSFERORDER_REQUIRE_RESPONSIBLE") }} +{{ globalsetting("TRANSFERORDER_EDIT_COMPLETED_ORDERS") }} diff --git a/docs/main.py b/docs/main.py index 148e61be65..9e44c5e8b1 100644 --- a/docs/main.py +++ b/docs/main.py @@ -442,6 +442,75 @@ def define_env(env): return ret_data + def render_attribute_table(attributes: dict, title: str) -> str: + """Render a table of field/property information, in a collapsible (collapsed by default) block. + + Returns an empty string (including no block) if there is nothing to display. + """ + if not attributes: + return '' + + table = '| Variable | Type | Description |\n| --- | --- | --- |\n' + + for k, v in sorted(attributes.items()): + description = ' '.join(v['description'].split()) + table += f'| {k} | `{v["type"]}` | {description} |\n' + + ret_data = f'??? note "{title}"\n\n' + ret_data += textwrap.indent(table, ' ') + + # Trailing blank line, so consecutive macro calls (e.g. fields followed by + # properties) don't run together when the template places them on adjacent lines + return ret_data + '\n' + + @env.macro + def reportable_model_context(): + """Render the full 'reportable model types' section. + + One heading plus fields/properties tables per model which templates can be + rendered against (e.g. `Part`, `SalesOrder`, `StockItem`). The list of models + comes directly from what `export_report_context` discovered via the + `InvenTreeReportMixin`, so there is no manually-maintained per-model heading + list to keep in sync here. + """ + global REPORT_CONTEXT + + models = REPORT_CONTEXT.get('models', {}) + + ret_data = '' + + for info in sorted(models.values(), key=lambda item: item['name']): + ret_data += f'### {info["name"]}\n\n' + ret_data += render_attribute_table(info.get('fields', {}), 'Fields') + ret_data += render_attribute_table(info.get('properties', {}), 'Properties') + + return ret_data + + @env.macro + def related_model_context(): + """Render the full 'related model types' section. + + A "related" model is one which is not itself reportable, but which is + referenced by a field or `@report_attribute` property on a reportable model + (e.g. `PartCategory` via `Part.category`, `SupplierPart` via `Part.default_supplier`). + + These are discovered automatically (one hop out from the reportable models) by + the `export_report_context` management command, so there is no manually-maintained + list of related models to keep in sync here. + """ + global REPORT_CONTEXT + + related = REPORT_CONTEXT.get('related_models', {}) + + ret_data = '' + + for info in sorted(related.values(), key=lambda item: item['name']): + ret_data += f'### {info["name"]}\n\n' + ret_data += render_attribute_table(info.get('fields', {}), 'Fields') + ret_data += render_attribute_table(info.get('properties', {}), 'Properties') + + return ret_data + @env.macro def icon( source: str, diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index ca0bb711ff..833abd5f90 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -87,11 +87,16 @@ nav: - Project Details: - Governance: project/governance.md - Project Security: security.md - - Resources: project/resources.md + - Sponsored Resources: project/sponsored_resources.md - Privacy: privacy.md - Concepts: - Terminology: concepts/terminology.md - - User Interface: concepts/user_interface.md + - User Interface: + - Overview: concepts/ui/index.md + - Tables: concepts/ui/tables.md + - Preview Panels: concepts/ui/preview_panels.md + - Forms: concepts/ui/forms.md + - Global Search: concepts/ui/global_search.md - Threat Model: concepts/threat_model.md - Physical Units: concepts/units.md - Companies: concepts/company.md @@ -102,6 +107,7 @@ nav: - Project Codes: concepts/project_codes.md - Attachments: concepts/attachments.md - Parameters: concepts/parameters.md + - Tags: concepts/tags.md - Barcodes: - Barcode Support: barcodes/index.md - Internal Barcodes: barcodes/internal.md @@ -129,6 +135,7 @@ nav: - Parts: part/index.md - Creating Parts: part/create.md - Virtual Parts: part/virtual.md + - Consumable Parts: part/consumable.md - Part Views: part/views.md - Tracking: part/trackable.md - Revisions: part/revision.md @@ -144,6 +151,7 @@ nav: - Stock Tracking: stock/tracking.md - Stock Status: stock/status.md - Adjusting Stock: stock/adjust.md + - Stock Disassembly: stock/disassemble.md - Stock Expiry: stock/expiry.md - Stock Ownership: stock/owner.md - Test Results: stock/test.md @@ -173,7 +181,10 @@ nav: - Template Editor: report/template_editor.md - Reports: report/report.md - Labels: report/labels.md - - Context Variables: report/context_variables.md + - Report Assets: report/assets.md + - Report Snippets: report/snippets.md + - Report Context: report/context_variables.md + - Model Context: report/model_context.md - Helper Functions: report/helpers.md - Barcodes: report/barcodes.md - Sample Templates: report/samples.md @@ -181,7 +192,8 @@ nav: - Global Settings: settings/global.md - User Settings: settings/user.md - Reference Patterns: settings/reference.md - - Admin Interface: settings/admin.md + - Admin Center: settings/admin.md + - Database Admin Interface: settings/db_admin.md - Setup: - User Permissions: settings/permissions.md - Single Sign on: settings/SSO.md @@ -365,7 +377,7 @@ extra: # provider: google # property: UA-143467500-1 - min_python_version: 3.11 + min_python_version: 3.12 min_invoke_version: 2.0.0 django_version: 5.2 docker_postgres_version: 17 diff --git a/docs/mlc_config.json b/docs/mlc_config.json index a3e538ca10..91d6692af8 100644 --- a/docs/mlc_config.json +++ b/docs/mlc_config.json @@ -31,9 +31,6 @@ }, { "pattern": "https://opensource.org/license/MIT" - }, - { - "pattern": "^https://dev.azure.com" } ] } diff --git a/docs/requirements.in b/docs/requirements.in index 7e88513072..b3368f1347 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,10 +1,10 @@ mkdocs==1.6.1 mkdocs-macros-plugin>=0.7,<2.0 -mkdocs-material>=9.0,<10.0 -mkdocs-git-revision-date-localized-plugin>=1.1,<2.0 +mkdocs-material>=9.7.7,<10.0 +mkdocs-git-revision-date-localized-plugin>=1.5.3,<2.0 mkdocs-redirects mkdocs-simple-hooks>=0.1,<1.0 mkdocs-include-markdown-plugin neoteroi-mkdocs -mkdocstrings[python]<=1.0.4,>=1.0.4 +mkdocstrings[python] mkdocs-mermaid2-plugin diff --git a/docs/requirements.txt b/docs/requirements.txt index 4248102d6e..d2475fe4db 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,8 +1,8 @@ # This file was autogenerated by uv via the following command: # uv pip compile docs/requirements.in -o docs/requirements.txt -c src/backend/requirements.txt -anyio==4.12.1 \ - --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ - --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c +anyio==4.14.2 \ + --hash=sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494 \ + --hash=sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f # via httpx babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ @@ -11,167 +11,130 @@ babel==2.18.0 \ # -c src/backend/requirements.txt # mkdocs-git-revision-date-localized-plugin # mkdocs-material -backrefs==6.2 \ - --hash=sha256:08aa7fae530c6b2361d7bdcbda1a7c454e330cc9dbcd03f5c23205e430e5c3be \ - --hash=sha256:0fdc7b012420b6b144410342caeb8adc54c6866cf12064abc9bb211302e496f8 \ - --hash=sha256:12df81596ab511f783b7d87c043ce26bc5b0288cf3bb03610fe76b8189282b2b \ - --hash=sha256:664e33cd88c6840b7625b826ecf2555f32d491800900f5a541f772c485f7cda7 \ - --hash=sha256:c3f4b9cb2af8cda0d87ab4f57800b57b95428488477be164dd2b47be54db0c90 \ - --hash=sha256:e5f805ae09819caa1aa0623b4a83790e7028604aa2b8c73ba602c4454e665de7 \ - --hash=sha256:f44ff4d48808b243b6c0cdc6231e22195c32f77046018141556c66f8bab72a49 +backrefs==7.0 \ + --hash=sha256:4989bb9e1e99eb23647c7160ed51fb21d0b41b5d200f2d3017da41e023097e82 \ + --hash=sha256:a0fa7360c63509e9e077e174ef4e6d3c21c8db94189b9d957289ae6d794b9475 \ + --hash=sha256:a6448b28180e3ca01134c9cf09dcebafad8531072e09903c5451748a05f24bc9 \ + --hash=sha256:b57cd227ea556b0aed3dc9b8da4628db4eabc0402c6d7fcfc69283a93955f7e9 \ + --hash=sha256:ca42ce6a49ace3d75684dfa9937f3373902a63284ecb385ce36d15e5dcb41c12 \ + --hash=sha256:f2c52955d631b9e1ac4cd56209f0a3a946d592b98e7790e77699339ae01c102a # via mkdocs-material -beautifulsoup4==4.14.3 \ - --hash=sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb \ - --hash=sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86 +beautifulsoup4==4.15.0 \ + --hash=sha256:288e3ca7d54b06f2ac191970bc275c1939cb46d450b255bf6718b04aa37ab4f7 \ + --hash=sha256:d6f88de62e1d4e38ecb1077eb9724cd0eff29d2a08ca16a401e9b9e93f117cf9 # via mkdocs-mermaid2-plugin -bracex==2.6 \ - --hash=sha256:0b0049264e7340b3ec782b5cb99beb325f36c3782a32e36e876452fd49a09952 \ - --hash=sha256:98f1347cd77e22ee8d967a30ad4e310b233f7754dbf31ff3fceb76145ba47dc7 +bracex==3.0 \ + --hash=sha256:3833e61c2f092d5aa0468fa2e6c6e990a306185abf763b6d122f0158e59c58a5 \ + --hash=sha256:b73f718d6bd98d8419e45df02426c86e9967c179949f779340d6c3a8c83b9111 # via wcmatch -certifi==2026.4.22 \ - --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ - --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 +certifi==2026.7.22 \ + --hash=sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775 \ + --hash=sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55 # via # -c src/backend/requirements.txt # httpcore # httpx # requests -charset-normalizer==3.4.7 \ - --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ - --hash=sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c \ - --hash=sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67 \ - --hash=sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4 \ - --hash=sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0 \ - --hash=sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c \ - --hash=sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5 \ - --hash=sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444 \ - --hash=sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153 \ - --hash=sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9 \ - --hash=sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01 \ - --hash=sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217 \ - --hash=sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b \ - --hash=sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c \ - --hash=sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a \ - --hash=sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83 \ - --hash=sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5 \ - --hash=sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7 \ - --hash=sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb \ - --hash=sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c \ - --hash=sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1 \ - --hash=sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42 \ - --hash=sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab \ - --hash=sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df \ - --hash=sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e \ - --hash=sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207 \ - --hash=sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18 \ - --hash=sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734 \ - --hash=sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38 \ - --hash=sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110 \ - --hash=sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18 \ - --hash=sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44 \ - --hash=sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d \ - --hash=sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48 \ - --hash=sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e \ - --hash=sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5 \ - --hash=sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d \ - --hash=sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53 \ - --hash=sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790 \ - --hash=sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c \ - --hash=sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b \ - --hash=sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116 \ - --hash=sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d \ - --hash=sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10 \ - --hash=sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6 \ - --hash=sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2 \ - --hash=sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776 \ - --hash=sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a \ - --hash=sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265 \ - --hash=sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008 \ - --hash=sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943 \ - --hash=sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374 \ - --hash=sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246 \ - --hash=sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e \ - --hash=sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5 \ - --hash=sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616 \ - --hash=sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15 \ - --hash=sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41 \ - --hash=sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960 \ - --hash=sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752 \ - --hash=sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e \ - --hash=sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72 \ - --hash=sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7 \ - --hash=sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8 \ - --hash=sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b \ - --hash=sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4 \ - --hash=sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545 \ - --hash=sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706 \ - --hash=sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366 \ - --hash=sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb \ - --hash=sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a \ - --hash=sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e \ - --hash=sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00 \ - --hash=sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f \ - --hash=sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a \ - --hash=sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1 \ - --hash=sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66 \ - --hash=sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356 \ - --hash=sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319 \ - --hash=sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4 \ - --hash=sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad \ - --hash=sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d \ - --hash=sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5 \ - --hash=sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7 \ - --hash=sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0 \ - --hash=sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686 \ - --hash=sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34 \ - --hash=sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49 \ - --hash=sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c \ - --hash=sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1 \ - --hash=sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e \ - --hash=sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60 \ - --hash=sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0 \ - --hash=sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274 \ - --hash=sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d \ - --hash=sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0 \ - --hash=sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae \ - --hash=sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f \ - --hash=sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d \ - --hash=sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe \ - --hash=sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3 \ - --hash=sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393 \ - --hash=sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1 \ - --hash=sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af \ - --hash=sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44 \ - --hash=sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00 \ - --hash=sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c \ - --hash=sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3 \ - --hash=sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7 \ - --hash=sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd \ - --hash=sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e \ - --hash=sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b \ - --hash=sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8 \ - --hash=sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259 \ - --hash=sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859 \ - --hash=sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46 \ - --hash=sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30 \ - --hash=sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b \ - --hash=sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46 \ - --hash=sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24 \ - --hash=sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a \ - --hash=sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24 \ - --hash=sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc \ - --hash=sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215 \ - --hash=sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063 \ - --hash=sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832 \ - --hash=sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6 \ - --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ - --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 +charset-normalizer==3.4.9 \ + --hash=sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380 \ + --hash=sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62 \ + --hash=sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c \ + --hash=sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226 \ + --hash=sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5 \ + --hash=sha256:0fa1aec2d32bcc03c8fa0f6f1712caad1adc38509f31142112e5c9daf5b9c833 \ + --hash=sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b \ + --hash=sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99 \ + --hash=sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501 \ + --hash=sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec \ + --hash=sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698 \ + --hash=sha256:231ddcbb35e2ff8973e1365db41fe0572662893b99a05deb183b68ad4c0c8bd4 \ + --hash=sha256:253a4a220747e8b5faf57ec320c4f5efb0cef05f647420bf267143ec15dba10a \ + --hash=sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3 \ + --hash=sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2 \ + --hash=sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a \ + --hash=sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e \ + --hash=sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4 \ + --hash=sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419 \ + --hash=sha256:3c09a49d6cde137258beb3d551994a2927fd35ad5cf96aed573f61bbd67c5f84 \ + --hash=sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da \ + --hash=sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519 \ + --hash=sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe \ + --hash=sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381 \ + --hash=sha256:43b9e366a31fdd1c87d0eb08f579b4a82b723ea54338f040d6b4e518a026ea29 \ + --hash=sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614 \ + --hash=sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0 \ + --hash=sha256:476743fe6dfe14a2da12e3ac79125dc84a3b2cf8094369a47a1529b0cd8549fe \ + --hash=sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29 \ + --hash=sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0 \ + --hash=sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917 \ + --hash=sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9 \ + --hash=sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32 \ + --hash=sha256:58150c9f9b9a552505912d182ccdf26f6396fb6094816ceebcbb20eecabaed94 \ + --hash=sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63 \ + --hash=sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd \ + --hash=sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198 \ + --hash=sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde \ + --hash=sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012 \ + --hash=sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1 \ + --hash=sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15 \ + --hash=sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b \ + --hash=sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993 \ + --hash=sha256:68ce9f4d6b26d5ccbf7fd4459bf75f74a0a146677ebba80597df60cbdb20e6f4 \ + --hash=sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5 \ + --hash=sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8 \ + --hash=sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35 \ + --hash=sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642 \ + --hash=sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2 \ + --hash=sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d \ + --hash=sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9 \ + --hash=sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c \ + --hash=sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33 \ + --hash=sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db \ + --hash=sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf \ + --hash=sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9 \ + --hash=sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee \ + --hash=sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84 \ + --hash=sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44 \ + --hash=sha256:920079c3f7456fa213e0829ed2073aaa727fd39d889ead5b4f35d0de5460d04f \ + --hash=sha256:93d59d504b230e83c7a843251681959a0b6a9cd76f6e146ce1b8a80eb8739af9 \ + --hash=sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9 \ + --hash=sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177 \ + --hash=sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8 \ + --hash=sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b \ + --hash=sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39 \ + --hash=sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41 \ + --hash=sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0 \ + --hash=sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616 \ + --hash=sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d \ + --hash=sha256:ad41ba96094304aa090f5a30cb6e4fb3b3f1c264c523394b4c39bbacc4dc92ba \ + --hash=sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2 \ + --hash=sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b \ + --hash=sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9 \ + --hash=sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b \ + --hash=sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209 \ + --hash=sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48 \ + --hash=sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046 \ + --hash=sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632 \ + --hash=sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a \ + --hash=sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2 \ + --hash=sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1 \ + --hash=sha256:ddf4af30b417d9fe16481e9b81c27ab2a7cde1ff7ba3e85653b02db7d145dc7b \ + --hash=sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990 \ + --hash=sha256:df7276909358e5635ae203673ab7e509ddd224225a8d6b0790bf13eb2bde1cc5 \ + --hash=sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b \ + --hash=sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9 \ + --hash=sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534 \ + --hash=sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81 \ + --hash=sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a \ + --hash=sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d \ + --hash=sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf \ + --hash=sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115 # via # -c src/backend/requirements.txt # requests -click==8.3.3 \ - --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ - --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 +click==8.4.2 \ + --hash=sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6 \ + --hash=sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76 # via # mkdocs # neoteroi-mkdocs @@ -202,12 +165,13 @@ gitdb==4.0.12 \ --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf # via gitpython -gitpython==3.1.50 \ - --hash=sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc \ - --hash=sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9 +gitpython==3.1.58 \ + --hash=sha256:621416df10ef3fd0e19fabf9172ddeed0fa704d353d04f194eec56a625a95b22 \ + --hash=sha256:d331e722577f0fd7fc1f857419b3ecc07af66282b933d2a4d95f84a042fdd50f # via mkdocs-git-revision-date-localized-plugin -griffelib==2.0.0 \ - --hash=sha256:01284878c966508b6d6f1dbff9b6fa607bc062d8261c5c7253cb285b06422a7f +griffelib==2.1.0 \ + --hash=sha256:762a186d2c6fd6794d4ea20d428d597ffb857cb56b66421651cbba15bdd5e813 \ + --hash=sha256:cc7b3d2d2865ad0b909fcc38086e3f554b5ea7acbaa7bbb7ecaa3f5dfb7d9f00 # via mkdocstrings-python h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ @@ -227,9 +191,9 @@ httpx==0.28.1 \ --hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \ --hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad # via neoteroi-mkdocs -idna==3.15 \ - --hash=sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8 \ - --hash=sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc +idna==3.18 \ + --hash=sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2 \ + --hash=sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848 # via # -c src/backend/requirements.txt # anyio @@ -246,13 +210,13 @@ jinja2==3.1.6 \ # mkdocstrings # neoteroi-mkdocs # properdocs -jsbeautifier==1.15.4 \ - --hash=sha256:5bb18d9efb9331d825735fbc5360ee8f1aac5e52780042803943aa7f854f7592 \ - --hash=sha256:72f65de312a3f10900d7685557f84cb61a9733c50dcc27271a39f5b0051bf528 +jsbeautifier==2.0.3 \ + --hash=sha256:9579d4e9dbaa00383f3efdff4c98c8140bb85ba319398e8b97cdaba27abd6ba3 \ + --hash=sha256:f0190e279a2cdb827556ada63f41c9c63c11f8116ee06e264b24aa50311cbee3 # via mkdocs-mermaid2-plugin -markdown==3.10.2 \ - --hash=sha256:994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950 \ - --hash=sha256:e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36 +markdown==3.10.3 \ + --hash=sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f \ + --hash=sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea # via # -c src/backend/requirements.txt # mkdocs @@ -261,9 +225,9 @@ markdown==3.10.2 \ # mkdocstrings # properdocs # pymdown-extensions -markdown-it-py==4.0.0 \ - --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ - --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 +markdown-it-py==4.2.0 \ + --hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \ + --hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a # via rich markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -398,21 +362,21 @@ mkdocs-get-deps==0.2.2 \ --hash=sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1 \ --hash=sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650 # via mkdocs -mkdocs-git-revision-date-localized-plugin==1.5.1 \ - --hash=sha256:2b0239455cd84784dd87ac8dfc9253fe4b2dd35e102696f21b5d34e2175981c6 \ - --hash=sha256:b00fd36ed0f9b2326b1488fd8fa31bf2ce64e68c4aa60a9ce857f10719571903 +mkdocs-git-revision-date-localized-plugin==1.5.3 \ + --hash=sha256:873444b54cab4d47c69bd6e85da05ef5fbe81fee27e64508114c46a0e4f81e37 \ + --hash=sha256:cd96e432de6a7e59b31c7041574b22f84179c8636835419ff458877ecfaaaf05 # via -r docs/requirements.in -mkdocs-include-markdown-plugin==7.2.2 \ - --hash=sha256:f052ccb741eccf498116b826c1d78a2d761c56747372594709441cee0963fbc9 \ - --hash=sha256:f2ec4487cf32d3e33ca528f9366f20fb9280ded9c8d1630eb2bbda244962dcd1 +mkdocs-include-markdown-plugin==7.3.0 \ + --hash=sha256:2800126746452e31c2e321bbd43c8190b356e0de353e20cbc16a34a3c3d6796c \ + --hash=sha256:5b5c99b5d3c9b9ce0114a9e60353bbafb6be53a26c2d3b74ec6b767a7a8e55ca # via -r docs/requirements.in mkdocs-macros-plugin==1.5.0 \ --hash=sha256:12aa45ce7ecb7a445c66b9f649f3dd05e9b92e8af6bc65e4acd91d26f878c01f \ --hash=sha256:c10fabd812bf50f9170609d0ed518e54f1f0e12c334ac29141723a83c881dd6f # via -r docs/requirements.in -mkdocs-material==9.7.6 \ - --hash=sha256:00bdde50574f776d328b1862fe65daeaf581ec309bd150f7bff345a098c64a69 \ - --hash=sha256:71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba +mkdocs-material==9.7.7 \ + --hash=sha256:8ea9bb1737a5b524a5f9dcf2e1b4ebda8274ae3008aa7845720a97083bef708f \ + --hash=sha256:c0649c065b1b0512d60aad8c10f947f8e455284475239b364b610f2deb4d0855 # via -r docs/requirements.in mkdocs-material-extensions==1.3.1 \ --hash=sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443 \ @@ -430,23 +394,23 @@ mkdocs-simple-hooks==0.1.5 \ --hash=sha256:dddbdf151a18723c9302a133e5cf79538be8eb9d274e8e07d2ac3ac34890837c \ --hash=sha256:efeabdbb98b0850a909adee285f3404535117159d5cb3a34f541d6eaa644d50a # via -r docs/requirements.in -mkdocstrings[python]==1.0.4 \ - --hash=sha256:3969a6515b77db65fd097b53c1b7aa4ae840bd71a2ee62a6a3e89503446d7172 \ - --hash=sha256:63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b +mkdocstrings[python]==1.0.6 \ + --hash=sha256:2703708697487d1b6d6d7b412e176fa436edf120c1bf81dc9e126b12d00893c7 \ + --hash=sha256:a0b8c2bdd29a6416c80d717aa369bbf7831946bd9f23c2a66db1b1dbe7693dbd # via # -r docs/requirements.in # mkdocstrings-python -mkdocstrings-python==2.0.3 \ - --hash=sha256:0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12 \ - --hash=sha256:c518632751cc869439b31c9d3177678ad2bfa5c21b79b863956ad68fc92c13b8 +mkdocstrings-python==2.0.5 \ + --hash=sha256:30c837bbff016549f659fcba6539ac351303f0fd7e713c89a040611072236e9d \ + --hash=sha256:3a4d92556ad39637e88af94a5374213af9a8e3040c3824ceaed04b486c017594 # via mkdocstrings neoteroi-mkdocs==1.2.0 \ --hash=sha256:58e25cb1b9db093ffa8d12bdb33264bf567cac30fb964b56e0a493efa749ad6e \ --hash=sha256:91b6aa95a4e46c9bb93e00e021d2044cb0c7d80c0b4600434ff8f440d613a0a8 # via -r docs/requirements.in -packaging==26.2 \ - --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ - --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 +packaging==26.3 \ + --hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \ + --hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c # via # -c src/backend/requirements.txt # mkdocs @@ -456,16 +420,16 @@ paginate==0.5.7 \ --hash=sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945 \ --hash=sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591 # via mkdocs-material -pathspec==1.0.4 \ - --hash=sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645 \ - --hash=sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723 +pathspec==1.1.1 \ + --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ + --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via # mkdocs # mkdocs-macros-plugin # properdocs -platformdirs==4.9.6 \ - --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ - --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 +platformdirs==4.11.0 \ + --hash=sha256:0555d18370482847566ffabcaa53ad7c6c1c29f195989ae1ed634a05f76ea1e0 \ + --hash=sha256:360ccded2b7fce0af0ff80cc8f5942a1c5d99b0e856033acb030bfc634709e74 # via # -c src/backend/requirements.txt # mkdocs-get-deps @@ -480,9 +444,9 @@ pygments==2.20.0 \ # via # mkdocs-material # rich -pymdown-extensions==10.21.3 \ - --hash=sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354 \ - --hash=sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6 +pymdown-extensions==11.0.1 \ + --hash=sha256:db3943a62bab7e03af1364f0c4083e64b91fb097675a4b6cceccfbe9a77e5eb2 \ + --hash=sha256:dd2905ae6fc5b75582fafb139a1266ffc754705efa902aa50067fa7ff4f94ec0 # via # mkdocs-material # mkdocs-mermaid2-plugin @@ -583,9 +547,9 @@ pyyaml-env-tag==1.1 \ # via # mkdocs # properdocs -requests==2.33.1 \ - --hash=sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517 \ - --hash=sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed # via # -c src/backend/requirements.txt # mkdocs-macros-plugin @@ -595,9 +559,9 @@ rich==15.0.0 \ --hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \ --hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36 # via neoteroi-mkdocs -setuptools==82.0.1 \ - --hash=sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9 \ - --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb +setuptools==83.0.0 \ + --hash=sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef \ + --hash=sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3 # via # -c src/backend/requirements.txt # mkdocs-mermaid2-plugin @@ -606,15 +570,14 @@ six==1.17.0 \ --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 # via # -c src/backend/requirements.txt - # jsbeautifier # python-dateutil smmap==5.0.3 \ --hash=sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c \ --hash=sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f # via gitdb -soupsieve==2.8.3 \ - --hash=sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349 \ - --hash=sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 +soupsieve==2.8.4 \ + --hash=sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e \ + --hash=sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65 # via beautifulsoup4 super-collections==0.6.2 \ --hash=sha256:0c8d8abacd9fad2c7c1c715f036c29f5db213f8cac65f24d45ecba12b4da187a \ @@ -624,9 +587,9 @@ termcolor==3.3.0 \ --hash=sha256:348871ca648ec6a9a983a13ab626c0acce02f515b9e1983332b17af7979521c5 \ --hash=sha256:cf642efadaf0a8ebbbf4bc7a31cec2f9b5f21a9f726f4ccbb08192c9c26f43a5 # via mkdocs-macros-plugin -typing-extensions==4.15.0 \ - --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ - --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 +typing-extensions==4.16.0 \ + --hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \ + --hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5 # via # -c src/backend/requirements.txt # anyio @@ -671,7 +634,7 @@ watchdog==6.0.0 \ # via # mkdocs # properdocs -wcmatch==10.1 \ - --hash=sha256:5848ace7dbb0476e5e55ab63c6bbd529745089343427caa5537f230cc01beb8a \ - --hash=sha256:f11f94208c8c8484a16f4f48638a85d771d9513f4ab3f37595978801cb9465af +wcmatch==11.0 \ + --hash=sha256:3a5977ace27e075eef67eb03d539563f1a19018b62881949a42932cf66926934 \ + --hash=sha256:55d95c2447789712774b198ceec72939e88b5618f1f8f0a9b605bf7740b63b96 # via mkdocs-include-markdown-plugin diff --git a/pyproject.toml b/pyproject.toml index 169e5a1f89..1076f0896a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,25 +97,24 @@ skip-magic-trailing-comma = true line-ending = "auto" [tool.uv.pip] -python-version = "3.11" +python-version = "3.12" no-strip-extras=true generate-hashes=true [tool.ty.environment] -root = ["src/backend/InvenTree"] +extra-paths = ["src/backend/InvenTree"] [tool.ty.rules] -unresolved-reference="ignore" # 21 # see https://github.com/astral-sh/ty/issues/220 -unresolved-attribute="ignore" # 505 # need Plugin Mixin typing +unresolved-attribute="ignore" # 837 # need Plugin Mixin typing call-non-callable="ignore" # 8 ## -invalid-assignment="ignore" # 17 # need to wait for better django field stubs -# invalid-method-override="ignore" # 99 -invalid-return-type="ignore" # 22 ## -# possibly-missing-attribute="ignore" # 25 # https://github.com/astral-sh/ty/issues/164 -unknown-argument="ignore" # 3 # need to wait for better django field stubs +invalid-assignment="ignore" # 40 # need to wait for better django field stubs +invalid-method-override="ignore" # 103 +invalid-return-type="ignore" # 44 ## invalid-argument-type="ignore" # 49 -no-matching-overload="ignore" # 3 # need to wait for betterdjango field stubs -possibly-unbound-attribute="ignore" # 21 +no-matching-overload="ignore" # 10 # need to wait for betterdjango field stubs + +# warn about unused ignore comments +unused-ignore-comment = "error" [tool.coverage.run] source = ["src/backend/InvenTree", "InvenTree"] diff --git a/readthedocs.yml b/readthedocs.yml index e2bf29c339..1d72620cfe 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -9,9 +9,9 @@ python: - requirements: src/backend/requirements.txt build: - os: "ubuntu-22.04" + os: "ubuntu-24.04" tools: - python: "3.11" + python: "3.12" jobs: post_install: - pip install -U invoke diff --git a/src/backend/InvenTree/InvenTree/admin.py b/src/backend/InvenTree/InvenTree/admin.py index 2655794159..637e77a10f 100644 --- a/src/backend/InvenTree/InvenTree/admin.py +++ b/src/backend/InvenTree/InvenTree/admin.py @@ -2,7 +2,12 @@ from django.contrib import admin from django.http.request import HttpRequest +from django.utils import timezone +from allauth.usersessions.admin import UserSessionAdmin +from allauth.usersessions.models import UserSession +from django_q.admin import ScheduleAdmin +from django_q.models import Schedule from djmoney.contrib.exchange.admin import RateAdmin from djmoney.contrib.exchange.models import Rate @@ -17,3 +22,51 @@ class CustomRateAdmin(RateAdmin): admin.site.unregister(Rate) admin.site.register(Rate, CustomRateAdmin) + + +def run_schedule_now(modeladmin, request, queryset): + """Immediately queue the selected scheduled tasks for execution.""" + queryset.update(next_run=timezone.now()) + count = queryset.count() + modeladmin.message_user(request, f'{count} task(s) queued for immediate execution.') + + +run_schedule_now.short_description = 'Run selected tasks now' + + +class ReadOnlyScheduleAdmin(ScheduleAdmin): + """Read-only admin interface for django-q Schedule objects.""" + + actions = [run_schedule_now] + + def has_add_permission(self, request: HttpRequest) -> bool: + """Prevent adding new Schedule objects.""" + return False + + def has_change_permission(self, request: HttpRequest, obj=None) -> bool: + """Prevent changing existing Schedule objects.""" + return False + + def has_delete_permission(self, request: HttpRequest, obj=None) -> bool: + """Prevent deleting Schedule objects.""" + return False + + +admin.site.unregister(Schedule) +admin.site.register(Schedule, ReadOnlyScheduleAdmin) + + +class InvenTreeUserSessionAdmin(UserSessionAdmin): + """Admin interface for UserSession - view and delete only, no add or edit.""" + + def has_add_permission(self, request: HttpRequest) -> bool: + """Prevent creating sessions via admin.""" + return False + + def has_change_permission(self, request: HttpRequest, obj=None) -> bool: + """Prevent editing sessions via admin.""" + return False + + +admin.site.unregister(UserSession) +admin.site.register(UserSession, InvenTreeUserSessionAdmin) diff --git a/src/backend/InvenTree/InvenTree/api.py b/src/backend/InvenTree/InvenTree/api.py index 87edf69474..c08f24289c 100644 --- a/src/backend/InvenTree/InvenTree/api.py +++ b/src/backend/InvenTree/InvenTree/api.py @@ -6,6 +6,7 @@ from pathlib import Path from django.conf import settings from django.contrib.contenttypes.models import ContentType +from django.core.exceptions import ObjectDoesNotExist from django.db import transaction from django.http import JsonResponse from django.urls import path, reverse @@ -15,7 +16,7 @@ from django.views.generic.base import RedirectView import structlog from django_q.models import OrmQ from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema -from rest_framework import serializers, viewsets +from rest_framework import permissions, serializers, viewsets from rest_framework.generics import GenericAPIView from rest_framework.request import clone_request from rest_framework.response import Response @@ -23,12 +24,15 @@ from rest_framework.serializers import ValidationError from rest_framework.views import APIView import InvenTree.config +import InvenTree.filters import InvenTree.permissions import InvenTree.version from common.settings import get_global_setting from InvenTree import helpers, ready from InvenTree.auth_overrides import registration_enabled from InvenTree.mixins import ListCreateAPI +from InvenTree.tasks import batch_offload_tasks +from plugin.base.event.events import batch_events from plugin.serializers import MetadataSerializer from users.models import ApiToken from users.permissions import check_user_permission, prefetch_rule_sets @@ -356,7 +360,10 @@ class InfoView(APIView): class NotFoundView(APIView): """Simple JSON view when accessing an invalid API view.""" - permission_classes = [InvenTree.permissions.AllowAnyOrReadScope] + permission_classes = [ + permissions.IsAuthenticated, + InvenTree.permissions.AllowAnyOrReadScope, + ] def not_found(self, request): """Return a 404 error.""" @@ -490,7 +497,7 @@ class BulkCreateMixin: if unique_create_fields := getattr(self, 'unique_create_fields', None): existing = collections.defaultdict(list) for idx, item in enumerate(data): - key = tuple(item[v] for v in list(unique_create_fields)) # type: ignore[not-subscriptable] + key = tuple(item[v] for v in list(unique_create_fields)) # ty: ignore[not-subscriptable] existing[key].append(idx) unique_errors = [[] for _ in range(len(data))] @@ -506,7 +513,7 @@ class BulkCreateMixin: if has_unique_errors: raise ValidationError(unique_errors) - with transaction.atomic(): + with transaction.atomic(), batch_events(), batch_offload_tasks(): for item in data: serializer = self.get_serializer(data=item) if serializer.is_valid(): @@ -530,8 +537,12 @@ class BulkUpdateMixin(BulkOperationMixin): Bulk update allows for multiple items to be updated in a single API query, rather than using multiple API calls to the various detail endpoints. + + Each instance is validated and saved individually, so that any custom save methods are triggered. """ + BULK_ID_FIELD: str = 'pk' + def validate_update(self, queryset, request) -> None: """Perform validation right before updating. @@ -575,17 +586,35 @@ class BulkUpdateMixin(BulkOperationMixin): # Perform the update operation data = request.data - n = queryset.count() + # Extract the primary key values up-front: + # Each instance is re-fetched from the database immediately before it is + # updated, as saving one instance may alter database state which other + # instances in the queryset depend on (e.g. MPTT tree structure fields). + # Saving a stale instance can result in database corruption (and it must + # be the *instance* that is fresh - refresh_from_db is not sufficient here, + # as MPTT caches original field values when the instance is loaded). + pk_values = sorted(queryset.values_list(self.BULK_ID_FIELD, flat=True)) instance_data = [] - with transaction.atomic(): + with transaction.atomic(), batch_events(), batch_offload_tasks(): # Perform object update # Note that we do not perform a bulk-update operation here, # as we want to trigger any custom post_save methods on the model # Run validation first - for instance in queryset: + for pk in pk_values: + try: + instance = queryset.select_for_update(of=('self',)).get(**{ + self.BULK_ID_FIELD: pk + }) + except ObjectDoesNotExist: + raise ValidationError({ + 'non_field_errors': _( + 'Item no longer matches the provided criteria' + ) + }) + serializer = self.get_serializer(instance, data=data, partial=True) serializer.is_valid(raise_exception=True) serializer.save() @@ -593,7 +622,7 @@ class BulkUpdateMixin(BulkOperationMixin): instance_data.append(serializer.data) return Response( - {'success': f'Updated {n} items', 'items': instance_data}, status=200 + {'success': 'Updated multiple items', 'items': instance_data}, status=200 ) @@ -665,7 +694,7 @@ class CommonBulkDeleteMixin(BulkOperationMixin): # Keep track of how many items we deleted n_deleted = queryset.count() - with transaction.atomic(): + with transaction.atomic(), batch_events(), batch_offload_tasks(): # Perform object deletion # Note that we do not perform a bulk-delete operation here, # as we want to trigger any custom post_delete methods on the model @@ -960,3 +989,43 @@ def meta_path(model, lookup_field: str = 'pk', lookup_field_ref: str = 'pk'): lookup_field_ref=lookup_field_ref, ), ) + + +class TreeMixin: + """A mixin class for supporting tree-structured data in the API.""" + + # Any API view which inherits from this mixin must define a 'model_class' attribute + model_class = None + + filter_backends = InvenTree.filters.SEARCH_ORDER_FILTER + search_fields = ['name', 'description'] + ordering_fields = ['level', 'name', 'subcategories'] + ordering_field_aliases = {'level': ['level', 'name'], 'name': ['name', 'level']} + ordering = ['level'] + + def filter_queryset(self, queryset): + """Filter the queryset, and provide extra support for tree-structured data.""" + queryset = super().filter_queryset(queryset) + + # If a search term is provided, include all ancestors of matched items in the results + if self.request.query_params.get('search', '').strip(): + ancestors = self.model_class.objects.get_queryset_ancestors( + queryset, include_self=True + ) + queryset = queryset | ancestors + + # If a specific ID is provided to "expand_to", include all ancestors and siblings + if expand_to := self.request.query_params.get('expand_to'): + try: + target = self.model_class.objects.get(pk=int(expand_to)) + target_ancestors = target.get_ancestors(include_self=True) + queryset = queryset | target_ancestors + + # We also want to include the "sibling" nodes of the expanded item + siblings = target.get_siblings(include_self=True) + queryset = queryset | siblings + + except (self.model_class.DoesNotExist, ValueError): + pass + + return queryset.distinct() diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index a8192a2431..0da8a25fa1 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,11 +1,138 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 494 +INVENTREE_API_VERSION = 532 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v532 -> 2026-08-15 : https://github.com/inventree/InvenTree/pull/12422 + - Adds "piece_count" field to the BomItem model and API endpoints (for cut-to-length parts) + +v531 -> 2026-08-13 : https://github.com/inventree/InvenTree/pull/12635 + - Adds "bulk update" support for the ReturnOrderLineItem API endpoint + +v530 -> 2026-07-28 : https://github.com/inventree/InvenTree/pull/12487 + - Adds searching against ReportSnippet API endpoint + +v529 -> 2026-07-26 : https://github.com/inventree/InvenTree/pull/12471 + - Adds "on_order" filter to the Part API + - Enable sorting by "ordering" quantity on the Part API endpoint + +v528 -> 2026-07-26 : https://github.com/inventree/InvenTree/pull/12469 + - Additional ordering options for SalesOrderAllocation API endpoint + +v527 -> 2026-07-24 : https://github.com/inventree/InvenTree/pull/12454 + - Extend API with dedicated login-by-code re-send endpoint + +v526 -> 2026-07-24 : https://github.com/inventree/InvenTree/pull/12463 + - Fix for data export on SalesOrderAllocation API endpoint + +v525 -> 2026-07-20 : https://github.com/inventree/InvenTree/pull/12409 + - Type clarifications for some fields; no functional changes + +v524 -> 2026-07-20 : https://github.com/inventree/InvenTree/pull/12393 + - Adds "discount" field to order line items (and extra line items) + +v523 -> 2026-07-14 : https://github.com/inventree/InvenTree/pull/12391 + - Adds "bulk delete" support for order line item API endpoints (PurchaseOrder / SalesOrder / ReturnOrder / TransferOrder) + - Adds "bulk delete" support for order extra line item API endpoints + - Completed TransferOrder objects are now "locked" (controlled by the new TRANSFERORDER_EDIT_COMPLETED_ORDERS global setting) + +v522 -> 2026-07-14 : https://github.com/inventree/InvenTree/pull/12388 + - Adds "unique" field to the ParameterTemplate model + +v521 -> 2026-07-12 : https://github.com/inventree/InvenTree/pull/12360 + - Removes the MPTT mixin from the StockItem model, and removes the self-referential tree structure from the database. + +v520 -> 2026-07-11 : https://github.com/inventree/InvenTree/pull/12310 + - Adds new "disassemble" API endpoint for stock items + - Allows a stock item to be broken down into component parts, based on its Bill of Materials + +v519 -> 2026-07-09 : https://github.com/inventree/InvenTree/pull/TODO + - Adds optional "roles" and "permissions" fields to the /user/me/ API endpoint, via the "?roles=true" query parameter + +v518 -> 2026-07-09 : https://github.com/inventree/InvenTree/pull/12341 + - Enable import of internal part prices via the API + +v517 -> 2026-07-08 : https://github.com/inventree/InvenTree/pull/12336 + - Fix currency code options for the PartPricing model and API endpoints + +v516 -> 2026-07-03 : https://github.com/inventree/InvenTree/pull/12295 + - Adds "consumable" field to the Part model and API endpoints + +v515 -> 2026-07-03 : https://github.com/inventree/InvenTree/pull/12298 + - Change the file fields definition to binary (from uri) in the upload requests + +v514 -> 2026-07-02 : https://github.com/inventree/InvenTree/pull/12294 + - Adds "duplicate" field to the BuildOrder, Company, ManufacturerPart, SupplierPart and SalesOrderShipment API endpoints + - Order duplication options: renames "order_id" field to "original", which now performs primary-key validation + - Part duplication options: renames "part" field to "original" + +v513 -> 2026-06-25 : https://github.com/inventree/InvenTree/pull/12250 + - Adds "active" field to the ProjectCode model and API endpoints + +v512 -> 2026-06-20 : https://github.com/inventree/InvenTree/pull/12022 + - Adds optional "merge" field to each item in the Stock Transfer API endpoint + - When merge is enabled, transferred stock is combined into compatible existing stock at the destination + - Stock merge tracking entries now include an "added" delta field. + +v511 -> 2026-06-19 : https://github.com/inventree/InvenTree/pull/12204 + - Adds new filtering options to PartCategoryTree and StockLocationTree API endpoints + +v510 -> 2026-06-18 : https://github.com/inventree/InvenTree/pull/12197 + - Require "staff" access permissions for the machine restart API endpoint + +v509 -> 2026-06-17 : https://github.com/inventree/InvenTree/pull/12184 + - Adds "completed_row_count_history" and "row_count_history" fields to the DataImportSession model, which store the historic count of completed rows and total rows for a data import session. + +v508 -> 2026-06-17 : https://github.com/inventree/InvenTree/pull/11982 + - An order's "status_custom_key" can be updated via PATCH API endpoint + +v507 -> 2026-06-16 : https://github.com/inventree/InvenTree/pull/12180 + - Adds "lookup_field" parameter to the DataImportSessionSerializer, which allows for more flexible lookup of related objects during data import operations + +v506 -> 2026-06-15 : https://github.com/inventree/InvenTree/pull/12168 + - Reduce permissions scope for a number of API endpoints, to improve security and ensure that users only have access to the data they need + +v505 -> 2026-06-15 : https://github.com/inventree/InvenTree/pull/12165 + - Allow parameters to be specified against the PartCategory model + +v504 -> 2026-06-13 : https://github.com/inventree/InvenTree/pull/12139 + - Adjustments to the SelectionList and SelectionListEntry API endpoints to support more efficient queries and data retrieval + +v503 -> 2026-06-11 : https://github.com/inventree/InvenTree/pull/12155 + - Adds additional filtering and sorting options to the LabelTemplate API endpoint + - Adds additional filtering and sorting options to the ReportTemplate API endpoint + +v502 -> 2026-06-10 : https://github.com/inventree/InvenTree/pull/12142 + - Prevents users from printing reports or labels against models for which they do not have adequate permissions. This change improves the security of the system by ensuring that users cannot access or print reports or labels for models they do not have permission to view. + +v501 -> 2026-06-05 : https://github.com/inventree/InvenTree/pull/12093 + - Adds "read_only" attribute to PluginSetting API endpoint, which indicates whether a particular plugin setting is read-only (i.e. cannot be modified via the API) + +v500 -> 2026-06-03 : https://github.com/inventree/InvenTree/pull/12077 + - Adds "tags" fields to multiple new model types + - Adds /api/tag/ endpoint for fetching tags + - Enable filtering various model types by tags + +v499 -> 2026-06-01 : https://github.com/inventree/InvenTree/pull/12057 + - Fixes search field issues on the BarcodeScanHistory API endpoint + +v498 -> 2026-05-31 : https://github.com/inventree/InvenTree/pull/12055 + - Updates the "status_text" field for models which support custom status values + +v497 -> 2026-05-27 : https://github.com/inventree/InvenTree/pull/12019 + - Adds "location" field to StockCount API endpoint + +v496 -> 2026-05-26 : https://github.com/inventree/InvenTree/pull/12011 + - Add "creation_date" field to the StockItem API endpoint + +v495 -> 2026-05-25 : https://github.com/inventree/InvenTree/pull/12000 + - Adds "auto-allocate" API endpoint for sales orders + - Allow bulk-delete of SalesOrderAllocation objects via the API + - Add new allocation options to the Build auto-allocate API endpoint + v494 -> 2026-05-23 : https://github.com/inventree/InvenTree/pull/11990 - Offload build output operations to a background task, and return a task ID which can be used to monitor the progress of the task diff --git a/src/backend/InvenTree/InvenTree/apps.py b/src/backend/InvenTree/InvenTree/apps.py index 50d5b6ae5d..1cbf4d11c7 100644 --- a/src/backend/InvenTree/InvenTree/apps.py +++ b/src/backend/InvenTree/InvenTree/apps.py @@ -64,9 +64,20 @@ class InvenTreeConfig(AppConfig): self.collect_tasks() self.start_background_tasks() - if not InvenTree.ready.isInTestMode(): # pragma: no cover + if ( + not InvenTree.ready.isInTestMode() + and not InvenTree.ready.isInWorkerThread() + ): # pragma: no cover # Let the background worker check for migrations - InvenTree.tasks.offload_task(InvenTree.tasks.check_for_migrations) + # Don't offload task if we are already *in* the background worker, otherwise we might end up in a deadlock situation + + try: + InvenTree.tasks.offload_task(InvenTree.tasks.check_for_migrations) + except Exception as exc: + logger.exception( + 'Failed to offload check_for_migrations task: %s', exc + ) + # Update exchange rates InvenTree.tasks.offload_task( InvenTree.tasks.update_exchange_rates, force_async=True @@ -177,13 +188,10 @@ class InvenTreeConfig(AppConfig): @ignore_ready_warning def add_heartbeat(self): """Ensure there is at least one background task in the queue.""" - import django_q.models - try: - if django_q.models.OrmQ.objects.count() == 0: - InvenTree.tasks.offload_task( - InvenTree.tasks.heartbeat, force_async=True, group='heartbeat' - ) + InvenTree.tasks.offload_task( + InvenTree.tasks.heartbeat, force_async=True, group='heartbeat' + ) except AppRegistryNotReady: # pragma: no cover pass except Exception: diff --git a/src/backend/InvenTree/InvenTree/auth_overrides.py b/src/backend/InvenTree/InvenTree/auth_overrides.py index 9a223dd2f9..32de0107bd 100644 --- a/src/backend/InvenTree/InvenTree/auth_overrides.py +++ b/src/backend/InvenTree/InvenTree/auth_overrides.py @@ -114,9 +114,12 @@ class RegistrationMixin: """ if registration_enabled(self.REGISTRATION_SETTING): return True - logger.warning( - f'INVE-W12: Signup attempt blocked, because registration is disabled via setting {self.REGISTRATION_SETTING}.' - ) + # Only warn when this is an actual signup submission, not when called as + # a feature-availability check during login or other auth flows. + if request and request.method == 'POST' and 'signup' in request.path: + logger.warning( + f'INVE-W12: Signup attempt blocked, because registration is disabled via setting {self.REGISTRATION_SETTING}.' + ) return False def clean_email(self, email): diff --git a/src/backend/InvenTree/InvenTree/conversion.py b/src/backend/InvenTree/InvenTree/conversion.py index 8db0eb8330..3b6fda27b8 100644 --- a/src/backend/InvenTree/InvenTree/conversion.py +++ b/src/backend/InvenTree/InvenTree/conversion.py @@ -114,6 +114,9 @@ def reload_unit_registry(): reg.define('@alias degF = Fahrenheit') reg.define('@alias degK = Kelvin') + # Override R as ohm (pint defines R as an SI prefix by default) + reg.define('R = ohm') + # Define some "standard" additional units reg.define('piece = 1') reg.define('each = 1 = ea') diff --git a/src/backend/InvenTree/InvenTree/exceptions.py b/src/backend/InvenTree/InvenTree/exceptions.py index 161860339d..633612922d 100644 --- a/src/backend/InvenTree/InvenTree/exceptions.py +++ b/src/backend/InvenTree/InvenTree/exceptions.py @@ -7,6 +7,7 @@ import traceback from typing import Optional from django.conf import settings +from django.core.exceptions import AppRegistryNotReady from django.core.exceptions import ValidationError as DjangoValidationError from django.utils.translation import gettext_lazy as _ @@ -19,12 +20,13 @@ logger = structlog.get_logger('inventree') def log_error( - path, - error_name=None, - error_info=None, - error_data=None, + path: Optional[str] = None, + error_name: Optional[str] = None, + error_info: Optional[str] = None, + error_data: Optional[str] = None, scope: Optional[str] = None, plugin: Optional[str] = None, + user_id: Optional[int] = None, ): """Log an error to the database. @@ -37,6 +39,7 @@ def log_error( error_data: The error data (optional, overrides 'data') scope: The scope of the error (optional) plugin: The plugin name associated with this error (optional) + user_id: The user ID associated with this error (optional) """ import InvenTree.ready @@ -71,6 +74,9 @@ def log_error( except AttributeError: data = 'No traceback information available' + if user_id: + data = f'User ID: {user_id}\n{data}' + # Log error to stderr logger.error(info) @@ -109,17 +115,36 @@ def exception_handler(exc, context): response = None - # Pass exception to sentry.io handler - try: - InvenTree.sentry.report_exception(exc) - except Exception: - # If sentry.io fails, we don't want to crash the server! - pass + # The Django app registry can be transiently un-ready while the plugin + # registry is reloading apps (see plugin.registry.PluginsRegistry._reload_apps). + # Any request handled by another thread/worker during that window can trip + # this - it is not a real server error, so ask the client to retry shortly + # rather than surfacing a 500. + if isinstance(exc, AppRegistryNotReady): + response = Response( + { + 'error': 'AppRegistryNotReady', + 'detail': _( + 'Server is temporarily reloading, please retry the request' + ), + }, + status=503, + ) + response['Retry-After'] = '1' + return response # Catch any django validation error, and re-throw a DRF validation error - if isinstance(exc, DjangoValidationError): + elif isinstance(exc, DjangoValidationError): exc = DRFValidationError(detail=serializers.as_serializer_error(exc)) + else: + # Pass any other (unhandled) exception to sentry.io handler + try: + InvenTree.sentry.report_exception(exc) + except Exception: + # If sentry.io fails, we don't want to crash the server! + pass + # Default to the built-in DRF exception handler response = drfviews.exception_handler(exc, context) diff --git a/src/backend/InvenTree/InvenTree/fields.py b/src/backend/InvenTree/InvenTree/fields.py index b7c09dbe12..8f6d55bde5 100644 --- a/src/backend/InvenTree/InvenTree/fields.py +++ b/src/backend/InvenTree/InvenTree/fields.py @@ -1,6 +1,7 @@ """Custom fields used in InvenTree.""" import sys +import uuid from decimal import Decimal from django import forms @@ -13,6 +14,7 @@ from djmoney.models.fields import MoneyField as ModelMoneyField from djmoney.models.validators import MinMoneyValidator from rest_framework.fields import URLField as RestURLField from rest_framework.fields import empty +from rest_framework.relations import PrimaryKeyRelatedField import InvenTree.helpers import InvenTree.ready @@ -47,6 +49,42 @@ class InvenTreeRestURLField(RestURLField): return super().run_validation(data=data) +class PrefetchedPrimaryKeyRelatedField(PrimaryKeyRelatedField): + """A PrimaryKeyRelatedField which resolves against a pre-fetched {pk: instance} map. + + PrimaryKeyRelatedField normally issues one .get() query per list entry when used + inside a many=True nested serializer - for large lists (hundreds of related objects) + that becomes an O(n) query cost just to validate the request. The parent serializer + should instead bulk-fetch all referenced objects in a single query and stash the + {pk: instance} map in self.context[cache_key] (typically from an overridden + to_internal_value()); this field then does an O(1) dict lookup instead of hitting + the database. + + Falls back to the default per-item query if no cache has been populated (or the pk + is missing from it), so this field remains safe to use standalone - e.g. in tests + constructing the child serializer directly, or for a pk that's genuinely invalid. + """ + + def __init__(self, cache_key: str, **kwargs): + """Store the context key under which the parent serializer stashes its prefetch cache.""" + self.cache_key = cache_key + super().__init__(**kwargs) + + def to_internal_value(self, data): + """Resolve 'data' (a raw pk value) against the prefetch cache, if available.""" + cache = self.context.get(self.cache_key) + + try: + pk = int(data) + except (TypeError, ValueError): + pk = None + + if not cache or pk not in cache: + return super().to_internal_value(data) + + return cache[pk] + + class InvenTreeURLField(models.URLField): """Custom URL field which has custom scheme validators.""" @@ -59,6 +97,34 @@ class InvenTreeURLField(models.URLField): super().__init__(**kwargs) +class InvenTreeUUIDField(models.UUIDField): + """UUIDField which is always stored as a char(32) column on MySQL / MariaDB. + + On MariaDB 10.7+, Django maps UUIDField to the native 'uuid' column type, + and writes 36-character (hyphenated) values to match. + However, databases migrated under older Django / MariaDB versions retain + their original char(32) columns, into which a 36-character value does not fit. + + To ensure consistent behavior across all supported database backends, + we force the legacy char(32) storage format on MySQL / MariaDB. + + Ref: https://docs.djangoproject.com/en/5.2/releases/5.0/#migrating-existing-uuidfield-on-mariadb-10-7 + """ + + def db_type(self, connection): + """Force a char(32) column type on MySQL / MariaDB backends.""" + if connection.vendor == 'mysql': + return 'char(32)' + return super().db_type(connection) + + def get_db_prep_value(self, value, connection, prepared=False): + """Store values in 32-character hex format on MySQL / MariaDB backends.""" + value = super().get_db_prep_value(value, connection, prepared) + if connection.vendor == 'mysql' and isinstance(value, uuid.UUID): + value = value.hex + return value + + def money_kwargs(**kwargs): """Returns the database settings for MoneyFields.""" from common.currency import currency_code_mappings @@ -71,7 +137,9 @@ def money_kwargs(**kwargs): kwargs['decimal_places'] = 6 if 'currency_choices' not in kwargs: - kwargs['currency_choices'] = currency_code_mappings() + # Pass the function itself (not the evaluated result) so that the + # available currency options are resolved dynamically. + kwargs['currency_choices'] = currency_code_mappings if InvenTree.ready.isRunningMigrations(): # During migrations, avoid setting a default currency diff --git a/src/backend/InvenTree/InvenTree/format.py b/src/backend/InvenTree/InvenTree/format.py index 3ee674b216..848c7e07ae 100644 --- a/src/backend/InvenTree/InvenTree/format.py +++ b/src/backend/InvenTree/InvenTree/format.py @@ -2,16 +2,9 @@ import re import string -from typing import Optional -from django.conf import settings -from django.utils import translation from django.utils.translation import gettext_lazy as _ -from babel import Locale -from babel.numbers import parse_pattern -from djmoney.money import Money - def parse_format_string(fmt_string: str) -> dict: """Extract formatting information from the provided format string. @@ -180,43 +173,3 @@ def extract_named_group(name: str, value: str, fmt_string: str) -> str: # And return the value we are interested in # Note: This will raise an IndexError if the named group was not matched return result.group(name) - - -def format_money( - money: Money, - decimal_places: Optional[int] = None, - fmt: Optional[str] = None, - include_symbol: bool = True, -) -> str: - """Format money object according to the currently set local. - - Args: - money (Money): The money object to format - decimal_places (int): Number of decimal places to use - fmt (str): Format pattern according LDML / the babel format pattern syntax (https://babel.pocoo.org/en/latest/numbers.html) - include_symbol (bool): Whether to include the currency symbol in the formatted output - - Returns: - str: The formatted string - - Raises: - ValueError: format string is incorrectly specified - """ - language = (None) or settings.LANGUAGE_CODE - locale = Locale.parse(translation.to_locale(language)) - if fmt: - pattern = parse_pattern(fmt) - else: - pattern = locale.currency_formats['standard'] - if decimal_places is not None: - pattern.frac_prec = (decimal_places, decimal_places) - - result = pattern.apply( - money.amount, - locale, - currency=money.currency.code if include_symbol else '', - currency_digits=decimal_places is None, - decimal_quantization=decimal_places is not None, - ) - - return result diff --git a/src/backend/InvenTree/InvenTree/helpers.py b/src/backend/InvenTree/InvenTree/helpers.py index 502ac9c3b0..792fd1b002 100644 --- a/src/backend/InvenTree/InvenTree/helpers.py +++ b/src/backend/InvenTree/InvenTree/helpers.py @@ -262,27 +262,42 @@ def checkStaticFile(*args) -> bool: return static_storage.exists(str(fn)) -def getLogoImage(as_file=False, custom=True): - """Return the InvenTree logo image, or a custom logo if available.""" +def getLogoImage(as_file: bool = False, custom: bool = True) -> str: + """Return the InvenTree logo image, or a custom logo if available. + + Arguments: + as_file: If True, return a base64-encoded data URI of the image contents, + suitable for embedding directly into a generated report (default = False) + custom: If True, return a custom logo if one has been provided (default = True) + """ + # Note: Imported here to avoid circular imports, as the 'report' app also imports from this module + import report.helpers + from report.templatetags.report import ( + get_media_file_contents, + get_static_file_contents, + ) + if custom and settings.CUSTOM_LOGO: static_storage = StaticFilesStorage() if static_storage.exists(settings.CUSTOM_LOGO): - storage = static_storage - elif default_storage.exists(settings.CUSTOM_LOGO): - storage = default_storage - else: - storage = None - - if storage is not None: if as_file: - return f'file://{storage.path(settings.CUSTOM_LOGO)}' - return storage.url(settings.CUSTOM_LOGO) + return report.helpers.encode_file_base64( + settings.CUSTOM_LOGO, get_static_file_contents(settings.CUSTOM_LOGO) + ) + return static_storage.url(settings.CUSTOM_LOGO) + elif default_storage.exists(settings.CUSTOM_LOGO): + if as_file: + return report.helpers.encode_file_base64( + settings.CUSTOM_LOGO, get_media_file_contents(settings.CUSTOM_LOGO) + ) + return default_storage.url(settings.CUSTOM_LOGO) # If we have got to this point, return the default logo if as_file: - path = settings.STATIC_ROOT.joinpath('img/inventree.png') - return f'file://{path}' + return report.helpers.encode_file_base64( + 'img/inventree.png', get_static_file_contents('img/inventree.png') + ) return getStaticUrl('img/inventree.png') @@ -550,29 +565,31 @@ def increment_serial_number(serial, part=None): incremented value, or None if incrementing could not be performed. """ from InvenTree.exceptions import log_error + from InvenTree.ready import isReadOnlyCommand from plugin import PluginMixinEnum, registry # Ensure we start with a string value if serial is not None: serial = str(serial).strip() - # First, let any plugins attempt to increment the serial number - for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): - try: - if not hasattr(plugin, 'increment_serial_number'): - continue + if not isReadOnlyCommand(): + # First, let any plugins attempt to increment the serial number + for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): + try: + if not hasattr(plugin, 'increment_serial_number'): + continue - signature = inspect.signature(plugin.increment_serial_number) + signature = inspect.signature(plugin.increment_serial_number) - # Note: 2024-08-21 - The 'part' parameter has been added to the signature - if 'part' in signature.parameters: - result = plugin.increment_serial_number(serial, part=part) - else: - result = plugin.increment_serial_number(serial) - if result is not None: - return str(result) - except Exception: - log_error('increment_serial_number', plugin=plugin.slug) + # Note: 2024-08-21 - The 'part' parameter has been added to the signature + if 'part' in signature.parameters: + result = plugin.increment_serial_number(serial, part=part) + else: + result = plugin.increment_serial_number(serial) + if result is not None: + return str(result) + except Exception: + log_error('increment_serial_number', plugin=plugin.slug) # If we get to here, no plugins were able to "increment" the provided serial value # Attempt to perform increment according to some basic rules diff --git a/src/backend/InvenTree/InvenTree/helpers_db.py b/src/backend/InvenTree/InvenTree/helpers_db.py new file mode 100644 index 0000000000..5ed25e0bee --- /dev/null +++ b/src/backend/InvenTree/InvenTree/helpers_db.py @@ -0,0 +1,72 @@ +"""Database helper functions for InvenTree.""" + +import uuid +from typing import Optional + +from django.db import transaction +from django.db.models import QuerySet + + +@transaction.atomic +def bulk_create_and_fetch( + model, items, id_field: str = 'pk', filters: Optional[dict] = None +) -> QuerySet: + """Bulk create items in the database, and return a list of the created items. + + Arguments: + model: The Django model class to create instances of. + items: A list of dictionaries containing the data for each item to be created. + id_field: The name of the field to use as the unique identifier for the created items. + filters: Optional dictionary of filters to apply when fetching the created items. + + Returns: + A QuerySet containing the created items. + + This helper method is required because the Django bulk_create() method + does not guarantee that the ID values of the created items will be populated in the returned objects. + In particular, MySQL does not support returning the ID values of bulk created items. + + So, we provide temporary metadata to the created items, + which can be used to fetch the created items from the database. + + Assumptions: + - The provided model type has a "metadata" attribute which can be overloaded for this purpose + - No "metadata" is provided in the input items, as this will be overwritten by the method + - The model type has an incrementing ID field (default: "pk") + + """ + bulk_create_id = uuid.uuid4().hex + + # Generate temporary metadata for bulk fetching + metadata = {'bulk_create_id': bulk_create_id} + + lookup_filters = dict(filters) if filters else {} + + lookup_filters['metadata__bulk_create_id'] = bulk_create_id + + if id_field: + # Find the "most recent" item in the database, to set a search floor + if instance := model.objects.order_by(f'-{id_field}').first(): + lookup_filters[f'{id_field}__gt'] = getattr(instance, id_field) + + # Overwrite the metadata values + for item in items: + item.metadata = metadata + + model.objects.bulk_create(items, batch_size=500) + + instances = model.objects.filter(**lookup_filters) + + id_field = id_field or 'pk' + + pks = list(instances.order_by(id_field).values_list(id_field, flat=True)) + + # Override the metadata values to remove the temporary bulk_create_id + instances.update(metadata=None) + + # Fetch the newly created items (by primary key, as the metadata filter no longer matches) + # Ordered by id_field: auto-increment values are assigned in insertion order on every + # backend, so this restores correspondence with the input 'items' list for callers that + # zip the result against it positionally. Without this, some backends (e.g. MySQL) may + # return 'pk__in' rows in a different order than they were inserted. + return model.objects.filter(**{f'{id_field}__in': pks}).order_by(id_field) diff --git a/src/backend/InvenTree/InvenTree/helpers_email.py b/src/backend/InvenTree/InvenTree/helpers_email.py index f6dca007f2..6a0894b73a 100644 --- a/src/backend/InvenTree/InvenTree/helpers_email.py +++ b/src/backend/InvenTree/InvenTree/helpers_email.py @@ -69,8 +69,21 @@ def send_email( html_message=None, prio: Priority = Priority.NORMAL, headers: Optional[dict] = None, + force_async: bool = False, + **kwargs, ) -> tuple[bool, Optional[str]]: - """Send an email with the specified subject and body, to the specified recipients list.""" + """Send an email with the specified subject and body, to the specified recipients list. + + Arguments: + subject: Subject of the email + body: Body of the email + recipients: List of recipients (or a single recipient) + from_email: Optional sender email address (if not specified, will use DEFAULT_FROM_EMAIL) + html_message: Optional HTML message to send + prio: Priority of the email (default is normal) + headers: Optional dictionary of headers to include in the email + force_async: If True, will force the email to be sent asynchronously + """ if isinstance(recipients, str): recipients = [recipients] @@ -109,6 +122,7 @@ def send_email( html_message=html_message, prio=prio, headers=headers, + force_async=force_async, group='notification', ) return True, None diff --git a/src/backend/InvenTree/InvenTree/helpers_model.py b/src/backend/InvenTree/InvenTree/helpers_model.py index ccd1cfd963..7fe10777b3 100644 --- a/src/backend/InvenTree/InvenTree/helpers_model.py +++ b/src/backend/InvenTree/InvenTree/helpers_model.py @@ -1,14 +1,14 @@ """Provides helper functions used throughout the InvenTree project that access the database.""" +import contextlib +import contextvars import io import ipaddress import socket -from decimal import Decimal from typing import Optional, cast from urllib.parse import urljoin, urlparse from django.conf import settings -from django.core.exceptions import ValidationError from django.core.validators import URLValidator from django.db.utils import OperationalError, ProgrammingError from django.utils.translation import gettext_lazy as _ @@ -16,8 +16,6 @@ from django.utils.translation import gettext_lazy as _ import requests import requests.exceptions import structlog -from djmoney.contrib.exchange.models import convert_money -from djmoney.money import Money from PIL import Image from common.notifications import ( @@ -31,7 +29,6 @@ from InvenTree.cache import ( get_session_cache, set_session_cache, ) -from InvenTree.format import format_money from InvenTree.ready import ignore_ready_warning logger = structlog.get_logger('inventree') @@ -90,6 +87,66 @@ def construct_absolute_url(*arg, base_url=None, request=None): return urljoin(base_url, relative_url) +_ssrf_guard_active = contextvars.ContextVar('ssrf_guard_active', default=False) +_real_getaddrinfo = socket.getaddrinfo + + +def _is_unsafe_ip(host: str) -> bool: + """Return True if the given (already-resolved) address string is private/reserved.""" + ip = ipaddress.ip_address(host) + return ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved + + +def _guarded_getaddrinfo(host, *args, **kwargs): + """Drop-in replacement for socket.getaddrinfo which enforces SSRF checks while active. + + DNS resolution is otherwise delegated to the OS resolver on every connection + attempt an HTTP client makes - including ones made well after an earlier, + now-discarded resolution was validated by `validate_url_no_ssrf()`. An attacker + controlling authoritative DNS for their own domain can answer a first ("check") + lookup with a public IP and a later ("use") lookup with a private/internal one + (DNS rebinding), bypassing a validation step that only inspects the first answer. + + Patching this at the socket layer means the *actual* resolution used to open the + real connection - whichever call that turns out to be - is the one that gets + checked, so there is no window between "validated" and "connected" for the + answer to change. The guard is only enforced while `ssrf_safe_context()` is + active in the current context, so unrelated resolutions (e.g. other threads + talking to the database/cache) are never affected. + """ + result = _real_getaddrinfo(host, *args, **kwargs) + + if _ssrf_guard_active.get(): + for _family, _type, _proto, _canonname, sockaddr in result: + if _is_unsafe_ip(sockaddr[0]): + raise socket.gaierror( + f'Host {host!r} resolved to a private or reserved address' + ) + + return result + + +socket.getaddrinfo = _guarded_getaddrinfo + + +@contextlib.contextmanager +def ssrf_safe_context(): + """Enforce SSRF IP validation on every DNS resolution performed within this block. + + Wrap any code which resolves a user/attacker-influenced hostname and then + connects to it (e.g. `requests.get()`, or a library like WeasyPrint doing its + own resolution internally) in this context manager so that the resolution + backing the *actual* connection is validated, not just an earlier, separate + lookup whose result is discarded. See `_guarded_getaddrinfo` for why this + closes the DNS-rebinding TOCTOU gap that a standalone pre-check cannot. + """ + token = _ssrf_guard_active.set(True) + try: + yield + finally: + _ssrf_guard_active.reset(token) + + def validate_url_no_ssrf(url): """Validate that a URL does not point to a private/internal network address. @@ -114,9 +171,7 @@ def validate_url_no_ssrf(url): raise ValueError(_('Invalid URL: hostname could not be resolved')) for _family, _type, _proto, _canonname, sockaddr in addrinfo: - ip = ipaddress.ip_address(sockaddr[0]) - - if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved: + if _is_unsafe_ip(sockaddr[0]): raise ValueError(_('URL points to a private or reserved IP address')) @@ -163,36 +218,40 @@ def download_image_from_url( headers = {'User-Agent': user_agent} if user_agent else None try: - response = requests.get( - remote_url, - timeout=timeout, - allow_redirects=False, - stream=True, - headers=headers, - ) - - # Handle redirects manually to validate each destination - max_redirects = 5 - redirect_count = 0 - - while response.is_redirect and redirect_count < max_redirects: - redirect_url = response.headers.get('Location') - if not redirect_url: - break - - # Validate the redirect destination against SSRF - validator(redirect_url) - validate_url_no_ssrf(redirect_url) - - redirect_count += 1 + # SSRF protection: guard every DNS resolution made while actually connecting + # (not just the pre-check above) so a hostname cannot pass validation with + # one IP and then be connected to via a different, private one (DNS rebinding). + with ssrf_safe_context(): response = requests.get( - redirect_url, + remote_url, timeout=timeout, allow_redirects=False, stream=True, headers=headers, ) + # Handle redirects manually to validate each destination + max_redirects = 5 + redirect_count = 0 + + while response.is_redirect and redirect_count < max_redirects: + redirect_url = response.headers.get('Location') + if not redirect_url: + break + + # Validate the redirect destination against SSRF + validator(redirect_url) + validate_url_no_ssrf(redirect_url) + + redirect_count += 1 + response = requests.get( + redirect_url, + timeout=timeout, + allow_redirects=False, + stream=True, + headers=headers, + ) + if redirect_count >= max_redirects: raise ValueError(_('Too many redirects')) @@ -252,85 +311,6 @@ def download_image_from_url( return img -def render_currency( - money: Money, - decimal_places: Optional[int] = None, - currency: Optional[str] = None, - multiplier: Optional[Decimal] = None, - min_decimal_places: Optional[int] = None, - max_decimal_places: Optional[int] = None, - include_symbol: bool = True, -): - """Render a currency / Money object to a formatted string (e.g. for reports). - - Arguments: - money: The Money instance to be rendered - decimal_places: The number of decimal places to render to. If unspecified, uses the PRICING_DECIMAL_PLACES setting. - currency: Optionally convert to the specified currency - multiplier: An optional multiplier to apply to the money amount before rendering - min_decimal_places: The minimum number of decimal places to render to. If unspecified, uses the PRICING_DECIMAL_PLACES_MIN setting. - max_decimal_places: The maximum number of decimal places to render to. If unspecified, uses the PRICING_DECIMAL_PLACES setting. - include_symbol: If True, include the currency symbol in the output - """ - if money in [None, '']: - return '-' - - if type(money) is not Money: - # Try to convert to a Money object - try: - money = Money( - Decimal(str(money)), - currency or get_global_setting('INVENTREE_DEFAULT_CURRENCY'), - ) - except Exception: - raise ValidationError( - f"render_currency: {_('Invalid money value')}: '{money}' ({type(money).__name__})" - ) - - if currency is not None: - # Attempt to convert to the provided currency - # If cannot be done, leave the original - try: - money = convert_money(money, currency) - except Exception: - pass - - if multiplier is not None: - try: - money *= Decimal(str(multiplier).strip()) - except Exception: - raise ValidationError( - f"render_currency: {_('Invalid multiplier value')}: '{multiplier}' ({type(multiplier).__name__})" - ) - - if min_decimal_places is None or not isinstance(min_decimal_places, (int, float)): - min_decimal_places = get_global_setting('PRICING_DECIMAL_PLACES_MIN', 0) - - if max_decimal_places is None or not isinstance(max_decimal_places, (int, float)): - max_decimal_places = get_global_setting('PRICING_DECIMAL_PLACES', 6) - - value = Decimal(str(money.amount)).normalize() - value = str(value) - - if decimal_places is not None and isinstance(decimal_places, (int, float)): - # Decimal place count is provided, use it - pass - elif '.' in value: - # If the value has a decimal point, use the number of decimal places in the value - decimal_places = len(value.split('.')[-1]) - else: - # No decimal point, use 2 as a default - decimal_places = 2 - - # Clip the decimal places to the specified range - decimal_places = max(decimal_places, min_decimal_places) - decimal_places = min(decimal_places, max_decimal_places) - - return format_money( - money, decimal_places=decimal_places, include_symbol=include_symbol - ) - - @ignore_ready_warning def getModelsWithMixin(mixin_class) -> list: """Return a list of database models that inherit from the given mixin class. diff --git a/src/backend/InvenTree/InvenTree/magic_login.py b/src/backend/InvenTree/InvenTree/magic_login.py index 7bdd466174..33a965ca4e 100644 --- a/src/backend/InvenTree/InvenTree/magic_login.py +++ b/src/backend/InvenTree/InvenTree/magic_login.py @@ -69,6 +69,9 @@ class GetSimpleLoginView(GenericAPIView): return User.objects.get(email=email) except User.DoesNotExist: return None + except User.MultipleObjectsReturned: + logger.warning('Multiple users found with email: %s', email) + return None def create_link(self, user): """Create a login link for this user.""" diff --git a/src/backend/InvenTree/InvenTree/management/commands/export_report_context.py b/src/backend/InvenTree/InvenTree/management/commands/export_report_context.py index cbebae51c4..2a0ff28056 100644 --- a/src/backend/InvenTree/InvenTree/management/commands/export_report_context.py +++ b/src/backend/InvenTree/InvenTree/management/commands/export_report_context.py @@ -7,13 +7,14 @@ This in turn allows report context to be documented in the InvenTree documentati without having to manually duplicate the information in multiple places. """ +import inspect import json from typing import get_args, get_origin, get_type_hints import django.db.models from django.core.management.base import BaseCommand, CommandError -from report.mixins import QuerySet +from report.mixins import REPORT_ATTRIBUTE_MARKER, QuerySet def get_type_str(type_obj): @@ -38,6 +39,29 @@ def get_type_str(type_obj): return f'{type_obj.__module__}.{type_obj.__name__}' +def find_related_models(type_obj) -> set: + """Recursively find any Django Model subclasses referenced by a type annotation. + + Handles plain model classes, `Optional[Model]`, and `report.mixins.QuerySet[Model]` + (and any nesting thereof), so that models referenced from a field/property type + can be discovered for the "related model" documentation, without needing to be + manually curated. + """ + found = set() + + if type_obj is None or type_obj is type(None): + return found + + if inspect.isclass(type_obj) and issubclass(type_obj, django.db.models.Model): + found.add(type_obj) + return found + + for arg in get_args(type_obj): + found |= find_related_models(arg) + + return found + + def parse_docstring(docstring: str): """Parse the docstring of a type object and return a dictionary of sections.""" sections = {} @@ -59,6 +83,92 @@ def parse_docstring(docstring: str): return sections +def get_report_attributes(model): + """Find all properties/methods on a model marked with @report_attribute. + + This walks the full MRO of the model class, so attributes contributed by + mixins (e.g. `InvenTreeBarcodeMixin.barcode`) are discovered too, regardless + of whether they are also explicitly included in `report_context()`. + + Returns a tuple of: + + - A dict of {name: {"description": ..., "type": ...}}, ordered so that + attributes redefined further down the MRO (i.e. on the model itself) take + precedence over the same name defined on a base/mixin class. + - A list of qualified names (e.g. "Part.default_supplier") for any + @report_attribute-marked property/method which is missing a return type + annotation. + - A set of any Django Model subclasses referenced by the return type of a + discovered property (e.g. `SupplierPart` for `Part.default_supplier`), used + to auto-discover "related" models which are not themselves reportable. + """ + found = {} + errors = [] + related_models = set() + + for klass in reversed(model.__mro__): + for name, member in vars(klass).items(): + target = member.fget if isinstance(member, property) else member + description = getattr(target, REPORT_ATTRIBUTE_MARKER, None) + + if description is None: + continue + + return_type = get_type_hints(target).get('return', None) + + if return_type is None: + errors.append(f'{klass.__name__}.{name}') + else: + related_models |= find_related_models(return_type) + + found[name] = { + 'description': description, + 'type': get_type_str(return_type) if return_type is not None else '', + } + + return found, errors, related_models + + +def get_model_field_attributes(model): + """Find all concrete database fields defined on a model. + + This includes fields inherited from mixins/abstract base classes, so (for + example) `barcode_data` and `barcode_hash` are discovered for any model + which uses `InvenTreeBarcodeMixin`, without needing to be documented by hand. + + Reverse relations (e.g. the 'lines' accessor on a linked order) are excluded, + as they are not actual fields on this model's table but related querysets - + these are documented (where relevant) via `report_context()` or `@report_attribute` instead. + + Returns a tuple of: + + - A dict of {name: {"description": ..., "type": ...}}. + - A set of any Django Model subclasses referenced by a relation field (e.g. + `PartCategory` for `Part.category`), used to auto-discover "related" models + which are not themselves reportable. + """ + found = {} + related_models = set() + + for field in model._meta.get_fields(): + if not field.concrete: + continue + + description = str(getattr(field, 'help_text', '') or '') or str( + getattr(field, 'verbose_name', field.name) + ) + + type_str = type(field).__name__ + + if field.is_relation and field.related_model is not None: + type_str = f'{type_str}[{get_type_str(field.related_model)}]' + related_models.add(field.related_model) + + found[field.name] = {'description': description, 'type': type_str} + + return found, related_models + + class Command(BaseCommand): """Extract report context information, and export to a JSON file.""" @@ -79,8 +189,10 @@ class Command(BaseCommand): ReportContextExtension, ) - context = {'models': {}, 'base': {}} + context = {'models': {}, 'related_models': {}, 'base': {}} is_error = False + is_attribute_error = False + related_model_classes = set() # Base context models for key, model in [ @@ -111,10 +223,23 @@ class Command(BaseCommand): is_error = True continue + fields, field_related = get_model_field_attributes(model) + properties, property_errors, property_related = get_report_attributes(model) + + related_model_classes |= field_related | property_related + + for qualified_name in property_errors: + print( + f'Error: {qualified_name} is marked with @report_attribute but does not have a return type annotation' + ) + is_attribute_error = True + context['models'][model_key] = { 'key': model_key, 'name': model_name, 'context': {}, + 'fields': fields, + 'properties': properties, } attributes = parse_docstring(ctx_type.__doc__).get('Attributes', {}) @@ -129,6 +254,38 @@ class Command(BaseCommand): 'INVE-E4 - Some models associated with the `InvenTreeReportMixin` do not have a valid `report_context` return type annotation.' ) + # Related models: models which are not themselves reportable, but which are + # referenced by a field or @report_attribute property on a reportable model. + # Discovered automatically (one hop) from the fields/properties collected above, + # so no manual list of "related" models needs to be maintained. + reportable_models = set(report_model_types()) + + for model in sorted( + related_model_classes - reportable_models, key=lambda m: m.__name__ + ): + model_key = model.__name__.lower() + + fields, _ = get_model_field_attributes(model) + properties, property_errors, _ = get_report_attributes(model) + + for qualified_name in property_errors: + print( + f'Error: {qualified_name} is marked with @report_attribute but does not have a return type annotation' + ) + is_attribute_error = True + + context['related_models'][model_key] = { + 'key': model_key, + 'name': str(model._meta.verbose_name).title(), + 'fields': fields, + 'properties': properties, + } + + if is_attribute_error: + raise CommandError( + 'INVE-E5 - Some properties/methods marked with `@report_attribute` do not have a valid return type annotation.' + ) + filename = kwargs.get('filename', 'inventree_report_context.json') with open(filename, 'w', encoding='utf-8') as f: diff --git a/src/backend/InvenTree/InvenTree/management/commands/rebuild_models.py b/src/backend/InvenTree/InvenTree/management/commands/rebuild_models.py index c1d35f879b..33a21b5d65 100644 --- a/src/backend/InvenTree/InvenTree/management/commands/rebuild_models.py +++ b/src/backend/InvenTree/InvenTree/management/commands/rebuild_models.py @@ -43,16 +43,6 @@ class Command(BaseCommand): except Exception: logger.info('Error rebuilding PartCategory objects') - # StockItem model - try: - logger.info('Rebuilding StockItem objects') - - from stock.models import StockItem - - StockItem.objects.rebuild() - except Exception: - logger.info('Error rebuilding StockItem objects') - # StockLocation model try: logger.info('Rebuilding StockLocation objects') diff --git a/src/backend/InvenTree/InvenTree/metadata.py b/src/backend/InvenTree/InvenTree/metadata.py index 4d8451e2db..d74645aa05 100644 --- a/src/backend/InvenTree/InvenTree/metadata.py +++ b/src/backend/InvenTree/InvenTree/metadata.py @@ -219,8 +219,15 @@ class InvenTreeMetadata(SimpleMetadata): serializer_info = super().get_serializer_info(serializer) - # Look for any dynamic fields which were not available when the serializer was instantiated - if hasattr(serializer, 'Meta'): + # Look for any dynamic fields which were not available when the serializer was + # instantiated - this lets an OPTIONS/schema response document an OptionalField + # (e.g. `part_detail`) even when it wasn't included on this particular instance, + # by rehydrating it directly from the class attribute. + if ( + hasattr(serializer, 'Meta') + and not getattr(serializer, '_is_importing', False) + and not getattr(serializer, '_exporting_data', False) + ): for field_name in serializer.Meta.fields: if field_name in serializer_info: # Already know about this one @@ -280,14 +287,26 @@ class InvenTreeMetadata(SimpleMetadata): elif name in model_default_values: serializer_info[name]['default'] = model_default_values[name] - for field_key, model_key in extra_attributes.items(): - field_value = getattr(serializer.fields[name], field_key, None) - model_value = getattr(field, model_key, None) + # Note: `name` may be present in `serializer_info` (above) without + # being a live entry in `serializer.fields` - the 'dynamic fields' + # lookup a few lines up adds metadata for OptionalFields that were + # excluded from *this* serializer instance (e.g. no matching query + # parameter was supplied), by rehydrating them directly from the + # class attribute. A model field can coincidentally share its name + # with such an OptionalField (e.g. `Group.permissions`, a real M2M + # field, vs. `GroupSerializer.permissions`, a computed OptionalField) + # - only touch `serializer.fields[name]` once we know it's real. + if name in serializer.fields: + for field_key, model_key in extra_attributes.items(): + field_value = getattr( + serializer.fields[name], field_key, None + ) + model_value = getattr(field, model_key, None) - if value := self.override_value( - name, field_key, field_value, model_value - ): - serializer_info[name][field_key] = value + if value := self.override_value( + name, field_key, field_value, model_value + ): + serializer_info[name][field_key] = value # Iterate through relations for name, relation in model_fields.relations.items(): @@ -311,14 +330,19 @@ class InvenTreeMetadata(SimpleMetadata): relation.model_field.get_limit_choices_to() ) - for field_key, model_key in extra_attributes.items(): - field_value = getattr(serializer.fields[name], field_key, None) - model_value = getattr(relation.model_field, model_key, None) + # See the comment above, in the 'simple fields' loop - `name` being in + # `serializer_info` doesn't guarantee it's a live `serializer.fields` + # entry (it may be a rehydrated, excluded OptionalField that happens to + # share its name with a real model relation). + if name in serializer.fields: + for field_key, model_key in extra_attributes.items(): + field_value = getattr(serializer.fields[name], field_key, None) + model_value = getattr(relation.model_field, model_key, None) - if value := self.override_value( - name, field_key, field_value, model_value - ): - serializer_info[name][field_key] = value + if value := self.override_value( + name, field_key, field_value, model_value + ): + serializer_info[name][field_key] = value if name in model_default_values: serializer_info[name]['default'] = model_default_values[name] diff --git a/src/backend/InvenTree/InvenTree/middleware.py b/src/backend/InvenTree/InvenTree/middleware.py index 98ffc08c22..0c6ff3c94b 100644 --- a/src/backend/InvenTree/InvenTree/middleware.py +++ b/src/backend/InvenTree/InvenTree/middleware.py @@ -106,6 +106,32 @@ apps_mfa_bypass = [ """App namespaces that bypass MFA enforcement - normal security model is still enforced.""" +def csrf_failure(request, reason=''): + """Custom CSRF failure handler. + + Returns a JSON response for API/headless requests so the frontend can + provide a meaningful error message to the user + """ + from django.views.csrf import csrf_failure as django_default + + if ( + request.path.startswith('/_allauth/') + or request.path.startswith('/api/') + or 'application/json' in request.headers.get('Accept', '') + or 'application/json' in request.headers.get('Content-Type', '') + ): + return JsonResponse( + { + 'detail': _( + 'CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly.' + ) + }, + status=403, + ) + + return django_default(request, reason=reason) + + class AuthRequiredMiddleware: """Check for user to be authenticated.""" diff --git a/src/backend/InvenTree/InvenTree/models.py b/src/backend/InvenTree/InvenTree/models.py index b6f5692c0a..8541b5a1a9 100644 --- a/src/backend/InvenTree/InvenTree/models.py +++ b/src/backend/InvenTree/InvenTree/models.py @@ -23,7 +23,9 @@ from django_q.models import Task from error_report.models import Error from mptt.exceptions import InvalidMove from mptt.models import MPTTModel, TreeForeignKey +from rest_framework.exceptions import PermissionDenied from stdimage.models import StdImageField +from taggit.managers import TaggableManager import common.settings import InvenTree.exceptions @@ -32,6 +34,7 @@ import InvenTree.format import InvenTree.helpers import InvenTree.helpers_model import InvenTree.sentry +import report.mixins logger = structlog.get_logger('inventree') @@ -73,6 +76,14 @@ class DiffMixin: if field.name == 'id': continue + if field.is_relation: + # Compare the raw FK id first (no query) - only dereference to the + # full related object (one query each side) if it actually differs. + # In the common case (unchanged FK) this avoids two full-object + # fetches per relational field for every single save() call. + if getattr(self, field.attname) == getattr(db_instance, field.attname): + continue + if getattr(self, field.name) != getattr(db_instance, field.name): deltas[field.name] = { 'old': getattr(db_instance, field.name), @@ -92,10 +103,23 @@ class PluginValidationMixin(DiffMixin): Any model class which inherits from this mixin will be exposed to the plugin validation system. """ + def should_plugin_validate(self): + """Return True if this model instance should be validated by plugins. + + The default implementation returns True, but this can be overridden in the implementing class if required. + """ + from InvenTree.ready import isReadOnlyCommand + + # Prevent plugin validation when importing or exporting data + return not isReadOnlyCommand() + def run_plugin_validation(self): """Throw this model against the plugin validation interface.""" from plugin import PluginMixinEnum, registry + if not self.should_plugin_validate(): + return + deltas = self.get_field_deltas() for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): @@ -139,15 +163,16 @@ class PluginValidationMixin(DiffMixin): from InvenTree.exceptions import log_error from plugin import PluginMixinEnum, registry - for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): - try: - plugin.validate_model_deletion(self) - except ValidationError as e: - # Plugin might raise a ValidationError to prevent deletion - raise e - except Exception: - log_error('validate_model_deletion', plugin=plugin.slug) - continue + if self.should_plugin_validate(): + for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): + try: + plugin.validate_model_deletion(self) + except ValidationError as e: + # Plugin might raise a ValidationError to prevent deletion + raise e + except Exception: + log_error('validate_model_deletion', plugin=plugin.slug) + continue super().delete(*args, **kwargs) @@ -543,7 +568,8 @@ class InvenTreeParameterMixin(InvenTreePermissionCheckMixin, models.Model): ) @property - def parameters(self) -> QuerySet: + @report.mixins.report_attribute() + def parameters(self) -> report.mixins.QuerySet: """Return a QuerySet containing all the Parameter instances for this model. This will return pre-fetched data if available (i.e. in a serializer context). @@ -553,7 +579,7 @@ class InvenTreeParameterMixin(InvenTreePermissionCheckMixin, models.Model): if 'parameters_list' in cache: return cache['parameters_list'] - return self.parameters_list.all() + return self.parameters_list.all().prefetch_related('template') def delete(self, *args, **kwargs): """Handle the deletion of a model instance. @@ -581,12 +607,21 @@ class InvenTreeParameterMixin(InvenTreePermissionCheckMixin, models.Model): content_type = ContentType.objects.get_for_model(self.__class__) - template_ids = [parameter.template.pk for parameter in other.parameters.all()] + # Skip any parameters which are linked to a template with a uniqueness requirement, + # as copying these values would create conflicting (duplicate) values + copyable_parameters = [ + parameter + for parameter in other.parameters.all().select_related('template') + if parameter.template.unique + == common.models.ParameterTemplate.UniqueOptions.NONE + ] + + template_ids = [parameter.template.pk for parameter in copyable_parameters] # Remove all conflicting parameters first self.parameters_list.filter(template__pk__in=template_ids).delete() - for parameter in other.parameters.all(): + for parameter in copyable_parameters: parameter.pk = None parameter.model_id = self.pk parameter.model_type = content_type @@ -667,7 +702,8 @@ class InvenTreeAttachmentMixin(InvenTreePermissionCheckMixin): super().delete(*args, **kwargs) @property - def attachments(self) -> QuerySet: + @report.mixins.report_attribute() + def attachments(self) -> report.mixins.QuerySet: """Return a queryset containing all attachments for this model.""" return self.attachments_for_model().filter(model_id=self.pk) @@ -719,6 +755,7 @@ class InvenTreeTree(ContentTypeMixin, MPTTModel): order_insertion_by = ['name'] + @transaction.atomic def delete(self, *args, **kwargs): """Handle the deletion of a tree node. @@ -789,18 +826,7 @@ class InvenTreeTree(ContentTypeMixin, MPTTModel): next_tree_id += 1 # 3. Rebuild the model tree(s) as required - # - If any partial rebuilds fail, we will rebuild the entire tree - - result = True - - for tree_id in trees: - if tree_id: - if not self.partial_rebuild(tree_id): - result = False - - if not result: - # Rebuild the entire tree (expensive!!!) - self.__class__.objects.rebuild() + self.__class__.rebuild_trees(trees) def handle_tree_delete(self, delete_children=False, delete_items=False): """Delete a single instance of the tree, based on provided kwargs. @@ -917,40 +943,89 @@ class InvenTreeTree(ContentTypeMixin, MPTTModel): # New instance, so we need to rebuild the tree (if it has a parent) trees.add(self.tree_id) - for tree_id in trees: - if tree_id: - self.partial_rebuild(tree_id) + # Flag to indicate that a tree rebuild task was triggered by this save + self._tree_rebuild_offloaded = False if len(trees) > 0: - # A tree update was performed, so we need to refresh the instance - try: - self.refresh_from_db() - except TransactionManagementError: - # If we are inside a transaction block, we cannot refresh from db - pass - except Exception as e: - # Any other error is unexpected - InvenTree.sentry.report_exception(e) - InvenTree.exceptions.log_error(f'{self.__class__.__name__}.save') + # Offload the tree rebuild(s) to the background worker. + # Note that repeated calls are de-duplicated (per tree), + # so a bulk operation results in a single rebuild per affected tree. + ran_sync = self.__class__.offload_tree_rebuild(trees) + self._tree_rebuild_offloaded = True - def partial_rebuild(self, tree_id: int) -> bool: + if ran_sync: + # The tree was rebuilt synchronously, so refresh the instance + try: + self.refresh_from_db() + except TransactionManagementError: + # If we are inside a transaction block, we cannot refresh from db + pass + except Exception as e: + # Any other error is unexpected + InvenTree.sentry.report_exception(e) + InvenTree.exceptions.log_error(f'{self.__class__.__name__}.save') + + @classmethod + def offload_tree_rebuild(cls, tree_ids) -> bool: + """Offload a rebuild of the specified trees to the background worker. + + - The tree structure (and pathstring values, where applicable) are rebuilt for each tree + - If the background worker is not running, the rebuild is performed synchronously + - Identical pending tasks are skipped, so repeated calls (e.g. during a bulk + operation) result in (at most) a single queued rebuild per affected tree + + Returns: + bool: True if any rebuild was performed synchronously (in the calling thread) + """ + from InvenTree.tasks import offload_task + + ran_sync = False + + for tree_id in tree_ids: + if tree_id: + result = offload_task( + 'InvenTree.tasks.rebuild_model_tree', cls._meta.label_lower, tree_id + ) + + if result is True: + # offload_task returns True if the task ran synchronously + ran_sync = True + + return ran_sync + + @classmethod + def rebuild_trees(cls, tree_ids) -> None: + """Rebuild the specified trees, with fallback to a full rebuild. + + - Perform a partial rebuild for each provided tree_id + - If any partial rebuild fails, rebuild the entire tree (expensive!!!) + """ + result = True + + for tree_id in tree_ids: + if tree_id and not cls.partial_rebuild(tree_id): + result = False + + if not result: + # Rebuild the entire tree (expensive!!!) + cls.objects.rebuild() + + @classmethod + def partial_rebuild(cls, tree_id: int) -> bool: """Perform a partial rebuild of the tree structure. If a failure occurs, log the error and return False. """ try: - self.__class__.objects.partial_rebuild(tree_id) + cls.objects.partial_rebuild(tree_id) return True except Exception as e: # This is a critical error, explicitly report to sentry InvenTree.sentry.report_exception(e) - InvenTree.exceptions.log_error(f'{self.__class__.__name__}.partial_rebuild') + InvenTree.exceptions.log_error(f'{cls.__name__}.partial_rebuild') logger.exception( - 'Failed to rebuild tree for %s <%s>: %s', - self.__class__.__name__, - self.pk, - e, + 'Failed to rebuild tree <%s> for %s: %s', tree_id, cls.__name__, e ) return False @@ -1053,6 +1128,11 @@ class PathStringMixin(models.Model): # Rebuild upper first, to ensure the lower nodes are updated correctly super().save(*args, **kwargs) + # Determine if a tree rebuild task was already triggered by this save + # (e.g. if the node was re-parented) - if so, the pathstring values + # for any lower nodes are updated by that task + rebuild_offloaded = getattr(self, '_tree_rebuild_offloaded', False) + # Ensure that the pathstring is correctly constructed pathstring = self.construct_pathstring(refresh=True) @@ -1063,12 +1143,10 @@ class PathStringMixin(models.Model): self.pathstring = pathstring super().save(*args, **kwargs) - # Bulk-update any child nodes, if applicable - lower_nodes = list( - self.get_descendants(include_self=False).values_list('pk', flat=True) - ) - - self.rebuild_lower_nodes(lower_nodes) + # Update the pathstring values for any lower nodes, + # by offloading the update to the background worker + if not rebuild_offloaded and self.get_descendant_count() > 0: + self.__class__.offload_tree_rebuild([self.tree_id]) def delete(self, *args, **kwargs): """Custom delete method for PathStringMixin. @@ -1086,9 +1164,7 @@ class PathStringMixin(models.Model): ) # Store the node ID values for lower nodes, before we delete this one - lower_nodes = list( - self.get_descendants(include_self=False).values_list('pk', flat=True) - ) + lower_nodes = self.get_lower_nodes() # Delete this node - after which we expect the tree structure will be updated super().delete(*args, **kwargs) @@ -1100,6 +1176,12 @@ class PathStringMixin(models.Model): """String representation of a category is the full path to that category.""" return f'{self.pathstring} - {self.description}' + def get_lower_nodes(self) -> list[int]: + """Return a list of all lower nodes in the tree.""" + return list( + self.get_descendants(include_self=False).values_list('pk', flat=True) + ) + def rebuild_lower_nodes(self, lower_nodes: list[int]): """Rebuild the pathstring for lower nodes in the tree. @@ -1120,6 +1202,52 @@ class PathStringMixin(models.Model): if len(nodes_to_update) > 0: self.__class__.objects.bulk_update(nodes_to_update, ['pathstring']) + @classmethod + def rebuild_tree_pathstring_values(cls, tree_ids) -> None: + """Rebuild the 'pathstring' values for all nodes in the specified trees. + + Each tree is processed in a single pass: + the pathstring for each node is constructed from its parent node, + and any changed values are written back in a single bulk update. + """ + tree_nodes = list(cls.objects.filter(tree_id__in=tree_ids)) + node_map = {node.pk: node for node in tree_nodes} + + # Cache of node ID -> list of path elements (from the top level down) + path_cache: dict[int, list[str]] = {} + + def path_names(node) -> list[str]: + """Construct the path (list of names) for a node, via its parent chain.""" + if node.pk in path_cache: + return path_cache[node.pk] + + names = [str(getattr(node, cls.PATH_FIELD, node.pk))] + + if node.parent_id: + parent = node_map.get(node.parent_id) + + if parent is None: + # Parent node exists outside the selected trees + parent = cls.objects.get(pk=node.parent_id) + node_map[node.parent_id] = parent + + names = [*path_names(parent), *names] + + path_cache[node.pk] = names + return names + + nodes_to_update = [] + + for node in tree_nodes: + pathstring = InvenTree.helpers.constructPathString(path_names(node)) + + if pathstring != node.pathstring: + node.pathstring = pathstring + nodes_to_update.append(node) + + if len(nodes_to_update) > 0: + cls.objects.bulk_update(nodes_to_update, ['pathstring'], batch_size=250) + def construct_pathstring(self, refresh: bool = False) -> str: """Construct the pathstring for this tree node. @@ -1152,8 +1280,9 @@ class PathStringMixin(models.Model): ) @property + @report.mixins.report_attribute() def parentpath(self) -> list: - """Get the parent path of this category. + """Construct the parent path of this tree node. Returns: List of category names from the top level to the parent of this category @@ -1161,8 +1290,9 @@ class PathStringMixin(models.Model): return list(self.get_ancestors()) @property + @report.mixins.report_attribute() def path(self) -> list: - """Get the complete part of this category. + """Construct the complete part of this tree node. e.g. ["Top", "Second", "Third", "This"] @@ -1236,6 +1366,25 @@ class InvenTreeNotesMixin(models.Model): ) +class InvenTreeTagsMixin(models.Model): + """A mixin class for adding tag functionality to a model class. + + The following fields are added to any model which implements this mixin: + + - tags : A text field for storing comma-separated tags + """ + + class Meta: + """Metaclass options for this mixin. + + Note: abstract must be true, as this is only a mixin, not a separate table + """ + + abstract = True + + tags = TaggableManager(blank=True) + + class InvenTreeBarcodeMixin(models.Model): """A mixin class for adding barcode functionality to a model class. @@ -1300,8 +1449,16 @@ class InvenTreeBarcodeMixin(models.Model): return generate_barcode(self) - def format_matched_response(self): + def format_matched_response(self, user, **kwargs): """Format a standard response for a matched barcode.""" + # Check permission for this object + from users.permissions import check_user_permission + + if not check_user_permission(user, self, 'view'): + raise PermissionDenied( + _('User does not have permission to view this model') + ) + data = {'pk': self.pk} if hasattr(self, 'get_api_url'): @@ -1324,6 +1481,7 @@ class InvenTreeBarcodeMixin(models.Model): return data @property + @report.mixins.report_attribute() def barcode(self) -> str: """Format a minimal barcode string (e.g. for label printing).""" return self.format_barcode() @@ -1422,11 +1580,15 @@ def after_failed_task(sender, instance: Task, created: bool, **kwargs): # Create a new Error object associated with this failed task # This will, in turn, trigger a notification to staff users via the Error post_save signal + message = f"Task '{instance.func} ({instance.pk})' failed after {n} attempts" + + logger.error(message) + log_error( 'task_failure', scope='worker', error_name='Task Failure', - error_info=f"Task '{instance.pk}' failed after {n} attempts", + error_info=message, error_data=str(instance.result) if instance.result else '', ) @@ -1498,14 +1660,26 @@ class InvenTreeImageMixin(models.Model): verbose_name=_('Image'), ) - def get_image_url(self): + def get_image_url(self) -> str: """Return the URL of the image for this object.""" if self.image: return InvenTree.helpers.getMediaUrl(self.image) return InvenTree.helpers.getBlankImage() + @property + @report.mixins.report_attribute() + def image_url(self) -> str: + """Return the URL of the image for this object.""" + return self.get_image_url() + def get_thumbnail_url(self) -> str: """Return the URL of the image thumbnail for this object.""" if self.image: return InvenTree.helpers.getMediaUrl(self.image, 'thumbnail') return InvenTree.helpers.getBlankThumbnail() + + @property + @report.mixins.report_attribute() + def thumbnail_url(self) -> str: + """Return the URL of the image thumbnail for this object.""" + return self.get_thumbnail_url() diff --git a/src/backend/InvenTree/InvenTree/permissions.py b/src/backend/InvenTree/InvenTree/permissions.py index 47af7dabcc..060a698c83 100644 --- a/src/backend/InvenTree/InvenTree/permissions.py +++ b/src/backend/InvenTree/InvenTree/permissions.py @@ -415,7 +415,6 @@ class GlobalSettingsPermissions(OASTokenMixin, permissions.BasePermission): """Check that the requesting user is 'admin'.""" try: user = request.user - if request.method in permissions.SAFE_METHODS: return True # Any other methods require staff access permissions diff --git a/src/backend/InvenTree/InvenTree/schema.py b/src/backend/InvenTree/InvenTree/schema.py index 55fa008349..bebc5ed487 100644 --- a/src/backend/InvenTree/InvenTree/schema.py +++ b/src/backend/InvenTree/InvenTree/schema.py @@ -16,6 +16,7 @@ from drf_spectacular.utils import ( extend_schema, extend_schema_view, ) +from rest_framework import serializers from rest_framework.pagination import LimitOffsetPagination from InvenTree.permissions import OASTokenMixin @@ -46,6 +47,20 @@ class ExtendedOAuth2Scheme(DjangoOAuthToolkitScheme): class ExtendedAutoSchema(AutoSchema): """Extend drf-spectacular to allow customizing the schema to match the actual API behavior.""" + def _map_serializer_field(self, field, direction, *args, **kwargs): + """Custom field mapping overrides, falling back to default behavior.""" + schema = super()._map_serializer_field(field, direction, *args, **kwargs) + + direction_value = getattr(direction, 'value', direction) + + # File and image fields in request schemas must be represented as binary + # payloads. In response schemas they are still rendered as URLs. + if direction_value == 'request' and isinstance(field, serializers.FileField): + schema['type'] = 'string' + schema['format'] = 'binary' + + return schema + def is_bulk_action(self, ref: str) -> bool: """Check the class of the current view for the bulk mixins.""" return ref in [c.__name__ for c in type(self.view).__mro__] @@ -208,12 +223,18 @@ def postprocess_schema_enums(result, generator, **kwargs): """Custom patch to ignore some drf-spectacular warnings. - Some warnings are unavoidable due to the way that InvenTree implements generic relationships (via ContentType). + - Some warnings are unavoidable due to the way that InvenTree implements custom (database-editable) status codes: + multiple serializers legitimately expose a 'status' field backed by the same dynamic StockStatus choice set + (e.g. stock adjustment, receiving a purchase order line, disassembling a stock item), and drf-spectacular + cannot settle on a single stable name for the shared, runtime-dependent choice set. - The cleanest way to handle this appears to be to override the 'warn' function from drf-spectacular. Ref: https://github.com/inventree/InvenTree/pull/10699 """ ignore_patterns = [ - 'enum naming encountered a non-optimally resolvable collision for fields named "model_type"' + 'enum naming encountered a non-optimally resolvable collision for fields named "model_type"', + 'enum naming encountered a non-optimally resolvable collision for fields named "status"', + 'encountered multiple names for the same choice set (StatusCustomKeyEnum)', ] if any(pattern in msg for pattern in ignore_patterns): @@ -282,7 +303,7 @@ def postprocess_print_stats(result, generator, request, public): scopes = {} for path, details in rlt_dict.items(): if details['oauth']: - for scope in details['oauth']: + for scope in list(details['oauth']): if scope not in scopes: scopes[scope] = [] scopes[scope].append(path) @@ -343,7 +364,7 @@ def schema_for_view_output_options(view_class): return extended_view -def exclude_from_schema(klass: type, alternative_path: str) -> type: +def exclude_from_schema(klass: type[Any], alternative_path: str) -> type[Any]: """Decorator to exclude a view from the OpenAPI schema. This is used to hide legacy endpoints from the schema, while still retaining them for backwards compatibility. diff --git a/src/backend/InvenTree/InvenTree/sentry.py b/src/backend/InvenTree/InvenTree/sentry.py index 5307220ee9..bf1252b331 100644 --- a/src/backend/InvenTree/InvenTree/sentry.py +++ b/src/backend/InvenTree/InvenTree/sentry.py @@ -36,6 +36,7 @@ def sentry_ignore_errors(): # pragma: no cover rest_framework.exceptions.AuthenticationFailed, rest_framework.exceptions.NotAuthenticated, rest_framework.exceptions.PermissionDenied, + rest_framework.exceptions.MethodNotAllowed, rest_framework.exceptions.ValidationError, ] diff --git a/src/backend/InvenTree/InvenTree/serializers.py b/src/backend/InvenTree/InvenTree/serializers.py index 3df76e9e3c..b1f0f5ce80 100644 --- a/src/backend/InvenTree/InvenTree/serializers.py +++ b/src/backend/InvenTree/InvenTree/serializers.py @@ -6,6 +6,7 @@ from dataclasses import dataclass from decimal import Decimal from typing import Optional +from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError as DjangoValidationError from django.core.files.storage import default_storage @@ -49,6 +50,12 @@ class OptionalField: This allows for optimization of database queries based only on the requested data. + If the field embeds another model's data (e.g. a nested "detail" serializer), the + requesting user's view permission against that model is checked before the field is + included - this is inferred from `serializer_class.Meta.model` unless `model` is + explicitly provided. This prevents a user from seeing embedded data (e.g. a Part, + via a BuildOrder's `part_detail`) that they do not have direct permission to view. + Example: class MySerializer(FilterableSerializerMixin, serializers.ModelSerializer): my_optional_field = OptionalField( @@ -70,6 +77,7 @@ class OptionalField: filter_name: Optional[str] = None filter_by_query: bool = True prefetch_fields: Optional[list[str]] = None + model: Optional[type] = None class FilterableSerializerMixin: @@ -120,20 +128,27 @@ class FilterableSerializerMixin: Order of operations: - - If we are generating the schema, always include the field + - If we are generating the schema, always include the field (unless the user does not have permission to view) - If this is a write request (POST, PUT, PATCH) and we are not exporting, always include the field - If this is a top-level serializer, check the request query parameters for the filter name - Check the kwargs provided to the serializer instance - Finally, fall back to the default_include value for the field itself + + Whatever the outcome of the above, if the field embeds another model's data, the + result is then narrowed by the requesting user's view permission against that + model (see `check_field_permission`) - the field is never included for a user who + cannot view the embedded model, regardless of query parameters or defaults. """ field_ref = field.filter_name or field_name # If we have already found a value for this filter, use it # This allows multiple optional fields to share the same filter value + # Note: fields sharing a filter_ref may still embed different models, so the + # permission gate is re-applied per-field even when the raw value is cached cached_value = self.optional_filters.get(field_ref, None) if cached_value is not None: - return cached_value + return self.check_field_permission(field, cached_value) # First, check kwargs provided to the serializer instance # We also pop the value to avoid issues with nested serializers @@ -149,10 +164,12 @@ class FilterableSerializerMixin: field_kwargs = field.serializer_kwargs or {} - # Skip filtering for a write request - all fields should be present for data creation + # Skip filtering for a write request + # All fields should be present for data creation, + # excepting those for which the user does not have the required permissions if method := getattr(self.request, 'method', None): if method not in SAFE_METHODS and not self.is_exporting(): - return True + return self.check_field_permission(field, True) else: # Ignore write_only fields for read requests if field_kwargs.get('write_only', False): @@ -175,7 +192,68 @@ class FilterableSerializerMixin: if value is None: value = field.default_include - return value + return self.check_field_permission(field, value) + + def check_field_permission(self, field: OptionalField, included: bool) -> bool: + """Narrow an inclusion decision by the requesting user's view permission. + + An OptionalField which embeds another model's data (e.g. `part_detail` embedding + a Part) should not be included unless the requesting user actually has view + permission on that model - otherwise a user could see e.g. Part data via a + BuildOrder's `part_detail` field without having Part view permission themselves. + + Arguments: + field: The OptionalField instance being resolved + included: The inclusion decision made so far + + Returns: + False if the field embeds a model the requesting user cannot view, otherwise + the original `included` value unchanged. + """ + if not included: + return included + + model = field.model or getattr( + getattr(field.serializer_class, 'Meta', None), 'model', None + ) + + if model is None: + return included + + # A handful of models describe *permission metadata itself* (who a user is, + # what a role can do) rather than embedded business data - gating these behind + # a role would hide a user's own account/role information from themselves and + # from almost every non-admin user, which is a different (and much broader) + # concern than embedding e.g. Part/Company records. Deliberately exempted here: + # - auth_user: username attribution fields (issued_by_detail, checked_by_detail, ...) + # - auth_group: group membership/attribution (ExtendedUserSerializer.groups, ...) + # - users_ruleset: role/permission listings (GroupSerializer.roles, ...) + # - users_owner: user/group "owner" wrapper (responsible_detail, ...) - already in + # get_ruleset_ignore() so check_user_permission would return True anyway, but + # exempted explicitly here to document intent and skip the call + from django.contrib.auth.models import Group + + from users.models import Owner, RuleSet + + if model in (get_user_model(), Group, Owner, RuleSet): + return included + + user = getattr(self.request, 'user', None) + + if user is None: + return included + + cache = self.__dict__.setdefault('_field_permission_cache', {}) + cache_key = (user.pk, model) + + if cache_key in cache: + return cache[cache_key] + + from users.permissions import check_user_permission + + result = check_user_permission(user, model, 'view') + cache[cache_key] = result + return result def find_optional_fields(self): """Find all optional fields defined on this serializer.""" @@ -219,7 +297,16 @@ class FilterableSerializerMixin: def get_field_names(self, declared_fields, info): """Remove unused fields before returning field names.""" - field_names = super().get_field_names(declared_fields, info) + # Note: when `Meta.fields` is a list/tuple, DRF's base `get_field_names` + # returns that *exact* list object rather than a copy - a single list + # shared by every instance of this serializer class, across every thread. + # Copy it before mutating below - otherwise concurrent requests that + # disagree on whether an OptionalField (e.g. `tags`) should be included + # append/remove it on each other's shared list. A request whose own + # append lands can still have the field silently removed again by a + # concurrent request's `.remove()` before its own field-building loop + # (in DRF's `get_fields()`, which iterates this same list) reaches it. + field_names = list(super().get_field_names(declared_fields, info)) # Add any optional fields which are included for field_name in self.optional_fields: @@ -291,6 +378,110 @@ class FilterableSerializerMixin: return queryset +@dataclass +class PrefetchSpec: + """Describes a single bulk-prefetch to run against incoming (un-validated) request data. + + Used by `BulkPrefetchSerializerMixin` to populate the {pk: instance} caches that + `InvenTree.fields.PrefetchedPrimaryKeyRelatedField` looks up against. + + Attributes: + list_field: Name of the list field in the raw request data (e.g. 'items'). + pk_field: Name of the pk-valued key within each entry of that list (e.g. 'stock_item'). + queryset: Base queryset used to resolve the collected pks (e.g. `StockItem.objects.select_related(...)`). + cache_key: Context key to store the resulting {pk: instance} map under - must match + the `cache_key` passed to the corresponding `PrefetchedPrimaryKeyRelatedField`. + """ + + list_field: str + pk_field: str + queryset: QuerySet + cache_key: str + + +class BulkPrefetchSerializerMixin: + """Mixin for a parent serializer whose nested list fields use PrefetchedPrimaryKeyRelatedField. + + Without this mixin, PrefetchedPrimaryKeyRelatedField falls back to one .get() query per + list entry, since no cache has been populated in the context - for a request with + hundreds of entries, that turns validation itself into an O(n) query cost. + + Subclasses declare `prefetch_fields`, a list of `PrefetchSpec` objects describing which + lists of raw entries to bulk-resolve before per-field validation runs: + + class MySerializer(BulkPrefetchSerializerMixin, serializers.Serializer): + prefetch_fields = [ + PrefetchSpec('items', 'stock_item', StockItem.objects.all(), '_stock_item'), + PrefetchSpec('items', 'build_line', BuildLine.objects.all(), '_build_line'), + ] + + items = MyItemSerializer(many=True) + + class MyItemSerializer(serializers.Serializer): + stock_item = PrefetchedPrimaryKeyRelatedField( + cache_key='_stock_item', queryset=StockItem.objects.all() + ) + build_line = PrefetchedPrimaryKeyRelatedField( + cache_key='_build_line', queryset=BuildLine.objects.all() + ) + + Multiple specs may share the same `list_field` (as above), one per pk-valued key + that needs resolving within each entry. + """ + + prefetch_fields: list[PrefetchSpec] = [] + + @staticmethod + def _extract_pks(entries, key: str) -> set: + """Pull the raw pk values for 'key' out of a list of raw (un-validated) dicts. + + Silently ignores entries which are not dicts, or whose value cannot be + interpreted as an integer pk - those are left for the per-field validation + (PrefetchedPrimaryKeyRelatedField) to reject with the usual error message. + """ + pks = set() + + for entry in entries or []: + if not isinstance(entry, dict): + continue + + try: + pks.add(int(entry.get(key))) + except (TypeError, ValueError): + continue + + return pks + + def to_internal_value(self, data): + """Bulk-prefetch the objects referenced by each declared PrefetchSpec. + + Populating context[cache_key] here means PrefetchedPrimaryKeyRelatedField resolves + each entry via an O(1) dict lookup, so the whole request is validated in a fixed, + small number of queries instead of one query per list entry. + """ + if isinstance(data, dict): + for spec in self.prefetch_fields: + pks = self._extract_pks(data.get(spec.list_field), spec.pk_field) + + self.context[spec.cache_key] = { + obj.pk: obj for obj in spec.queryset.filter(pk__in=pks) + } + + self.after_prefetch(data) + + return super().to_internal_value(data) + + def after_prefetch(self, data): + """Optional hook called once the pk caches are populated, before nested field validation runs. + + Override this to bulk-compute anything else that per-entry `validate_()` + or `validate()` methods would otherwise recompute one entry at a time - e.g. an + aggregate that would otherwise cost one query per entry. Stash the result in + `self.context` (the same mechanism `prefetch_fields` uses) so nested serializers + can look it up. + """ + + class EmptySerializer(serializers.Serializer): """Empty serializer for use in testing.""" @@ -600,7 +791,7 @@ class InvenTreeModelSerializer(serializers.ModelSerializer): Default implementation returns an empty list """ - return [] + return getattr(self, 'SKIP_CREATE_FIELDS', []) def save(self, **kwargs): """Catch any django ValidationError thrown at the moment `save` is called, and re-throw as a DRF ValidationError.""" @@ -699,10 +890,6 @@ class InvenTreeTaggitSerializer(TaggitSerializer): return self._save_tags(tag_object, to_be_tagged) -class InvenTreeTagModelSerializer(InvenTreeTaggitSerializer, InvenTreeModelSerializer): - """Combination of InvenTreeTaggitSerializer and InvenTreeModelSerializer.""" - - class InvenTreeAttachmentSerializerField(serializers.FileField): """Override the DRF native FileField serializer, to remove the leading server path. @@ -764,6 +951,56 @@ class InvenTreeDecimalField(serializers.FloatField): raise serializers.ValidationError(_('Invalid value')) +class CustomStatusSerializerMixin(serializers.Serializer): + """Serializer mixin for models that support custom status values. + + Provides a `status_text` SerializerMethodField that resolves custom + status labels with a single database query per model per serializer + context (i.e. one query for a whole list page) rather than one query per + object (N+1). + """ + + status_text = serializers.SerializerMethodField() + + @extend_schema_field(serializers.CharField(allow_null=True)) + def get_status_text(self, instance) -> Optional[str]: + """Return the human-readable status text for the instance. + + Uses a per-context cache keyed by model name so that all objects in a + single serialization pass share one DB hit for custom label lookup. + + During write operations DRF may call to_representation on the raw + validated_data dict rather than a model instance (e.g. when building + response headers). Return None in that case — the response body is + always produced from a real instance via a separate serializer call. + """ + if not hasattr(instance, 'get_custom_status'): + return None + + custom_key = instance.get_custom_status() + + if custom_key is None: + return instance.status_class.label(instance.get_status()) + + model_name = instance._meta.model_name + cache_key = f'_custom_status_labels_{model_name}' + + # Cache a dict of custom status labels for this model, if not already cached + if cache_key not in self.context: + from common.models import InvenTreeCustomUserStateModel + + self.context[cache_key] = { + obj.key: obj.label + for obj in InvenTreeCustomUserStateModel.objects.filter( + model__model=model_name + ) + } + + return self.context[cache_key].get( + custom_key, instance.status_class.label(instance.get_status()) + ) + + class NotesFieldMixin: """Serializer mixin for handling 'notes' fields. @@ -776,9 +1013,13 @@ class NotesFieldMixin: super().__init__(*args, **kwargs) if hasattr(self, 'context'): + request = self.context.get('request', None) + method = getattr(request, 'method', None) + if view := self.context.get('view', None): if ( issubclass(view.__class__, ListModelMixin) + and method in SAFE_METHODS and not InvenTree.ready.isGeneratingSchema() ): self.fields.pop('notes', None) @@ -875,3 +1116,104 @@ class ContentTypeField(serializers.ChoiceField): ) return content_type + + +class DuplicateOptionsSerializer(serializers.Serializer): + """Generic serializer for specifying copy options when duplicating a model instance. + + Builds its fields dynamically at instantiation time so the same class can be + reused for any model without subclassing. + """ + + # Special 'shortcut' fields which are used for multiple models + DEFAULT_FIELDS = [ + ( + 'copy_parameters', + _('Copy Parameters'), + _('Copy parameters from the original item'), + False, + ), + ( + 'copy_lines', + _('Copy Lines'), + _('Copy line items from the original order'), + False, + ), + ( + 'copy_extra_lines', + _('Copy Extra Lines'), + _('Copy extra line items from the original order'), + False, + ), + ] + + def __init__( + self, + queryset: QuerySet, + *args, + copy_fields: Optional[list[dict]] = None, + **kwargs, + ): + """Initialise the serializer and dynamically attach fields. + + Arguments: + queryset: Queryset used for the `original` PrimaryKeyRelatedField. + copy_fields: Optional list of dicts, each describing one boolean copy toggle. + Keys: + name: (str, required) + label: (str, optional) + help_text: (str, optional) + default: (bool, optional, default True) + """ + # Enforce certain properties onto this serializer + kwargs['label'] = kwargs.get('label', _('Duplication Options')) + kwargs['help_text'] = kwargs.get( + 'help_text', _('Specify options for duplicating this item') + ) + kwargs['required'] = False + kwargs['write_only'] = True + + copy_fields = copy_fields or [] + copy_field_names = [spec['name'] for spec in copy_fields] + + # Apply "default" fields + for name, label, help_text, default_value in self.DEFAULT_FIELDS: + popped_value = kwargs.pop(name, default_value) + + if name in copy_field_names: + # Manually supplied field, continue + continue + + if popped_value: + copy_fields.append({ + 'name': name, + 'label': label, + 'help_text': help_text, + 'default': True, + }) + + super().__init__(*args, **kwargs) + + # Re-class the instance with a model-specific subclass, + # so that each model generates a unique schema component name + if self.__class__ is DuplicateOptionsSerializer: + self.__class__ = type( + f'{queryset.model.__name__}DuplicateOptionsSerializer', + (DuplicateOptionsSerializer,), + {}, + ) + + self.fields['original'] = serializers.PrimaryKeyRelatedField( + queryset=queryset, + required=True, + label=_('Original'), + help_text=_('Select instance to duplicate'), + ) + + for spec in copy_fields or []: + self.fields[spec['name']] = serializers.BooleanField( + required=False, + default=spec.get('default', True), + label=spec.get('label', spec['name']), + help_text=spec.get('help_text', ''), + ) diff --git a/src/backend/InvenTree/InvenTree/setting/db_backend.py b/src/backend/InvenTree/InvenTree/setting/db_backend.py index 3cedea07d4..6defd52374 100644 --- a/src/backend/InvenTree/InvenTree/setting/db_backend.py +++ b/src/backend/InvenTree/InvenTree/setting/db_backend.py @@ -5,10 +5,23 @@ from pathlib import Path import structlog from InvenTree.config import get_boolean_setting, get_config_value, get_setting +from InvenTree.ready import isInWorkerThread logger = structlog.get_logger('inventree') +def _get_conn_max_age() -> int | None: + """Return the configured CONN_MAX_AGE value. + + Accepts an integer number of seconds, or 'None' for unlimited persistence. + Defaults to 0 (close the connection after each request). + """ + value = get_setting('INVENTREE_DB_CONN_MAX_AGE', 'database.conn_max_age', 0) + if value is None or str(value).strip().lower() == 'none': + return None + return int(value) + + def get_db_backend(): """Return the database backend configuration.""" # For the core database configuration values, we test for UPPERCASE configuration values as a backup, @@ -43,6 +56,13 @@ def get_db_backend(): ) or get_config_value('database.OPTIONS') or {}, + # Seconds to keep idle connections open across requests (0 = close after each request). + # Set to None for unlimited. Enable CONN_HEALTH_CHECKS alongside any non-zero value + # so stale connections are detected before use rather than causing request failures. + 'CONN_MAX_AGE': _get_conn_max_age(), + 'CONN_HEALTH_CHECKS': get_boolean_setting( + 'INVENTREE_DB_CONN_HEALTH_CHECKS', 'database.conn_health_checks', False + ), } # Check for required keys @@ -113,9 +133,9 @@ def set_postgres_options(db_options: dict): if 'connect_timeout' not in db_options: # The DB server is in the same data center, it should not take very # long to connect to the database server - # # seconds, 2 is minimum allowed by libpq - db_options['connect_timeout'] = int( - get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 2) + # Note: 2 seconds is minimum allowed by libpq + db_options['connect_timeout'] = max( + 2, int(get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 10)) ) # Setup TCP keepalive @@ -133,7 +153,7 @@ def set_postgres_options(db_options: dict): if 'keepalives_idle' not in db_options: db_options['keepalives_idle'] = int( get_setting( - 'INVENTREE_DB_TCP_KEEPALIVES_IDLE', 'database.tcp_keepalives_idle', 1 + 'INVENTREE_DB_TCP_KEEPALIVES_IDLE', 'database.tcp_keepalives_idle', 5 ) ) @@ -143,7 +163,7 @@ def set_postgres_options(db_options: dict): get_setting( 'INVENTREE_DB_TCP_KEEPALIVES_INTERVAL', 'database.tcp_keepalives_interval', - '1', + '5', ) ) @@ -157,10 +177,13 @@ def set_postgres_options(db_options: dict): ) ) - # # Milliseconds for how long pending data should remain unacked - # by the remote server - # TODO: Supported starting in PSQL 11 - # "tcp_user_timeout": int(os.getenv("PGTCP_USER_TIMEOUT", "1000"), + # # Milliseconds for how long pending data should remain unacked by the remote server + if 'tcp_user_timeout' not in db_options: + db_options['tcp_user_timeout'] = int( + get_setting( + 'INVENTREE_DB_TCP_USER_TIMEOUT', 'database.tcp_user_timeout', '2000' + ) + ) # Postgres's default isolation level is Read Committed which is # normally fine, but most developers think the database server is @@ -178,10 +201,21 @@ def set_postgres_options(db_options: dict): else IsolationLevel.READ_COMMITTED ) + # Specify the application name for the database connection + # This can be useful for debugging and monitoring purposes + if 'application_name' not in db_options: + db_options['application_name'] = ( + 'inventree-worker' if isInWorkerThread() else 'inventree-server' + ) + def set_mysql_options(db_options: dict): """Set database options specific to mysql backend.""" - # TODO TCP time outs and keepalives + # Timeout values + if 'connect_timeout' not in db_options: + db_options['connect_timeout'] = int( + get_setting('INVENTREE_DB_TIMEOUT', 'database.timeout', 10) + ) # MariaDB's default isolation level is Repeatable Read which is # normally fine, but most developers think the database server is diff --git a/src/backend/InvenTree/InvenTree/setting/ldap.py b/src/backend/InvenTree/InvenTree/setting/ldap.py index 6e6f57989f..3b39179701 100644 --- a/src/backend/InvenTree/InvenTree/setting/ldap.py +++ b/src/backend/InvenTree/InvenTree/setting/ldap.py @@ -9,8 +9,8 @@ def get_ldap_config(debug: bool = False) -> dict: The returned settings will be updated into the globals() object, and will be used to configure the LDAP authentication backend. """ - import django_auth_ldap.config # type: ignore[unresolved-import] - import ldap # type: ignore[unresolved-import] + import django_auth_ldap.config # ty: ignore[unresolved-import] + import ldap # ty: ignore[unresolved-import] # get global options from dict and use ldap.OPT_* as keys and values global_options_dict = get_setting( diff --git a/src/backend/InvenTree/InvenTree/settings.py b/src/backend/InvenTree/InvenTree/settings.py index 3aa32669be..b42351035b 100644 --- a/src/backend/InvenTree/InvenTree/settings.py +++ b/src/backend/InvenTree/InvenTree/settings.py @@ -56,7 +56,11 @@ INVENTREE_BASE_URL = 'https://inventree.org' INVENTREE_NEWS_URL = f'{INVENTREE_BASE_URL}/news/feed.atom' # Determine if we are running in "test" mode e.g. "manage.py test" -TESTING = 'test' in sys.argv or 'TESTING' in os.environ or 'pytest' in sys.argv +TESTING = ( + 'test' in sys.argv + or 'TESTING' in os.environ + or any('pytest' in arg for arg in sys.argv) +) if TESTING: # Use a weaker password hasher for testing (improves testing speed) @@ -525,6 +529,8 @@ REST_FRAMEWORK = { 'DEFAULT_METADATA_CLASS': 'InvenTree.metadata.InvenTreeMetadata', 'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer'], 'TOKEN_MODEL': 'users.models.ApiToken', + 'DEFAULT_THROTTLE_CLASSES': [], + 'DEFAULT_THROTTLE_RATES': {}, } if DEBUG: @@ -540,6 +546,21 @@ if USE_JWT: JWT_AUTH_REFRESH_COOKIE = 'inventree-token' INSTALLED_APPS.append('rest_framework_simplejwt') +# Throtteling setup +THROTTLE_ANON = get_setting('INVENTREE_THROTTLE_ANON', 'throttle.anon', '20/minute') +THROTTLE_USER = get_setting('INVENTREE_THROTTLE_USER', 'throttle.user', '60/second') + +if not DEBUG and THROTTLE_ANON and str(THROTTLE_ANON).lower() != 'none': + REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']['anon'] = THROTTLE_ANON + REST_FRAMEWORK['DEFAULT_THROTTLE_CLASSES'].append( + 'rest_framework.throttling.AnonRateThrottle' + ) +if not DEBUG and THROTTLE_USER and str(THROTTLE_USER).lower() != 'none': + REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']['user'] = THROTTLE_USER + REST_FRAMEWORK['DEFAULT_THROTTLE_CLASSES'].append( + 'rest_framework.throttling.UserRateThrottle' + ) + # WSGI default setting WSGI_APPLICATION = 'InvenTree.wsgi.application' @@ -847,6 +868,7 @@ valid_cookie_modes = ['lax', 'strict', 'none'] COOKIE_MODE = COOKIE_MODE.capitalize() if COOKIE_MODE in valid_cookie_modes else False # Additional CSRF settings +CSRF_FAILURE_VIEW = 'InvenTree.middleware.csrf_failure' CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN' CSRF_COOKIE_NAME = 'csrftoken' @@ -990,13 +1012,11 @@ USERSESSIONS_TRACK_ACTIVITY = True # allauth rate limiting: https://docs.allauth.org/en/latest/account/rate_limits.html # The default login rate limit is "5/m/user,5/m/ip,5/m/key" login_attempts = get_setting('INVENTREE_LOGIN_ATTEMPTS', 'login_attempts', 5) - try: - login_attempts = int(login_attempts) - login_attempts = f'{login_attempts}/m,{login_attempts}/m' + # Only the per-account ('key') limit is user-configurable with an int - use a str for more custom limits + login_attempts = f'10/m/ip,{int(login_attempts)}/m/key' except ValueError: # pragma: no cover pass - ACCOUNT_RATE_LIMITS = {'login_failed': login_attempts} # Default protocol for login @@ -1096,6 +1116,21 @@ if len(GLOBAL_SETTINGS_OVERRIDES) > 0: # Set the global setting logger.debug('- Override value for %s = ********', key) +# Plugin settings overrides +# If provided, these values will override any plugin settings (and prevent them from being changed) +# Specified as a nested dict: {plugin_slug: {SETTING_KEY: value}} +PLUGIN_SETTING_OVERRIDES = get_setting( + 'INVENTREE_PLUGIN_SETTINGS', 'plugin_settings', typecast=dict +) + +if len(PLUGIN_SETTING_OVERRIDES) > 0: + logger.info( + 'INVE-I1: Plugin settings overrides: %s', list(PLUGIN_SETTING_OVERRIDES.keys()) + ) + for slug, overrides in PLUGIN_SETTING_OVERRIDES.items(): + for key in overrides: + logger.debug('- Override value for %s.%s = ********', slug, key) + # User interface customization values CUSTOM_LOGO = get_setting('INVENTREE_CUSTOM_LOGO', 'customize.logo', typecast=str) @@ -1165,3 +1200,6 @@ if 'dbbackup' not in STORAGES: if _media: MEDIA_URL = _media PRESIGNED_URL_EXPIRATION = 600 + +# Taggit settings +TAGGIT_CASE_INSENSITIVE = True diff --git a/src/backend/InvenTree/InvenTree/tasks.py b/src/backend/InvenTree/InvenTree/tasks.py index c231bf2197..f16832c531 100644 --- a/src/backend/InvenTree/InvenTree/tasks.py +++ b/src/backend/InvenTree/InvenTree/tasks.py @@ -1,10 +1,13 @@ """Functions for tasks and a few general async tasks.""" +import contextvars import json import os import re import warnings +from collections import defaultdict from collections.abc import Callable +from contextlib import contextmanager from dataclasses import dataclass from datetime import datetime, timedelta from typing import Optional @@ -13,7 +16,7 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.core.exceptions import AppRegistryNotReady, ValidationError from django.core.management import call_command -from django.db import DEFAULT_DB_ALIAS, connections +from django.db import DEFAULT_DB_ALIAS, connections, transaction from django.db.migrations.executor import MigrationExecutor from django.db.utils import NotSupportedError, OperationalError, ProgrammingError from django.utils import timezone @@ -201,6 +204,86 @@ def check_existing_task(taskname, group: str, *args, **kwargs) -> Optional[str]: return task_id +# Context-local batch of pending offload_task() calls (see batch_offload_tasks()) +_task_batch: contextvars.ContextVar = contextvars.ContextVar('task_batch', default=None) + + +class TaskBatch: + """Collects offload_task() calls made within a batch_offload_tasks() scope. + + Entries are grouped by (taskname, group, force_async), so that each distinct + combination triggered within the batch is flushed via its own bulk_offload_task() call. + """ + + def __init__(self): + """Initialize an empty batch.""" + self.entries: dict[tuple, list] = defaultdict(list) + + def add( + self, taskname, group: str, force_async: bool, args: tuple, kwargs: dict + ) -> None: + """Record a single offload_task() call against this batch.""" + self.entries[taskname, group, force_async].append((args, kwargs)) + + def flush(self) -> None: + """Fire a bulk_offload_task() call for each (taskname, group, force_async) group collected so far.""" + entries, self.entries = self.entries, defaultdict(list) + + for (taskname, group, force_async), task_entries in entries.items(): + bulk_offload_task( + taskname, task_entries, group=group, force_async=force_async + ) + + +@contextmanager +def batch_offload_tasks(): + """Batch offload_task() calls made within this scope into bulk_offload_task() calls. + + Any offload_task() call made (directly, or indirectly via a nested function call) while + this context is active is queued instead of immediately offloaded - *except* for calls + which pass force_sync=True, which always run immediately and synchronously as before. + Excluding these is necessary because a forced-sync call is relied upon to have completed, + with its side effects visible, by the time offload_task() returns control to the caller - + deferring it would silently break that contract. + + The queued calls are flushed - grouped by (taskname, group, force_async), one + bulk_offload_task() call per group - when the current database transaction commits (or + immediately, if no transaction is active). If the transaction is instead rolled back, the + queued calls are discarded, rather than being fired for a write that never happened. + + Note: bulk_offload_task() does not perform duplicate-task checking, unlike offload_task()'s + default (check_duplicates=True) behavior - queued calls are never deduplicated, regardless + of the check_duplicates value passed to offload_task(). + + A batched offload_task() call always returns True immediately, rather than a task ID - + the actual task ID is not known until the batch is flushed, possibly well after the + call returns. Callers which depend on the returned task ID should not use this context. + + Nesting is not supported: a nested batch_offload_tasks() call reuses the outer batch, + and only the outermost call schedules a flush. + + This mirrors plugin.base.event.events.batch_events() and stock.models.batch_tracking_entries() + - see batch_events()'s docstring for the reasoning behind the on-commit flush and the + context-local (rather than parameter-based) design. + + Yields: + The current TaskBatch instance + """ + if _task_batch.get() is not None: + # Already inside a batch - extend it, rather than creating a nested one + yield _task_batch.get() + return + + batch = TaskBatch() + token = _task_batch.set(batch) + + try: + yield batch + finally: + _task_batch.reset(token) + transaction.on_commit(batch.flush) + + def offload_task( taskname, *args, @@ -224,11 +307,18 @@ def offload_task( Returns: str | bool: Task ID if the task was offloaded, True if ran synchronously, False otherwise """ - from InvenTree.exceptions import log_error - # Extract group information from kwargs group = kwargs.pop('group', 'inventree') + if not force_sync and (batch := _task_batch.get()) is not None: + # A batch_offload_tasks() context is active - queue this task rather than + # offloading it immediately (force_sync=True calls never reach this branch - + # see batch_offload_tasks() for why they are excluded from batching) + batch.add(taskname, group, force_async, args, kwargs) + return True + + from InvenTree.exceptions import log_error + try: import importlib @@ -282,40 +372,31 @@ def offload_task( # function was passed - use that _func = taskname else: - # Split path + # Split on the last dot: everything before is the module path, + # everything after is the function name. rsplit handles any depth + # (e.g. 'app.module.func' or 'app.sub.module.func'). try: - app, mod, func = taskname.split('.') - app_mod = app + '.' + mod + module_path, func_name = taskname.rsplit('.', 1) except ValueError: raise_warning( f"WARNING: '{taskname}' not started - Malformed function path" ) return False - # Import module from app try: - _mod = importlib.import_module(app_mod) + _mod = importlib.import_module(module_path) except ModuleNotFoundError: log_error('offload_task', scope='worker') raise_warning( - f"WARNING: '{taskname}' not started - No module named '{app_mod}'" + f"WARNING: '{taskname}' not started - No module named '{module_path}'" ) return False - # Retrieve function - try: - _func = getattr(_mod, func) - except AttributeError: # pragma: no cover - # getattr does not work for local import - _func = None - - try: - if not _func: - _func = eval(func) # pragma: no cover - except NameError: + _func = getattr(_mod, func_name, None) + if _func is None: log_error('offload_task', scope='worker') raise_warning( - f"WARNING: '{taskname}' not started - No function named '{func}'" + f"WARNING: '{taskname}' not started - No function named '{func_name}'" ) return False @@ -332,6 +413,96 @@ def offload_task( return True +def bulk_offload_task( + taskname, + entries: list, + group: str = 'inventree', + force_sync: bool = False, + force_async: bool = False, +) -> bool: + """Queue the same background task many times, in a single bulk database write. + + Equivalent to calling offload_task() once per (args, kwargs) pair in 'entries', but + writes all of the queued tasks to the django-q2 ORM broker table (OrmQ) in a single + bulk_create() call, rather than one INSERT per task. + + Note: InvenTree always configures django-q2 to use the ORM broker (see + InvenTree.setting.worker.get_worker_config), so this does not need to handle any + other broker backend. + + Arguments: + taskname: The name of the task to be run, in the format 'app.module.function' + entries: List of (args, kwargs) tuples, one per task instance to queue + group: The task group to assign to each queued task + force_sync: If True, run all tasks synchronously (even if workers are running) + force_async: If True, force all tasks to be queued (even if workers are not running) + + Returns: + bool: True if the tasks were queued (or run synchronously), False otherwise + """ + if not entries: + return False + + try: + from django_q.brokers import get_broker + from django_q.humanhash import uuid + from django_q.models import OrmQ + from django_q.signing import SignedPackage + + from InvenTree.status import is_worker_running + except AppRegistryNotReady: # pragma: no cover + logger.warning( + "Could not offload bulk task '%s' - app registry not ready", taskname + ) + force_sync = True + except (OperationalError, ProgrammingError): # pragma: no cover + raise_warning(f"Could not offload bulk task '{taskname}' - database not ready") + force_sync = True + + if not force_async and (force_sync or not is_worker_running()): + # Workers are not available - fall back to running each task synchronously + for args, kwargs in entries: + offload_task( + taskname, + *args, + group=group, + force_sync=True, + check_duplicates=False, + **kwargs, + ) + + return True + + broker = get_broker() + + tasks = [] + + for args, kwargs in entries: + name, task_id = uuid() + + task = { + 'id': task_id, + 'name': name, + 'func': taskname, + 'args': args, + 'kwargs': kwargs, + 'group': group, + 'started': timezone.now(), + } + + tasks.append( + OrmQ( + key=broker.list_key or 'inventree', + payload=SignedPackage.dumps(task), + lock=timezone.now(), + ) + ) + + OrmQ.objects.bulk_create(tasks) + + return True + + def get_queued_task(task_id: str): """Find the task in the queue, if it exists. @@ -446,22 +617,65 @@ def scheduled_task( return _task_wrapper -@tracer.start_as_current_span('heartbeat') -@scheduled_task(ScheduledTask.MINUTES, 5) -def heartbeat(): - """Simple task which runs at 5 minute intervals, so we can determine that the background worker is actually running. +@tracer.start_as_current_span('rebuild_model_tree') +def rebuild_model_tree(model: str, tree_id: int) -> None: + """Rebuild the tree structure (and pathstring values) for a tree model. - (There is probably a less "hacky" way of achieving this)? + This task is offloaded to the background worker whenever nodes are + restructured (e.g. re-parented), to avoid expensive tree rebuild + operations blocking the calling thread. + + Arguments: + model: Label of the model class to rebuild, e.g. 'stock.stocklocation' + tree_id: ID of the tree to rebuild """ + from django.apps import apps + + import InvenTree.models + + try: + model_class = apps.get_model(model) + except (LookupError, ValueError): + logger.warning("rebuild_model_tree: Model '%s' does not exist", model) + return + + if not issubclass(model_class, InvenTree.models.InvenTreeTree): + logger.warning("rebuild_model_tree: Model '%s' is not a tree model", model) + return + + # Rebuild the tree structure, based on the parent-child relationships + model_class.rebuild_trees([tree_id]) + + # Rebuild the 'pathstring' values for the entire tree (if applicable) + if issubclass(model_class, InvenTree.models.PathStringMixin): + model_class.rebuild_tree_pathstring_values([tree_id]) + + +@tracer.start_as_current_span('heartbeat') +@scheduled_task(ScheduledTask.MINUTES, 1) +def heartbeat(): + """Simple task which runs at 1 minute intervals, so we can determine that the background worker is actually running.""" try: from django_q.models import OrmQ, Success except AppRegistryNotReady: # pragma: no cover logger.info('Could not perform heartbeat task - App registry not ready') return - threshold = timezone.now() - timedelta(minutes=30) + # Write a timestamp file so that health checks can verify worker liveness + # without needing to start a full Django process. + import tempfile + from pathlib import Path - # Delete heartbeat results more than half an hour old, + try: + Path(tempfile.gettempdir()).joinpath('inventree_worker_heartbeat').write_text( + str(timezone.now().timestamp()) + ) + except Exception: + pass + + threshold = timezone.now() - timedelta(minutes=15) + + # Delete heartbeat results more than 15 minutes old, # otherwise they just create extra noise heartbeats = Success.objects.filter( func='InvenTree.tasks.heartbeat', started__lte=threshold @@ -642,6 +856,7 @@ def check_for_updates(): data = json.loads(response.text) tag = data.get('tag_name', None) + release_url = data.get('html_url') if not tag: raise ValueError("'tag_name' missing from GitHub response") # pragma: no cover @@ -671,11 +886,13 @@ def check_for_updates(): trigger_notification( None, 'update_available', + notification_uid=0, targets=get_user_model().objects.filter(is_superuser=True), delivery_methods={InvenTreeUINotifications}, context={ 'name': _('Update Available'), 'message': _('An update for InvenTree is available'), + 'link': release_url, }, ) diff --git a/src/backend/InvenTree/InvenTree/test_api.py b/src/backend/InvenTree/InvenTree/test_api.py index 5475edd03a..c74632d4bc 100644 --- a/src/backend/InvenTree/InvenTree/test_api.py +++ b/src/backend/InvenTree/InvenTree/test_api.py @@ -4,12 +4,15 @@ from base64 import b64encode from pathlib import Path from tempfile import TemporaryDirectory +from django.core.exceptions import AppRegistryNotReady +from django.test import TestCase from django.urls import reverse from rest_framework import status from InvenTree.api import read_license_file from InvenTree.api_version import INVENTREE_API_VERSION +from InvenTree.exceptions import exception_handler from InvenTree.unit_test import InvenTreeAPITestCase, InvenTreeTestCase from InvenTree.version import inventreeApiText, parse_version_text from users.ruleset import RULESET_NAMES @@ -66,6 +69,25 @@ class HTMLAPITests(InvenTreeTestCase): self.assertEqual(response.status_code, 404) +class ExceptionHandlerTests(TestCase): + """Tests for the custom DRF exception handler.""" + + def test_app_registry_not_ready(self): + """AppRegistryNotReady should be reported as a transient 503, not a 500. + + Regression test: this can be raised on a request served by one thread while + the plugin registry is mid-reload on another (see + plugin.registry.PluginsRegistry._reload_apps, which briefly clears Django's + app registry) - it is not a genuine server error, so the client should be + told to retry rather than seeing a hard failure. + """ + response = exception_handler(AppRegistryNotReady(), {}) + + self.assertEqual(response.status_code, 503) + self.assertEqual(response.data['error'], 'AppRegistryNotReady') + self.assertEqual(response['Retry-After'], '1') + + class ApiAccessTests(InvenTreeAPITestCase): """Tests for various access scenarios with the InvenTree API.""" @@ -612,6 +634,7 @@ class GeneralApiTests(InvenTreeAPITestCase): response = self.get( url, headers={'Authorization': f'Token {token}'}, max_query_count=20 ) + self.assertIsNotNone(data.get('active_plugins')) self.assertGreater(len(response.json()['database']), 4) data = response.json() diff --git a/src/backend/InvenTree/InvenTree/test_commands.py b/src/backend/InvenTree/InvenTree/test_commands.py index 82caec7d73..7554f16db0 100644 --- a/src/backend/InvenTree/InvenTree/test_commands.py +++ b/src/backend/InvenTree/InvenTree/test_commands.py @@ -1,5 +1,7 @@ """Tests for custom InvenTree management commands.""" +import os +import subprocess from pathlib import Path from django.conf import settings @@ -15,6 +17,48 @@ from InvenTree.config import get_testfolder_dir class CommandTestCase(TestCase): """Test case for custom management commands.""" + def test_makemigrations_currency_overrides_no_changes(self): + """Ensure currency list changes do not cause migration drift.""" + currency_sets = ['USD,EUR,GBP', 'JPY,CNY,KRW'] + + for currency_codes in currency_sets: + with self.subTest(currency_codes=currency_codes): + old_value = os.environ.get('INVENTREE_CURRENCY_CODES') + + try: + os.environ['INVENTREE_CURRENCY_CODES'] = currency_codes + project_dir = Path(__file__).resolve().parents[1] + + result = subprocess.run( + [ + 'python3', + 'manage.py', + 'makemigrations', + '--check', + '--dry-run', + '--verbosity', + '0', + ], + cwd=project_dir, + env=os.environ.copy(), + capture_output=True, + text=True, + check=False, + ) + + if result.returncode != 0: + self.fail( + 'makemigrations reported schema changes ' + f'for INVENTREE_CURRENCY_CODES={currency_codes}\n' + f'stdout:\n{result.stdout}\n' + f'stderr:\n{result.stderr}' + ) + finally: + if old_value is None: + os.environ.pop('INVENTREE_CURRENCY_CODES', None) + else: + os.environ['INVENTREE_CURRENCY_CODES'] = old_value + def test_schema(self): """Test the schema generation command.""" output = call_command('schema', file='schema.yml', verbosity=0) diff --git a/src/backend/InvenTree/InvenTree/test_helpers/__init__.py b/src/backend/InvenTree/InvenTree/test_helpers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/backend/InvenTree/InvenTree/test_helpers/sample_tasks.py b/src/backend/InvenTree/InvenTree/test_helpers/sample_tasks.py new file mode 100644 index 0000000000..39f16907f8 --- /dev/null +++ b/src/backend/InvenTree/InvenTree/test_helpers/sample_tasks.py @@ -0,0 +1,6 @@ +"""Sample task functions used by offload_task unit tests.""" + + +def get_result(): + """Return a fixed value; used to verify 4-part module paths resolve correctly.""" + return 'abc' diff --git a/src/backend/InvenTree/InvenTree/test_helpers_db.py b/src/backend/InvenTree/InvenTree/test_helpers_db.py new file mode 100644 index 0000000000..de4da41b50 --- /dev/null +++ b/src/backend/InvenTree/InvenTree/test_helpers_db.py @@ -0,0 +1,163 @@ +"""Functional tests for the InvenTree.helpers_db module.""" + +from django.db import connection +from django.test import TestCase +from django.test.utils import CaptureQueriesContext + +from company.models import Company, Contact +from InvenTree.helpers_db import bulk_create_and_fetch +from order.models import PurchaseOrder +from part.models import Part +from stock.models import StockItem + + +class BulkCreateAndFetchTest(TestCase): + """Tests for the bulk_create_and_fetch helper function.""" + + def test_basic(self): + """Created items are returned with populated, unique primary keys.""" + company = Company.objects.create(name='ACME') + + items = [Contact(company=company, name=f'Contact {idx}') for idx in range(10)] + + result = bulk_create_and_fetch(Contact, items) + + self.assertEqual(len(result), 10) + + pks = [c.pk for c in result] + + # Every item has a valid, unique primary key + self.assertTrue(all(pk is not None for pk in pks)) + self.assertEqual(len(pks), len(set(pks))) + + # Returned items exactly match what is actually in the database + db_pks = set( + Contact.objects.filter(company=company).values_list('pk', flat=True) + ) + self.assertEqual(set(pks), db_pks) + + # Temporary bulk-create metadata should have been cleared again + for contact in Contact.objects.filter(pk__in=pks): + self.assertIsNone(contact.metadata) + + def test_with_filters(self): + """Additional filters correctly scope the returned queryset.""" + company_a = Company.objects.create(name='Company A') + company_b = Company.objects.create(name='Company B') + + items_a = [Contact(company=company_a, name=f'A{i}') for i in range(3)] + items_b = [Contact(company=company_b, name=f'B{i}') for i in range(4)] + + result_a = bulk_create_and_fetch( + Contact, items_a, filters={'company': company_a} + ) + result_b = bulk_create_and_fetch( + Contact, items_b, filters={'company': company_b} + ) + + self.assertEqual(len(result_a), 3) + self.assertEqual(len(result_b), 4) + + self.assertTrue(all(c.company_id == company_a.pk for c in result_a)) + self.assertTrue(all(c.company_id == company_b.pk for c in result_b)) + + def test_ignores_pre_existing_rows(self): + """The 'search floor' should exclude pre-existing rows in the table.""" + company = Company.objects.create(name='ACME') + + # Pre-existing item, *not* created via the helper + Contact.objects.create(company=company, name='Existing') + + items = [Contact(company=company, name=f'New {i}') for i in range(2)] + result = bulk_create_and_fetch(Contact, items) + + self.assertEqual(len(result), 2) + self.assertNotIn('Existing', [c.name for c in result]) + + def test_empty_list(self): + """Calling with an empty list of items should not raise, and return no items.""" + result = bulk_create_and_fetch(Contact, []) + self.assertEqual(len(result), 0) + + def test_does_not_mutate_caller_filters(self): + """The caller-provided 'filters' dict should not be mutated as a side effect.""" + company = Company.objects.create(name='ACME') + filters = {'company': company} + + items = [Contact(company=company, name='Contact')] + bulk_create_and_fetch(Contact, items, filters=filters) + + def test_purchase_order(self): + """The helper works for the PurchaseOrder model.""" + supplier = Company.objects.create(name='Supplier Co', is_supplier=True) + + references = [f'PO-{idx:04d}' for idx in range(10)] + + items = [ + PurchaseOrder(supplier=supplier, reference=ref, description=f'Order {ref}') + for ref in references + ] + + result = bulk_create_and_fetch(PurchaseOrder, items) + + self.assertEqual(len(result), 10) + + pks = [o.pk for o in result] + self.assertTrue(all(pk is not None for pk in pks)) + self.assertEqual(len(pks), len(set(pks))) + + self.assertEqual( + set(result.values_list('reference', flat=True)), set(references) + ) + + for order in PurchaseOrder.objects.filter(pk__in=pks): + self.assertIsNone(order.metadata) + + def test_stock_item(self): + """The helper works for the StockItem model.""" + part = Part.objects.create(name='Widget', description='A widget') + + items = [StockItem(part=part, quantity=idx + 1) for idx in range(10)] + + result = bulk_create_and_fetch(StockItem, items) + + self.assertEqual(len(result), 10) + + pks = [si.pk for si in result] + self.assertTrue(all(pk is not None for pk in pks)) + self.assertEqual(len(pks), len(set(pks))) + + self.assertEqual( + sorted(result.values_list('quantity', flat=True)), + sorted(idx + 1 for idx in range(10)), + ) + + for stock_item in StockItem.objects.filter(pk__in=pks): + self.assertIsNone(stock_item.metadata) + + def _create_and_count_queries(self, n: int) -> int: + """Bulk-create 'n' Contact items, and return the number of queries used.""" + company = Company.objects.create(name=f'Company {n}') + + items = [Contact(company=company, name=f'Contact {i}') for i in range(n)] + + with CaptureQueriesContext(connection) as ctx: + result = bulk_create_and_fetch(Contact, items) + + self.assertEqual(len(result), n) + + MAX_QUERIES = 25 if n > 100 else 10 + + self.assertLess(len(ctx.captured_queries), MAX_QUERIES) + + return len(ctx.captured_queries) + + def test_query_count_is_constant(self): + """The number of queries used should not depend on the number of created items.""" + small_query_count = self._create_and_count_queries(5) + large_query_count = self._create_and_count_queries(100) + + self.assertEqual(small_query_count, large_query_count) + + # Perform a very large bulk-create - this will be batched + self._create_and_count_queries(2000) diff --git a/src/backend/InvenTree/InvenTree/test_middleware.py b/src/backend/InvenTree/InvenTree/test_middleware.py index 410822d3cf..b6b89cf31d 100644 --- a/src/backend/InvenTree/InvenTree/test_middleware.py +++ b/src/backend/InvenTree/InvenTree/test_middleware.py @@ -2,8 +2,7 @@ from unittest.mock import patch -from django.conf import settings -from django.http import Http404 +from django.http import Http404, HttpRequest from django.urls import reverse from error_report.models import Error @@ -289,18 +288,63 @@ class MiddlewareTests(InvenTreeTestCase): response, 'window.INVENTREE_SETTINGS', status_code=500 ) - # Log stuff # TODO remove - print( - '###DBG-TST###', - 'site', - settings.SITE_URL, - 'trusted', - settings.CSRF_TRUSTED_ORIGINS, - ) - # Check that the correct step triggers the error message self.assertContains( response, 'INVE-E7: The visited path `http://testserver` does not match', status_code=500, ) + + def test_csrf_failure(self): + """Test the custom CSRF failure handler.""" + from InvenTree.middleware import csrf_failure + + EXPECTED_DETAIL = 'CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly.' + + def make_request(path, headers=None): + request = HttpRequest() + request.path = path + request.META['SERVER_NAME'] = 'testserver' + request.META['SERVER_PORT'] = '80' + for key, value in (headers or {}).items(): + request.META[f'HTTP_{key.upper().replace("-", "_")}'] = value + return request + + # API path -> JSON 403 with meaningful message + response = csrf_failure( + make_request('/api/part/'), reason='origin check failed' + ) + self.assertEqual(response.status_code, 403) + import json + + data = json.loads(response.content) + self.assertEqual(data['detail'], EXPECTED_DETAIL) + + # allauth headless path -> JSON 403 + response = csrf_failure(make_request('/_allauth/browser/v1/auth/login')) + self.assertEqual(response.status_code, 403) + data = json.loads(response.content) + self.assertEqual(data['detail'], EXPECTED_DETAIL) + + # Accept: application/json header -> JSON 403 + response = csrf_failure( + make_request('/some/other/path/', {'Accept': 'application/json'}), + reason='origin check failed', + ) + self.assertEqual(response.status_code, 403) + data = json.loads(response.content) + self.assertEqual(data['detail'], EXPECTED_DETAIL) + + # Content-Type: application/json header -> JSON 403 + response = csrf_failure( + make_request('/some/other/path/', {'Content-Type': 'application/json'}), + reason='origin check failed', + ) + self.assertEqual(response.status_code, 403) + data = json.loads(response.content) + self.assertEqual(data['detail'], EXPECTED_DETAIL) + + # Plain browser request -> falls back to Django default CSRF page (403 HTML, not JSON) + response = csrf_failure(make_request('/web/'), reason='origin check failed') + self.assertEqual(response.status_code, 403) + self.assertNotIn(b'application/json', response.get('Content-Type', '').encode()) diff --git a/src/backend/InvenTree/InvenTree/test_serializers.py b/src/backend/InvenTree/InvenTree/test_serializers.py index aeccf73d4b..9228cc6bbb 100644 --- a/src/backend/InvenTree/InvenTree/test_serializers.py +++ b/src/backend/InvenTree/InvenTree/test_serializers.py @@ -1,5 +1,9 @@ """Low level tests for serializers.""" +import sys +import threading +from concurrent.futures import ThreadPoolExecutor + from django.contrib import admin from django.contrib.auth.models import User from django.urls import path, reverse @@ -11,6 +15,7 @@ from InvenTree.mixins import ListCreateAPI, OutputOptionsMixin from InvenTree.serializers import OptionalField from InvenTree.unit_test import InvenTreeAPITestCase from InvenTree.urls import backendpatterns +from part.models import Part class SampleSerializer( @@ -23,7 +28,15 @@ class SampleSerializer( """Meta options.""" model = User - fields = ['field_a', 'field_b', 'field_c', 'field_d', 'field_e', 'id'] + fields = [ + 'field_a', + 'field_b', + 'field_c', + 'field_d', + 'field_e', + 'field_f', + 'id', + ] field_a = SerializerMethodField(method_name='sample') field_b = OptionalField( @@ -49,6 +62,15 @@ class SampleSerializer( filter_by_query=False, ) + # Field which embeds a model the requesting user may not have permission to view + field_f = OptionalField( + serializer_class=SerializerMethodField, + serializer_kwargs={'method_name': 'sample'}, + default_include=True, + filter_name='field_f', + model=Part, + ) + def sample(self, obj): """Sample method field.""" return 'sample123' @@ -111,3 +133,86 @@ class FilteredSerializers(InvenTreeAPITestCase): self.assertContains(response, 'field_c') self.assertContains(response, 'field_d') self.assertNotContains(response, 'field_e') + + def test_permission_gating(self): + """An OptionalField which embeds a model should respect the model's permissions. + + 'field_f' defaults to included, but declares 'model=Part' - it should only + appear in the response if the requesting user actually has 'part.view'. + """ + with self.settings( + ROOT_URLCONF=__name__, + CSRF_TRUSTED_ORIGINS=['http://testserver'], + SITE_URL='http://testserver', + ): + url = reverse('sample-list', urlconf=__name__) + + # No 'part' role assigned - field should be hidden despite default_include=True + response = self.client.get(url) + self.assertContains(response, 'field_a') + self.assertNotContains(response, 'field_f') + + # Assign the 'part.view' role - field should now appear + self.assignRole('part.view') + response = self.client.get(url) + self.assertContains(response, 'field_f') + self.assertEqual(response.data[0]['field_f'], 'sample123') + + +class ConcurrentOptionalFieldTests(InvenTreeAPITestCase): + """Regression test for a race condition in `FilterableSerializerMixin.get_field_names`. + + When `Meta.fields` is a plain list (as it is for every real serializer in this + codebase), DRF's `ModelSerializer.get_field_names()` returns that *exact* list + object rather than a copy - a single list shared by every instance of the + serializer class, across every thread. `get_field_names()` used to `.append()`/ + `.remove()` an OptionalField's name directly on that shared list. + + Two concurrent requests that disagree on whether an OptionalField (here, + `field_b`) should be included could then corrupt each other's output: one + request's `.append('field_b')` could be immediately undone by another, + concurrent request's `.remove('field_b')` on the *same* list object, before + the first request's own field-building loop (DRF's `get_fields()`, which + iterates this same list) reached it - silently dropping the field from a + response that should have included it. + """ + + def test_concurrent_optional_field_inclusion(self): + """Serializers built concurrently with conflicting field_b inclusion must not corrupt each other. + + Builds many `SampleSerializer` instances in parallel threads, alternating + whether `field_b` should be included (passed directly as a constructor + kwarg, per `FilterableSerializerMixin.is_field_included`, so this needs no + HTTP request/response machinery). Every instance's rendered `.data` must + match what *that* instance asked for, regardless of what other concurrently + running instances asked for. + """ + errors = [] + lock = threading.Lock() + + def worker(include: bool): + serializer = SampleSerializer(self.user, field_b=include) + has_field_b = 'field_b' in serializer.data + if has_field_b != include: + with lock: + errors.append((include, has_field_b)) + + # Force frequent thread switches - the race window between the shared + # list being fixed up and it being iterated over is only a handful of + # bytecodes wide, so the default switch interval rarely lands inside it. + old_interval = sys.getswitchinterval() + sys.setswitchinterval(1e-6) + try: + with ThreadPoolExecutor(max_workers=16) as executor: + futures = [executor.submit(worker, i % 2 == 0) for i in range(2000)] + for future in futures: + future.result() + finally: + sys.setswitchinterval(old_interval) + + self.assertEqual( + errors, + [], + f'{len(errors)} / 2000 concurrently-built serializers had the wrong ' + f"'field_b' inclusion (expected, got) pairs shown above", + ) diff --git a/src/backend/InvenTree/InvenTree/test_tasks.py b/src/backend/InvenTree/InvenTree/test_tasks.py index 04df009198..098b1cc9d0 100644 --- a/src/backend/InvenTree/InvenTree/test_tasks.py +++ b/src/backend/InvenTree/InvenTree/test_tasks.py @@ -2,14 +2,17 @@ import os from datetime import timedelta +from unittest.mock import patch from django.conf import settings from django.contrib.auth.models import User from django.core.management import call_command +from django.db import transaction from django.db.utils import NotSupportedError from django.test import TestCase from django.utils import timezone +import requests_mock from django_q.models import OrmQ, Schedule, Task from error_report.models import Error @@ -67,26 +70,72 @@ class InvenTreeTaskTests(PluginRegistryMixin, TestCase): # Run with string ref InvenTree.tasks.offload_task('InvenTree.test_tasks.get_result') - # Error runs + # The error-path tests below all use force_sync=True so that the sync + # resolution code is exercised regardless of whether background workers + # happen to be running in this environment. + # Malformed taskname with self.assertWarnsMessage( UserWarning, "WARNING: 'InvenTree' not started - Malformed function path" ): - InvenTree.tasks.offload_task('InvenTree') + InvenTree.tasks.offload_task('InvenTree', force_sync=True) # Non existent app with self.assertWarnsMessage( UserWarning, "WARNING: 'InvenTreeABC.test_tasks.doesnotmatter' not started - No module named 'InvenTreeABC.test_tasks'", ): - InvenTree.tasks.offload_task('InvenTreeABC.test_tasks.doesnotmatter') + InvenTree.tasks.offload_task( + 'InvenTreeABC.test_tasks.doesnotmatter', force_sync=True + ) # Non existent function with self.assertWarnsMessage( UserWarning, "WARNING: 'InvenTree.test_tasks.doesnotexist' not started - No function named 'doesnotexist'", ): - InvenTree.tasks.offload_task('InvenTree.test_tasks.doesnotexist') + InvenTree.tasks.offload_task( + 'InvenTree.test_tasks.doesnotexist', force_sync=True + ) + + def test_offloading_deep_path(self): + """Test that task paths with more than 3 components are resolved correctly. + + Previously the sync fallback split on '.' requiring exactly 3 parts, + so a 4-part path raised ValueError and returned False with no warning. + Now rsplit('.', 1) is used, so any depth works. + """ + # 4-part valid path: module = 'InvenTree.test_helpers.sample_tasks', func = 'get_result' + InvenTree.tasks.offload_task( + 'InvenTree.test_helpers.sample_tasks.get_result', force_sync=True + ) + + # 4-part path with a non-existent module — should warn cleanly rather than crash + with self.assertWarnsMessage( + UserWarning, + "WARNING: 'InvenTreeABC.sub.tasks.doesnotmatter' not started - No module named 'InvenTreeABC.sub.tasks'", + ): + InvenTree.tasks.offload_task( + 'InvenTreeABC.sub.tasks.doesnotmatter', force_sync=True + ) + + def test_offloading_no_eval_bypass(self): + """Verify that names in tasks.py scope cannot be resolved via an eval bypass. + + The previous implementation fell back to eval(func) when getattr returned + None, evaluating the function name in the local scope of offload_task rather + than in the target module. This meant a Python builtin like 'eval', or any + name imported into tasks.py, could be invoked via a crafted taskname. The + replacement uses only getattr on the imported module and rejects anything + not found there. + """ + # 'eval' is a Python builtin; it is not an attribute of InvenTree.test_tasks. + # Previously eval('eval') in tasks.py's scope would resolve it; now it fails. + with self.assertWarnsMessage( + UserWarning, + "WARNING: 'InvenTree.test_tasks.eval' not started - No function named 'eval'", + ): + InvenTree.tasks.offload_task('InvenTree.test_tasks.eval', force_sync=True) def test_task_heartbeat(self): """Test the task heartbeat.""" @@ -121,19 +170,57 @@ class InvenTreeTaskTests(PluginRegistryMixin, TestCase): errors = Error.objects.filter(when__lte=threshold) self.assertEqual(len(errors), 0) - def test_task_check_for_updates(self): - """Test the task check_for_updates.""" - # Check that setting should be empty + @requests_mock.Mocker() + def test_task_check_for_updates(self, requests_mocker): + """Test update notification creation and deduplication.""" + from common.models import NotificationEntry, NotificationMessage + from common.serializers import NotificationMessageSerializer + + self.ensurePluginsLoaded(force=True) + + user = User.objects.create_superuser( + username='update_admin', + email='update@example.com', + password='test-password', + ) + + release_url = 'https://github.com/InvenTree/InvenTree/releases/tag/99.99.99' + + requests_mocker.get( + 'https://api.github.com/repos/inventree/inventree/releases/latest', + json={'tag_name': '99.99.99', 'html_url': release_url}, + ) + InvenTreeSetting.set_setting('_INVENTREE_LATEST_VERSION', '') - self.assertEqual(InvenTreeSetting.get_setting('_INVENTREE_LATEST_VERSION'), '') - # Get new version - InvenTree.tasks.offload_task(InvenTree.tasks.check_for_updates) + with ( + patch( + 'InvenTree.tasks.isInvenTreeUpToDate', return_value=False + ) as mock_up_to_date, + patch('InvenTree.tasks.check_daily_holdoff', return_value=True), + ): + InvenTree.tasks.check_for_updates() - # Check that setting is not empty - response = InvenTreeSetting.get_setting('_INVENTREE_LATEST_VERSION') - self.assertNotEqual(response, '') - self.assertTrue(bool(response)) + self.assertEqual( + InvenTreeSetting.get_setting('_INVENTREE_LATEST_VERSION'), '99.99.99' + ) + self.assertEqual(NotificationMessage.objects.count(), 1) + self.assertEqual(NotificationEntry.objects.count(), 1) + + message = NotificationMessage.objects.get(user=user) + entry = NotificationEntry.objects.get() + + self.assertEqual(message.link, release_url) + self.assertEqual(entry.uid, '0') + + serialized = NotificationMessageSerializer(message).data + self.assertEqual(serialized['target']['link'], release_url) + + InvenTree.tasks.check_for_updates() + + self.assertEqual(NotificationMessage.objects.count(), 1) + self.assertEqual(NotificationEntry.objects.count(), 1) + mock_up_to_date.assert_called() def test_task_check_for_migrations(self): """Test the task check_for_migrations.""" @@ -365,3 +452,175 @@ class InvenTreeTaskTests(PluginRegistryMixin, TestCase): # 20 more tasks should have been added self.assertEqual(OrmQ.objects.count(), 41) + + def test_bulk_offload(self): + """Test the bulk_offload_task function.""" + # Start with a blank slate + OrmQ.objects.all().delete() + + entries = [ + ((idx, idx + 1), {'animal': f'animal_{idx}', 'count': idx}) + for idx in range(10) + ] + + # Queuing all 10 tasks should only take a single database write (bulk_create) + with self.assertNumQueries(1): + result = InvenTree.tasks.bulk_offload_task( + 'dummy_module.dummy_function', entries, force_async=True + ) + + self.assertTrue(result) + self.assertEqual(OrmQ.objects.count(), 10) + + # Read out the pending tasks, and check that the args / kwargs match + queued_tasks = OrmQ.objects.all().order_by('id') + + for task, (args, kwargs) in zip(queued_tasks, entries, strict=True): + self.assertEqual(task.func(), 'dummy_module.dummy_function') + self.assertEqual(task.group(), 'inventree') + self.assertEqual(task.args(), args) + self.assertEqual(task.kwargs(), kwargs) + + +class TaskBatchTests(TestCase): + """Unit tests for the batch_offload_tasks() context manager.""" + + def setUp(self): + """Start each test with an empty task queue.""" + super().setUp() + OrmQ.objects.all().delete() + + def test_tasks_queued_and_flushed_on_commit(self): + """Tasks offloaded inside batch_offload_tasks() are queued and flushed as one bulk write on commit.""" + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), InvenTree.tasks.batch_offload_tasks(): + for idx in range(10): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function', + idx, + force_async=True, + animal=f'animal_{idx}', + ) + + # Nothing should be queued yet - the batch only flushes on commit + self.assertEqual(OrmQ.objects.count(), 0) + + self.assertEqual(OrmQ.objects.count(), 10) + + queued_tasks = OrmQ.objects.all().order_by('id') + + for idx, task in enumerate(queued_tasks): + self.assertEqual(task.func(), 'dummy_module.dummy_function') + self.assertEqual(task.group(), 'inventree') + self.assertEqual(task.args(), (idx,)) + self.assertEqual(task.kwargs(), {'animal': f'animal_{idx}'}) + + def test_tasks_grouped_by_name_and_group(self): + """Tasks with different (taskname, group) combinations are flushed as separate bulk writes.""" + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), InvenTree.tasks.batch_offload_tasks(): + for idx in range(5): + InvenTree.tasks.offload_task( + 'dummy_module.task_a', idx, force_async=True, group='alpha' + ) + for idx in range(3): + InvenTree.tasks.offload_task( + 'dummy_module.task_b', idx, force_async=True, group='beta' + ) + + self.assertEqual(OrmQ.objects.count(), 8) + self.assertEqual( + sum( + 1 + for t in OrmQ.objects.all() + if t.func() == 'dummy_module.task_a' and t.group() == 'alpha' + ), + 5, + ) + self.assertEqual( + sum( + 1 + for t in OrmQ.objects.all() + if t.func() == 'dummy_module.task_b' and t.group() == 'beta' + ), + 3, + ) + + def test_tasks_discarded_on_rollback(self): + """Tasks queued in a batch are discarded, not fired, if the transaction rolls back.""" + with self.captureOnCommitCallbacks(execute=True): + try: + with transaction.atomic(), InvenTree.tasks.batch_offload_tasks(): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function', force_async=True + ) + raise ValueError('boom') + except ValueError: + pass + + self.assertEqual(OrmQ.objects.count(), 0) + + def test_tasks_outside_batch_fire_immediately(self): + """Tasks offloaded outside any batch_offload_tasks() context are unaffected - fired immediately.""" + InvenTree.tasks.offload_task('dummy_module.dummy_function', force_async=True) + + # No transaction commit or captureOnCommitCallbacks needed - it was never queued + self.assertEqual(OrmQ.objects.count(), 1) + + def test_nested_batch_share_one_flush(self): + """A nested batch_offload_tasks() call reuses the outer batch, rather than flushing twice.""" + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), InvenTree.tasks.batch_offload_tasks(): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function', 1, force_async=True + ) + with InvenTree.tasks.batch_offload_tasks(): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function', 2, force_async=True + ) + self.assertEqual(OrmQ.objects.count(), 0) + + self.assertEqual(OrmQ.objects.count(), 2) + + def test_force_sync_excluded_from_batch(self): + """force_sync=True calls bypass batch_offload_tasks() entirely and run immediately.""" + calls = [] + + def sync_target(): + calls.append('ran') + + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), InvenTree.tasks.batch_offload_tasks(): + InvenTree.tasks.offload_task(sync_target, force_sync=True) + + # Ran immediately - not deferred to flush, and never touched the task queue + self.assertEqual(calls, ['ran']) + self.assertEqual(OrmQ.objects.count(), 0) + + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function', force_async=True + ) + + # The (non-force_sync) async call is queued, not yet in OrmQ + self.assertEqual(OrmQ.objects.count(), 0) + + # After commit: only the batched async call produced an OrmQ entry + self.assertEqual(OrmQ.objects.count(), 1) + self.assertEqual(calls, ['ran']) + + def test_batched_calls_skip_duplicate_check(self): + """Unlike individual offload_task() calls, batched calls are never deduplicated.""" + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), InvenTree.tasks.batch_offload_tasks(): + for _ in range(3): + InvenTree.tasks.offload_task( + 'dummy_module.dummy_function_dup', + 1, + 2, + animal='cat', + force_async=True, + ) + + # All 3 identical calls were queued, unlike the non-batched dedup behavior + # exercised in InvenTreeTaskTests.test_duplicate_tasks + self.assertEqual(OrmQ.objects.count(), 3) diff --git a/src/backend/InvenTree/InvenTree/tests.py b/src/backend/InvenTree/InvenTree/tests.py index d00c868133..d3d04c9194 100644 --- a/src/backend/InvenTree/InvenTree/tests.py +++ b/src/backend/InvenTree/InvenTree/tests.py @@ -1,9 +1,11 @@ """Test general functions and helpers.""" +import base64 import os -import time from datetime import datetime, timedelta from decimal import Decimal +from io import BytesIO +from pathlib import Path from unittest import mock from zoneinfo import ZoneInfo @@ -12,15 +14,20 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.core import mail from django.core.exceptions import ValidationError +from django.core.files.base import ContentFile +from django.core.files.storage import default_storage from django.test import TestCase, override_settings from django.urls import reverse from django.utils import timezone import pint.errors +import requests_mock from djmoney.contrib.exchange.exceptions import MissingRate from djmoney.contrib.exchange.models import Rate, convert_money from djmoney.money import Money from maintenance_mode.core import get_maintenance_mode, set_maintenance_mode +from PIL import Image +from rest_framework import serializers from sesame.utils import get_user from stdimage.models import StdImageFieldFile @@ -102,10 +109,9 @@ class TreeFixtureTest(TestCase): self.run_tree_test(Build) def test_stock(self): - """Test MPTT tree structure for Stock model.""" - from stock.models import StockItem, StockLocation + """Test MPTT tree structure for StockLocation model.""" + from stock.models import StockLocation - self.run_tree_test(StockItem) self.run_tree_test(StockLocation) @@ -292,6 +298,16 @@ class ConversionTest(TestCase): ) self.assertAlmostEqual(output, expected, 12) + # Test that 'R' is interpreted as ohms + # Ref: https://github.com/inventree/InvenTree/issues/12063 + r_tests = [('8R6', 8.6), ('10R', 10), ('4R7', 4.7), ('100R', 100)] + + for val, expected in r_tests: + output = InvenTree.conversion.convert_physical_value( + val, 'ohm', strip_units=True + ) + self.assertAlmostEqual(output, expected, 6) + def test_scientific_notation(self): """Test that scientific notation is handled correctly.""" tests = [ @@ -597,35 +613,6 @@ class FormatTest(TestCase): with self.assertRaises(ValueError): InvenTree.format.extract_named_group('test', 'PO-ABC-xyz', 'PO-###-{test}') - def test_currency_formatting(self): - """Test that currency formatting works correctly for multiple currencies.""" - test_data = ( - (Money(3651.285718, 'USD'), 4, True, '$3,651.2857'), - (Money(487587.849178, 'CAD'), 5, True, 'CA$487,587.84918'), - (Money(0.348102, 'EUR'), 1, False, '0.3'), - (Money(0.916530, 'GBP'), 1, True, '£0.9'), - (Money(61.031024, 'JPY'), 3, False, '61.031'), - (Money(49609.694602, 'JPY'), 1, True, '¥49,609.7'), - (Money(155565.264777, 'AUD'), 2, False, '155,565.26'), - (Money(0.820437, 'CNY'), 4, True, 'CN¥0.8204'), - (Money(7587.849178, 'EUR'), 0, True, '€7,588'), - (Money(0.348102, 'GBP'), 3, False, '0.348'), - (Money(0.652923, 'CHF'), 0, True, 'CHF1'), - (Money(0.820437, 'CNY'), 1, True, 'CN¥0.8'), - (Money(98789.5295680, 'CHF'), 0, False, '98,790'), - (Money(0.585787, 'USD'), 1, True, '$0.6'), - (Money(0.690541, 'CAD'), 3, True, 'CA$0.691'), - (Money(427.814104, 'AUD'), 5, True, 'A$427.81410'), - ) - - with self.settings(LANGUAGE_CODE='en-us'): - for value, decimal_places, include_symbol, expected_result in test_data: - result = InvenTree.format.format_money( - value, decimal_places=decimal_places, include_symbol=include_symbol - ) - - self.assertEqual(result, expected_result) - class TestHelpers(TestCase): """Tests for InvenTree helper functions.""" @@ -721,12 +708,59 @@ class TestHelpers(TestCase): def test_logo_image(self): """Test for retrieving logo image.""" - # By default, there is no custom logo provided + # By default, there is no custom logo provided - return the default InvenTree logo logo = helpers.getLogoImage() self.assertEqual(logo, '/static/img/inventree.png') + # When requested 'as_file', the logo must be returned as an embeddable + # base64 data URI - file:// URIs are no longer permitted in reports logo = helpers.getLogoImage(as_file=True) - self.assertEqual(logo, f'file://{settings.STATIC_ROOT}/img/inventree.png') + self.assertNotIn('file://', logo) + self.assertTrue(logo.startswith('data:image/png;base64,')) + + # Ensure the encoded data actually represents a valid image + decoded = base64.b64decode(logo.removeprefix('data:image/png;base64,')) + Image.open(BytesIO(decoded)).verify() + + def test_logo_image_custom_static(self): + """Test retrieval of a custom logo which lives in the static storage backend.""" + with override_settings(CUSTOM_LOGO='img/inventree.png'): + logo = helpers.getLogoImage() + self.assertEqual(logo, '/static/img/inventree.png') + + logo = helpers.getLogoImage(as_file=True) + self.assertNotIn('file://', logo) + self.assertTrue(logo.startswith('data:image/png;base64,')) + + # Disabling 'custom' must fall back to the default logo, even if set + logo = helpers.getLogoImage(custom=False) + self.assertEqual(logo, '/static/img/inventree.png') + + def test_logo_image_custom_media(self): + """Test retrieval of a custom logo which lives in the media (uploaded) storage backend.""" + custom_logo_path = 'custom/test_logo.png' + + img = Image.new('RGB', (16, 16), color='blue') + buffer = BytesIO() + img.save(buffer, 'PNG') + image_data = buffer.getvalue() + + default_storage.save(custom_logo_path, ContentFile(image_data)) + + try: + with override_settings(CUSTOM_LOGO=custom_logo_path): + logo = helpers.getLogoImage() + self.assertEqual(logo, default_storage.url(custom_logo_path)) + + logo = helpers.getLogoImage(as_file=True) + self.assertNotIn('file://', logo) + self.assertTrue(logo.startswith('data:image/png;base64,')) + + # The decoded data must exactly match the uploaded image + decoded = base64.b64decode(logo.removeprefix('data:image/png;base64,')) + self.assertEqual(decoded, image_data) + finally: + default_storage.delete(custom_logo_path) def test_download_image(self): """Test function for downloading image from remote URL.""" @@ -742,6 +776,41 @@ class TestHelpers(TestCase): large_img, timeout=10, max_size=10 * 1024 * 1024 ) + def test_download_image_dns_rebind_blocked(self): + """A hostname that resolves safely for validation but privately for the real fetch must be blocked. + + Regression test: `validate_url_no_ssrf()` used to resolve the hostname once, + validate that result, and then discard it - the actual `requests.get()` call + resolved the same hostname again independently. An attacker controlling DNS + for their own domain could answer the first ("check") lookup with a public IP + and every subsequent ("use") lookup with a private/internal one (DNS + rebinding), so the real connection went somewhere the validator never saw. + """ + public_addrinfo = [(2, 1, 6, '', ('93.184.216.34', 0))] + private_addrinfo = [(2, 1, 6, '', ('127.0.0.1', 0))] + + calls = {'n': 0} + + def rebinding_getaddrinfo(host, *args, **kwargs): + calls['n'] += 1 + return public_addrinfo if calls['n'] == 1 else private_addrinfo + + with mock.patch.object( + InvenTree.helpers_model, + '_real_getaddrinfo', + side_effect=rebinding_getaddrinfo, + ): + # The pre-check sees the safe public IP and passes; the *actual* + # connection attempt made by requests.get() must be independently + # guarded and must fail once it resolves to the private IP. + with self.assertRaisesRegex(Exception, 'Connection error'): + InvenTree.helpers_model.download_image_from_url( + 'http://rebind.example.com/image.png' + ) + + # Both the validation-time and connection-time lookups must have happened. + self.assertEqual(calls['n'], 2) + def test_model_mixin(self): """Test the getModelsWithMixin function.""" from InvenTree.models import InvenTreeBarcodeMixin @@ -1102,8 +1171,26 @@ class TestVersionNumber(TestCase): class CurrencyTests(TestCase): """Unit tests for currency / exchange rate functionality.""" - def test_rates(self): + RATES = { + 'AUD': 1.5, + 'CAD': 1.35, + 'CNY': 7.2, + 'EUR': 0.9, + 'GBP': 0.8, + 'JPY': 150.0, + 'NZD': 1.65, + 'USD': 1.0, + } + + @requests_mock.Mocker() + def test_rates(self, requests_mocker): """Test exchange rate update.""" + # Patch setting for remote url + response_rates = {code: self.RATES.get(code, 1.0) for code in currency_codes()} + requests_mocker.get( + 'https://api.frankfurter.app/latest', json={'rates': response_rates} + ) + # Initially, there will not be any exchange rate information rates = Rate.objects.all() @@ -1116,24 +1203,10 @@ class CurrencyTests(TestCase): with self.assertRaises(MissingRate): convert_money(Money(100, 'AUD'), 'USD') - update_successful = False + InvenTree.tasks.update_exchange_rates() - # Note: the update sometimes fails in CI, let's give it a few chances - for _ in range(10): - InvenTree.tasks.update_exchange_rates() - - rates = Rate.objects.all() - - if rates.count() == len(currency_codes()): - update_successful = True - break - - else: # pragma: no cover - print('Exchange rate update failed - retrying') - print(f'Expected {currency_codes()}, got {[a.currency for a in rates]}') - time.sleep(1) - - self.assertTrue(update_successful) + rates = Rate.objects.all() + self.assertEqual(rates.count(), len(currency_codes())) # Now that we have some exchange rate information, we can perform conversions @@ -1257,6 +1330,22 @@ class TestSettings(InvenTreeTestCase): str(test_file).lower(), str(config.get_config_file()).lower() ) + # LEGACY - old path + if settings.DOCKER: # pragma: no cover + # In Docker, the legacy path is not used + return + legacy_path = config.get_base_dir().joinpath('config.yaml') + assert not legacy_path.exists(), ( + 'Legacy config file does exist, stopping as a percaution!' + ) + self.assertTrue(test_file.exists(), f'Test file {test_file} does not exist!') + test_file.rename(legacy_path) + self.assertIn( + 'src/backend/inventree/config.yaml', str(config.get_config_file()).lower() + ) + # Clean up again + legacy_path.unlink(missing_ok=True) + def test_helpers_plugin_file(self): """Test get_plugin_file.""" # normal run - not configured @@ -1287,6 +1376,22 @@ class TestSettings(InvenTreeTestCase): with in_env_context({'INVENTREE_SECRET_KEY_FILE': str(test_file)}): self.assertIn(str(test_file), str(config.get_secret_key(return_path=True))) + # LEGACY - old path + if settings.DOCKER: # pragma: no cover + # In Docker, the legacy path is not used + return + legacy_path = config.get_base_dir().joinpath('secret_key.txt') + assert not legacy_path.exists(), ( + 'Legacy secret key file does exist, stopping as a percaution!' + ) + test_file.rename(legacy_path) + self.assertIn( + 'src/backend/inventree/secret_key.txt', + str(config.get_secret_key(return_path=True)).lower(), + ) + # Clean up again + legacy_path.unlink(missing_ok=True) + # Test with content set per environment with in_env_context({'INVENTREE_SECRET_KEY': '123abc123'}): self.assertEqual(config.get_secret_key(), '123abc123') @@ -1312,6 +1417,27 @@ class TestSettings(InvenTreeTestCase): with in_env_context({'INVENTREE_OIDC_PRIVATE_KEY': '123abc123'}): self.assertEqual(config.get_oidc_private_key(), '123abc123') + # LEGACY - old path + if settings.DOCKER: # pragma: no cover + # In Docker, the legacy path is not used + return + legacy_path = config.get_base_dir().joinpath('oidc.pem') + assert not legacy_path.exists(), ( + 'Legacy OIDC private key file does exist, stopping as a precaution!' + ) + test_file.rename(legacy_path) + assert isinstance(trgt_path, Path) + new_path = trgt_path.rename( + trgt_path.parent / '_oidc.pem' + ) # move out current config + self.assertIn( + 'src/backend/inventree/oidc.pem', + str(config.get_oidc_private_key(return_path=True)).lower(), + ) + # Clean up again + legacy_path.unlink(missing_ok=True) + new_path.rename(trgt_path) # restore original path for current config + def test_helpers_setting(self): """Test get_setting.""" TEST_ENV_NAME = '123TEST' @@ -1434,7 +1560,7 @@ class TestOffloadTask(InvenTreeTestCase): offload_task('dummy_task.numbers', 1, 1, 1, force_sync=True) ) - self.assertIn('Malformed function path', str(log.output)) + self.assertIn("No module named \\'dummy_task\\'", str(log.output)) # Offload dummy task with a Part instance # This should succeed, ensuring that the Part instance is correctly pickled @@ -1586,6 +1712,18 @@ class MagicLoginTest(InvenTreeTestCase): # And we should be logged in again self.assertEqual(resp.wsgi_request.user, self.user) + def test_duplicate_email(self): + """Test that duplicate email addresses do not raise a server error.""" + User = get_user_model() + User.objects.create_user( + username='duplicate', email=self.user.email, password='password' + ) + + resp = self.client.post(reverse('sesame-generate'), {'email': self.user.email}) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.data, {'status': 'ok'}) + self.assertEqual(len(mail.outbox), 0) + class MaintenanceModeTest(InvenTreeTestCase): """Unit tests for maintenance mode.""" @@ -1781,3 +1919,54 @@ class SchemaPostprocessingTest(TestCase): self.assertNotIn('customer_detail', schemas_out.get('SalesOrder')['required']) # required key removed when empty self.assertNotIn('required', schemas_out.get('SalesOrderShipment')) + + def test_file_field_request_schema_binary(self): + """Verify only request file fields are exposed as binary.""" + auto_schema = object.__new__(schema.ExtendedAutoSchema) + + mapped_schemas = [ + {'type': 'string', 'format': 'uri', 'nullable': True}, + {'type': 'string', 'format': 'uri'}, + {'type': 'string', 'format': 'uri', 'nullable': True}, + ] + + with mock.patch( + 'drf_spectacular.openapi.AutoSchema._map_serializer_field', + side_effect=mapped_schemas, + ): + file_request = auto_schema._map_serializer_field( + serializers.FileField(allow_null=True), 'request' + ) + url_request = auto_schema._map_serializer_field( + serializers.URLField(), 'request' + ) + file_response = auto_schema._map_serializer_field( + serializers.FileField(allow_null=True), 'response' + ) + + self.assertEqual(file_request['format'], 'binary') + self.assertTrue(file_request['nullable']) + self.assertEqual(url_request['format'], 'uri') + self.assertEqual(file_response['format'], 'uri') + + +class URLCompatibilityTest(InvenTreeTestCase): + """Unit test for legacy URL compatibility.""" + + URL_MAPPINGS = [ + ('/index/', '/web'), + ('/part/1/', '/web/part/1/'), + ('/company/customers/', '/web/sales/index/customers'), + ('/build/3/', '/web/manufacturing/build-order/3'), + ('/stock/item/1/', '/web/stock/item/1/'), + ] + + @override_settings( + SITE_URL='http://testserver', CSRF_TRUSTED_ORIGINS=['http://testserver'] + ) + def test_legacy_urls(self): + """Test legacy URLs.""" + for old_url, new_url in self.URL_MAPPINGS: + response = self.client.get(old_url) + self.assertEqual(response.status_code, 302) + self.assertEqual(response['Location'], new_url) diff --git a/src/backend/InvenTree/InvenTree/tracing.py b/src/backend/InvenTree/InvenTree/tracing.py index f97da6c0eb..77122903e7 100644 --- a/src/backend/InvenTree/InvenTree/tracing.py +++ b/src/backend/InvenTree/InvenTree/tracing.py @@ -50,12 +50,17 @@ def setup_tracing( """ if InvenTree.ready.isImportingData() or InvenTree.ready.isRunningMigrations(): return + if endpoint is None or headers is None: print( 'Tracing endpoint or headers not specified - skipping tracing setup' ) # pragma: no cover return # pragma: no cover + # check if trace is already set up - if so, skip + if trace.get_tracer_provider() is not None: + return + # Logger configuration logger = logging.getLogger('inventree') @@ -163,29 +168,34 @@ def setup_tracing( def setup_instruments(db_engine: str): # pragma: no cover """Run auto-instrumentation for OpenTelemetry tracing.""" - DjangoInstrumentor().instrument() - RedisInstrumentor().instrument() - RequestsInstrumentor().instrument() - SystemMetricsInstrumentor().instrument() + if not DjangoInstrumentor()._is_instrumented_by_opentelemetry: + DjangoInstrumentor().instrument() + RedisInstrumentor().instrument() + RequestsInstrumentor().instrument() + SystemMetricsInstrumentor().instrument() db_engine = str(db_engine).lower().strip() # DBs if 'sqlite' in db_engine: - SQLite3Instrumentor().instrument() + inst = SQLite3Instrumentor() + if not inst._is_instrumented_by_opentelemetry: + inst.instrument() elif 'postgresql' in db_engine: try: from opentelemetry.instrumentation.psycopg import PsycopgInstrumentor - PsycopgInstrumentor().instrument( - enable_commenter=False, commenter_options={} - ) + inst = PsycopgInstrumentor() + if not inst._is_instrumented_by_opentelemetry: + inst.instrument(enable_commenter=False, commenter_options={}) except ModuleNotFoundError: pass elif 'mysql' in db_engine: try: from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor - PyMySQLInstrumentor().instrument() + inst = PyMySQLInstrumentor() + if not inst._is_instrumented_by_opentelemetry: + inst.instrument() except ModuleNotFoundError: pass diff --git a/src/backend/InvenTree/InvenTree/unit_test.py b/src/backend/InvenTree/InvenTree/unit_test.py index bae1262297..572f8930cc 100644 --- a/src/backend/InvenTree/InvenTree/unit_test.py +++ b/src/backend/InvenTree/InvenTree/unit_test.py @@ -380,13 +380,23 @@ class TestQueryMixin: ): """Context manager to check that the number of queries is less than a certain value. + Arguments: + value: The maximum number of queries allowed + using: The database connection to use (default = 'default') + verbose: If True, print the queries to the console (default = False) + url: Optional URL to print in the output (default = None) + log_to_file: If True, log the queries to a file (default = False) + + Yields: + The CaptureQueriesContext object, which contains the captured queries + Example: with self.assertNumQueriesLessThan(10): # Do some stuff Ref: https://stackoverflow.com/questions/1254170/django-is-there-a-way-to-count-sql-queries-from-an-unit-test/59089020#59089020 """ with CaptureQueriesContext(connections[using]) as context: - yield # your test will be run here + yield context # your test will be run here n = len(context.captured_queries) @@ -492,12 +502,16 @@ class InvenTreeAPITestCase( expected_code = kwargs.pop('expected_code', None) msg = kwargs.pop('msg', None) - max_queries = kwargs.pop('max_query_count', self.MAX_QUERY_COUNT) + max_query_count = kwargs.pop('max_query_count', self.MAX_QUERY_COUNT) max_query_time = kwargs.pop('max_query_time', self.MAX_QUERY_TIME) + benchmark = kwargs.pop('benchmark', False) t1 = time.time() - with self.assertNumQueriesLessThan(max_queries, url=url): + with ( + self.assertNumQueriesLessThan(max_query_count, url=url) as context, + self.captureOnCommitCallbacks(execute=True), + ): response = method(url, data, **kwargs) t2 = time.time() @@ -512,6 +526,11 @@ class InvenTreeAPITestCase( self.assertLessEqual(dt, max_query_time) + if benchmark: + print( + f"Benchmark @ '{url}': {len(context.captured_queries)} queries (of {max_query_count}) in {dt:.4f}s (of {max_query_time}s max)" + ) + return response def get(self, url, data=None, expected_code=200, **kwargs): diff --git a/src/backend/InvenTree/InvenTree/validators.py b/src/backend/InvenTree/InvenTree/validators.py index 9682c32575..ae4145a140 100644 --- a/src/backend/InvenTree/InvenTree/validators.py +++ b/src/backend/InvenTree/InvenTree/validators.py @@ -1,5 +1,7 @@ """Custom field validators for InvenTree.""" +import tokenize + from django.conf import settings from django.core import validators from django.core.exceptions import ValidationError @@ -9,6 +11,7 @@ import pint.errors from moneyed import CURRENCIES import InvenTree.conversion +import InvenTree.exceptions from common.settings import get_global_setting @@ -24,7 +27,17 @@ def validate_physical_units(unit): try: ureg(unit) - except (AssertionError, AttributeError, pint.errors.UndefinedUnitError): + except ( + AssertionError, + AttributeError, + pint.errors.UndefinedUnitError, + tokenize.TokenError, + ): + raise ValidationError(_('Invalid physical unit')) + except Exception: + # Pint parses unit expressions via the python tokenizer, so any + # other unexpected exception type may be raised for malformed input + InvenTree.exceptions.log_error('validate_physical_units', scope='validators') raise ValidationError(_('Invalid physical unit')) diff --git a/src/backend/InvenTree/InvenTree/version.py b/src/backend/InvenTree/InvenTree/version.py index b2b211b791..9d41c75422 100644 --- a/src/backend/InvenTree/InvenTree/version.py +++ b/src/backend/InvenTree/InvenTree/version.py @@ -15,10 +15,10 @@ from datetime import timedelta as td from .api_version import INVENTREE_API_TEXT, INVENTREE_API_VERSION # InvenTree software version -INVENTREE_SW_VERSION = '1.4.0 dev' +INVENTREE_SW_VERSION = '1.6.0 dev' # Minimum supported Python version -MIN_PYTHON_VERSION = (3, 11) +MIN_PYTHON_VERSION = (3, 12) logger = logging.getLogger('inventree') @@ -55,6 +55,10 @@ try: except (KeyError, IndexError): logger.warning('INVE-W1: Current branch could not be detected.') main_branch = None + + if main_repo is not None: + main_repo.close() + main_repo = None except ImportError: logger.warning( 'INVE-W2: Dulwich module not found, git information will not be available.' @@ -129,27 +133,14 @@ def isInvenTreeDevelopmentVersion() -> bool: return inventreeVersion().endswith('dev') -def inventreeDocsVersion() -> str: - """Return the version string matching the latest documentation. - - Development -> "latest" - Release -> "major.minor.sub" e.g. "0.5.2" - """ - if isInvenTreeDevelopmentVersion(): - return 'latest' - - return INVENTREE_SW_VERSION - - def inventreeDocUrl() -> str: """Return URL for InvenTree documentation site.""" - tag = inventreeDocsVersion() - return f'https://docs.inventree.org/en/{tag}' + return 'https://docs.inventree.org' def inventreeAppUrl() -> str: """Return URL for InvenTree app site.""" - return 'https://docs.inventree.org/en/stable/app/' + return 'https://docs.inventree.org/en/latest/app/' def inventreeGithubUrl() -> str: diff --git a/src/backend/InvenTree/build/api.py b/src/backend/InvenTree/build/api.py index 8a7771c2db..a50d062720 100644 --- a/src/backend/InvenTree/build/api.py +++ b/src/backend/InvenTree/build/api.py @@ -3,7 +3,8 @@ from __future__ import annotations from django.contrib.auth.models import User -from django.db.models import F, Q +from django.db.models import DecimalField, F, OuterRef, Q, Subquery, Sum +from django.db.models.functions import Coalesce from django.urls import include, path from django.utils.translation import gettext_lazy as _ @@ -16,6 +17,7 @@ from rest_framework.response import Response import build.models as build_models import build.serializers +import common.filters import common.models import common.serializers import part.models as part_models @@ -25,7 +27,7 @@ from build.models import Build, BuildItem, BuildLine from build.status_codes import BuildStatus, BuildStatusGroups from data_exporter.mixins import DataExportViewMixin from generic.states.api import StatusView -from InvenTree.api import BulkDeleteMixin, ParameterListMixin +from InvenTree.api import BulkDeleteMixin, ParameterListMixin, meta_path from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.filters import ( SEARCH_ORDER_FILTER, @@ -307,6 +309,8 @@ class BuildFilter(FilterSet): return queryset + tags = common.filters.TagsFilter() + class BuildMixin: """Mixin class for Build API endpoints.""" @@ -391,9 +395,7 @@ class BuildList( serializer = self.get_serializer(data=self.clean_data(request.data)) serializer.is_valid(raise_exception=True) - build = serializer.save() - build.issued_by = request.user - build.save() + serializer.save(issued_by=request.user) headers = self.get_success_headers(serializer.data) return Response( @@ -455,8 +457,21 @@ class BuildLineFilter(FilterSet): # Fields on related models consumable = rest_filters.BooleanFilter( - label=_('Consumable'), field_name='bom_item__consumable' + label=_('Consumable'), method='filter_consumable' ) + + def filter_consumable(self, queryset, name, value): + """Filter the queryset based on the "effective" consumable status of the BOM item. + + A BuildLine is considered "consumable" if either the BOM item itself, + or the underlying part, is marked as consumable. + """ + return queryset.filter( + part_models.BomItem.consumable_filter( + consumable=str2bool(value), prefix='bom_item__' + ) + ) + optional = rest_filters.BooleanFilter( label=_('Optional'), field_name='bom_item__optional' ) @@ -492,9 +507,25 @@ class BuildLineFilter(FilterSet): def filter_allocated(self, queryset, name, value): """Filter by whether each BuildLine is fully allocated.""" + allocated_subquery = ( + BuildItem.objects + .filter(build_line=OuterRef('pk')) + .values('build_line') + .annotate(total=Sum('quantity')) + .values('total') + ) + + queryset = queryset.alias( + allocated_quantity=Coalesce( + Subquery(allocated_subquery), 0, output_field=DecimalField() + ) + ) + if str2bool(value): - return queryset.filter(allocated__gte=F('quantity') - F('consumed')) - return queryset.filter(allocated__lt=F('quantity') - F('consumed')) + return queryset.filter( + allocated_quantity__gte=F('quantity') - F('consumed') + ) + return queryset.filter(allocated_quantity__lt=F('quantity') - F('consumed')) consumed = rest_filters.BooleanFilter(label=_('Consumed'), method='filter_consumed') @@ -517,8 +548,24 @@ class BuildLineFilter(FilterSet): - The quantity available for each BuildLine (including variants and substitutes) - The quantity allocated for each BuildLine """ - flt = Q( - quantity__lte=F('allocated') + allocated_subquery = ( + BuildItem.objects + .filter(build_line=OuterRef('pk')) + .values('build_line') + .annotate(total=Sum('quantity')) + .values('total') + ) + + queryset = queryset.alias( + allocated_quantity=Coalesce( + Subquery(allocated_subquery), 0, output_field=DecimalField() + ) + ) + + # A query filter construct to determine the total quantity available for this BuildLine, + # taking into account any stock which is already allocated or consumed + available = ( + F('allocated_quantity') + F('consumed') + F('available_stock') + F('available_substitute_stock') @@ -526,8 +573,9 @@ class BuildLineFilter(FilterSet): ) if str2bool(value): - return queryset.filter(flt) - return queryset.exclude(flt) + return queryset.filter(quantity__lte=available) + + return queryset.filter(quantity__gt=available) on_order = rest_filters.BooleanFilter(label=_('On Order'), method='filter_on_order') @@ -886,6 +934,8 @@ class BuildAutoAllocate(BuildOrderContextMixin, CreateAPI): serializer.is_valid(raise_exception=True) data = serializer.validated_data + build_lines = data.get('build_lines', []) + # Offload the task to the background worker task_id = offload_task( auto_allocate_build, @@ -896,6 +946,8 @@ class BuildAutoAllocate(BuildOrderContextMixin, CreateAPI): substitutes=data['substitutes'], optional_items=data['optional_items'], item_type=data.get('item_type', 'untracked'), + stock_sort_by=data['stock_sort_by'], + line_ids=[line.pk for line in build_lines] if build_lines else None, group='build', ) @@ -1165,7 +1217,13 @@ build_api_urls = [ path( 'item/', include([ - path('/', BuildItemDetail.as_view(), name='api-build-item-detail'), + path( + '/', + include([ + meta_path(BuildItem), + path('', BuildItemDetail.as_view(), name='api-build-item-detail'), + ]), + ), path('', BuildItemList.as_view(), name='api-build-item-list'), ]), ), @@ -1205,6 +1263,7 @@ build_api_urls = [ path('finish/', BuildFinish.as_view(), name='api-build-finish'), path('cancel/', BuildCancel.as_view(), name='api-build-cancel'), path('unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'), + meta_path(Build), path('', BuildDetail.as_view(), name='api-build-detail'), ]), ), diff --git a/src/backend/InvenTree/build/migrations/0059_build_tags.py b/src/backend/InvenTree/build/migrations/0059_build_tags.py new file mode 100644 index 0000000000..329722a5dd --- /dev/null +++ b/src/backend/InvenTree/build/migrations/0059_build_tags.py @@ -0,0 +1,29 @@ +# Generated by Django 5.2.14 on 2026-06-03 10:07 + +import taggit.managers +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("build", "0058_buildline_consumed"), + ( + "taggit", + "0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx", + ), + ] + + operations = [ + migrations.AddField( + model_name="build", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/src/backend/InvenTree/build/models.py b/src/backend/InvenTree/build/models.py index c3691c5677..ede56d0f61 100644 --- a/src/backend/InvenTree/build/models.py +++ b/src/backend/InvenTree/build/models.py @@ -1,5 +1,6 @@ """Build database model definitions.""" +import copy import decimal from typing import Optional, TypedDict @@ -8,6 +9,7 @@ from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator from django.db import models, transaction from django.db.models import F, Q, QuerySet, Sum +from django.db.models.base import ModelState from django.db.models.functions import Coalesce from django.db.models.signals import post_save from django.dispatch.dispatcher import receiver @@ -37,13 +39,19 @@ from build.validators import ( validate_build_order_reference, ) from common.models import ProjectCode -from common.settings import ( - get_global_setting, - prevent_build_output_complete_on_incompleted_tests, -) +from common.settings import get_global_setting from generic.enums import StringEnum -from generic.states import StateTransitionMixin, StatusCodeMixin -from plugin.events import trigger_event +from generic.states import ( + Deprecations, + StateTransitionMixin, + StatusCodeMixin, + can_proceed, + deprecated, + inventree_transition, +) +from InvenTree.helpers_db import bulk_create_and_fetch +from plugin.events import bulk_trigger_event, trigger_event +from stock.events import StockEvents from stock.status_codes import StockHistoryCode, StockStatus logger = structlog.get_logger('inventree') @@ -79,6 +87,7 @@ class Build( InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeBarcodeMixin, + InvenTree.models.InvenTreeTagsMixin, InvenTree.models.InvenTreeNotesMixin, InvenTree.models.ReferenceIndexingMixin, StateTransitionMixin, @@ -650,43 +659,328 @@ class Build( return self.is_fully_allocated(tracked=False) - def complete_allocations(self, user) -> None: + @transaction.atomic + def complete_allocations( + self, + build_items: QuerySet, + quantities: Optional[dict] = None, + notes: Optional[str] = None, + user: Optional[User] = None, + ): + """Complete the allocation of stock for the given build lines. + + Arguments: + build_items: QuerySet of build items to complete allocations for + quantities: Optional dict of quantities to allocate + notes: Optional notes for the allocation + user: The user completing the allocation + + Notes: + This unrolls what would otherwise be a per-BuildItem call, so that the underlying StockItem, + StockItemTracking, BuildLine and BuildItem writes can be batched into + a handful of bulk queries instead of several per build item. + """ + import part.tasks + + notes = notes or '' + quantities = quantities or {} + + # Lock this build's database row: all allocate / consume / complete + # operations for a given build are serialized against each other, + # so the in-memory BuildItem and BuildLine arithmetic below cannot + # race against a concurrent operation on the same build + Build.objects.select_for_update().get(pk=self.pk) + + # Preselect related fields to avoid per-row database queries below + build_items = list( + build_items.select_related( + 'build_line', 'stock_item', 'stock_item__part', 'install_into' + ) + ) + + # Lock the distinct StockItem rows (in pk order, to avoid deadlocks) and + # re-read their quantities, so the clamping arithmetic below operates on + # the current committed values. Stock adjustments elsewhere lock these + # same rows, so concurrent adjustments cannot be silently overwritten. + locked_quantities = dict( + stock.models.StockItem.objects + .select_for_update() + .filter(pk__in={item.stock_item_id for item in build_items}) + .order_by('pk') + .values_list('pk', 'quantity') + ) + + split_items = [] # (source_item, new_item, quantity) - stock to split off + install_items = [] # (build_item, target_item, output, quantity) - stock to install + consume_items = [] # (target_item, quantity) - stock to mark as consumed + + # Canonical (mutable) copy of each distinct StockItem being drawn from - multiple + # build items may allocate against the same StockItem, so track running state + seen_stock_items: dict = {} + + # Track the build items and build lines which have already been processed, to avoid double counting + seen_build_items: dict = {} + seen_build_lines: dict = {} + + # Keep track of build items which need to be removed from the database after processing + # This is because the required quantity may be less than the allocated quantity, and we need to split the allocation + build_items_to_remove = set() + + for build_item in build_items: + build_line = build_item.build_line + + stock_item = ( + seen_stock_items.get(build_item.stock_item_id) or build_item.stock_item + ) + + if (locked_qty := locked_quantities.pop(stock_item.pk, None)) is not None: + # First encounter: refresh the quantity from the locked database row + stock_item.quantity = locked_qty + elif stock_item.pk not in seen_stock_items: + # The stock item no longer exists in the database - skip + continue + + quantity = quantities.get(build_item.pk, build_item.quantity) + + if not isinstance(quantity, decimal.Decimal): + # Avoid float -> Decimal precision artifacts (e.g. Decimal(0.1)) + quantity = decimal.Decimal(str(quantity)) + + # Clamp to the maximum quantity available for this build item and stock item + quantity = max( + decimal.Decimal(0), + min(quantity, build_item.quantity, stock_item.quantity), + ) + + if quantity <= 0: + continue + + # Register this StockItem as "seen" now that we know it will be touched + seen_stock_items[stock_item.pk] = stock_item + + trackable_install = stock_item.part.trackable and build_item.install_into_id + output = build_item.install_into if trackable_install else None + + if quantity < stock_item.quantity: + # Split off exactly the consumed quantity into a new StockItem, + # leaving the remainder in place as available stock + new_item = copy.copy(stock_item) + new_item._state = ModelState() + new_item.pk = None + new_item.quantity = quantity + new_item.parent = stock_item + + stock_item.quantity -= quantity + + target_item = new_item + split_items.append((stock_item, new_item, quantity)) + else: + target_item = stock_item + + # Resolve the final resting state of the target item now - it may not have a + # primary key yet (if newly split), so this cannot depend on any pk lookups + target_item.consumed_by = self + target_item.location = None + + if trackable_install: + target_item.belongs_to = output + install_items.append((build_item, target_item, output, quantity)) + else: + consume_items.append((target_item, quantity)) + + # Increase the "consumed" quantity for the build line + _line = seen_build_lines.get(build_line.pk) or build_line + _line.consumed += quantity + seen_build_lines[build_line.pk] = _line + + # Decrease the "quantity" for the build item + _item = seen_build_items.get(build_item.pk) or build_item + _item.quantity = max(decimal.Decimal(0), _item.quantity - quantity) + seen_build_items[build_item.pk] = _item + + # If the total item quantity is now zero, we can remove the build item from the database + if _item.quantity <= 0: + build_items_to_remove.add(_item.pk) + + # Nothing to do? + if not seen_build_items: + return + + # Bulk-create the newly split-off stock items - this resolves their primary keys, + # which the tracking entries and (for installed items) BuildItem records need below + new_stock_item_data = [new_item for _, new_item, _ in split_items] + + new_stock_items = bulk_create_and_fetch( + stock.models.StockItem, new_stock_item_data + ) + + # Back-populate the resolved primary keys onto the original 'new_item' objects + # (in-place, not via replacement) since 'install_items' / 'consume_items' hold + # references to these same objects (as 'target_item') and must see the + # resolved pk too. On backends that can't return pks from bulk_create (MySQL), + # 'new_stock_items' are freshly-fetched, distinct objects, so a plain list + # replacement here would leave those other references with pk=None. + for i, (_stock_item, new_item, _quantity) in enumerate(split_items): + new_item.pk = new_stock_items[i].pk + + tracking_entries = [] + split_events = [] + install_events = [] + + # Split stock items for "split_items" + for source_item, new_item, quantity in split_items: + tracking_entries.append( + stock.models.StockItemTracking( + item_id=new_item.pk, + part_id=new_item.part_id, + tracking_type=StockHistoryCode.SPLIT_FROM_PARENT.value, + user=user, + notes=notes, + deltas={'stockitem': source_item.pk, 'quantity': float(quantity)}, + ) + ) + tracking_entries.append( + stock.models.StockItemTracking( + item_id=source_item.pk, + part_id=source_item.part_id, + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value, + user=user, + notes=notes, + deltas={ + 'removed': float(quantity), + 'quantity': float(source_item.quantity), + }, + ) + ) + + split_events.append(((), {'id': new_item.pk, 'parent': source_item.pk})) + + # Install stock items for "install_items" + for build_item, target_item, output, quantity in install_items: + tracking_entries.append( + stock.models.StockItemTracking( + item_id=target_item.pk, + part_id=target_item.part_id, + tracking_type=StockHistoryCode.INSTALLED_INTO_ASSEMBLY.value, + user=user, + notes=notes, + deltas={ + 'stockitem': output.pk, + 'quantity': float(quantity), + 'buildorder': self.pk, + }, + ) + ) + tracking_entries.append( + stock.models.StockItemTracking( + item_id=output.pk, + part_id=output.part_id, + tracking_type=StockHistoryCode.INSTALLED_CHILD_ITEM.value, + user=user, + notes=notes, + deltas={'stockitem': target_item.pk, 'quantity': float(quantity)}, + ) + ) + + install_events.append(( + (), + {'id': target_item.pk, 'assembly_id': output.pk}, + )) + + # Ensure the build item points to the (possibly newly split) stock item + build_item.stock_item = target_item + + # Consume stock items for "consume_items" + for target_item, quantity in consume_items: + tracking_entries.append( + stock.models.StockItemTracking( + item_id=target_item.pk, + part_id=target_item.part_id, + tracking_type=StockHistoryCode.BUILD_CONSUMED.value, + user=user, + notes=notes, + deltas={'buildorder': self.pk, 'quantity': float(quantity)}, + ) + ) + + # Flush all StockItem field changes (quantity reductions, consumption, installs) + stock.models.StockItem.objects.bulk_update( + seen_stock_items.values(), + ['quantity', 'consumed_by', 'location', 'belongs_to'], + ) + + stock.models.StockItemTracking.objects.bulk_create(tracking_entries) + + # Update build lines for "seen_build_lines" + BuildLine.objects.bulk_update(seen_build_lines.values(), ['consumed']) + + # Update build items for "seen_build_items" (excluding those being removed) + build_items_to_update = [ + item + for pk, item in seen_build_items.items() + if pk not in build_items_to_remove + ] + BuildItem.objects.bulk_update(build_items_to_update, ['quantity', 'stock_item']) + + # Remove build items in "build_items_to_remove" + BuildItem.objects.filter(pk__in=build_items_to_remove).delete() + + # Queue the ITEM_SPLIT / ITEM_INSTALLED_INTO_ASSEMBLY plugin events in bulk, + # rather than one offload_task() call (and one OrmQ insert) per item + bulk_trigger_event(StockEvents.ITEM_SPLIT, split_events) + bulk_trigger_event(StockEvents.ITEM_INSTALLED_INTO_ASSEMBLY, install_events) + + # bulk_update()/bulk_create() above do not fire StockItem's post_save signal, + # which normally triggers a low-stock check for the affected part - so queue + # that check explicitly, once per distinct part touched by this call + touched_part_ids = {item.part_id for item in seen_stock_items.values()} + + InvenTree.tasks.bulk_offload_task( + part.tasks.notify_low_stock_if_required, + [((part_id,), {}) for part_id in touched_part_ids], + group='notification', + force_async=True, + ) + + @transaction.atomic + def complete_outstanding_allocations(self, user) -> None: """Complete all stock allocations for this build order. - - This function is called when a build order is completed + - This function is called when a build order is completed. + - Any outstanding allocations will be consumed + + Arguments: + user: The user who is completing the build """ - # Remove untracked allocated stock - self.subtract_allocated_stock(user) + # Find all BuildItem objects which point to this build + items = self.allocated_stock.filter( + build_line__bom_item__sub_part__trackable=False + ) + + self.complete_allocations(build_items=items, user=user) + + # Delete any remaining allocations + items.all().delete() # Ensure that there are no longer any BuildItem objects # which point to this Build Order self.allocated_stock.all().delete() - @transaction.atomic + # region fsm + @inventree_transition( + field=status, + source=[BuildStatus.PENDING, BuildStatus.PRODUCTION, BuildStatus.ON_HOLD], + target=BuildStatus.COMPLETE, + ) def complete_build(self, user: User, trim_allocated_stock: bool = False): - """Mark this build as complete. + """Transition this Build to COMPLETE status. Arguments: user: The user who is completing the build trim_allocated_stock: If True, trim any allocated stock """ - return self.handle_transition( - self.status, - BuildStatus.COMPLETE.value, - self, - self._action_complete, - user=user, - trim_allocated_stock=trim_allocated_stock, - ) - - def _action_complete(self, *args, **kwargs): - """Action to be taken when a build is completed.""" import build.tasks - trim_allocated_stock = kwargs.pop('trim_allocated_stock', False) - user = kwargs.pop('user', None) - - # Prevent completion if there are open child builds if ( get_global_setting('BUILDORDER_REQUIRE_CLOSED_CHILDS') and self.has_open_child_builds @@ -709,85 +1003,61 @@ class Build( group='build', ) - self.completion_date = InvenTree.helpers.current_date() - self.completed_by = user - self.status = BuildStatus.COMPLETE.value - self.save() - - @transaction.atomic + @inventree_transition( + field=status, + source=[BuildStatus.PENDING, BuildStatus.ON_HOLD], + target=BuildStatus.PRODUCTION, + event=BuildEvents.ISSUED, + ) def issue_build(self): - """Mark the Build as IN PRODUCTION. + """Transition this Build to PRODUCTION status. - Args: - user: The user who is issuing the build + The build must currently be PENDING or ON_HOLD. """ - return self.handle_transition( - self.status, BuildStatus.PENDING.value, self, self._action_issue + from build.tasks import check_build_stock + + # Run checks on required parts + InvenTree.tasks.offload_task( + check_build_stock, self, group='build', force_async=True ) @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_issue(self) -> bool: """Returns True if this BuildOrder can be issued.""" - return self.status in [BuildStatus.PENDING.value, BuildStatus.ON_HOLD.value] + return can_proceed(self.issue_build) - def _action_issue(self, *args, **kwargs): - """Perform the action to mark this order as PRODUCTION.""" - if self.can_issue: - self.status = BuildStatus.PRODUCTION.value - self.save() - - trigger_event(BuildEvents.ISSUED, id=self.pk) - - from build.tasks import check_build_stock - - # Run checks on required parts - InvenTree.tasks.offload_task( - check_build_stock, self, group='build', force_async=True - ) - - @transaction.atomic + @inventree_transition( + field=status, + source=[BuildStatus.PENDING, BuildStatus.PRODUCTION], + target=BuildStatus.ON_HOLD, + event=BuildEvents.HOLD, + ) def hold_build(self): - """Mark the Build as ON HOLD.""" - return self.handle_transition( - self.status, BuildStatus.ON_HOLD.value, self, self._action_hold - ) + """Transition this Build to ON_HOLD status. + + The build must currently be PENDING or PRODUCTION. + """ @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_hold(self) -> bool: """Returns True if this BuildOrder can be placed on hold.""" - return self.status in [BuildStatus.PENDING.value, BuildStatus.PRODUCTION.value] + return can_proceed(self.hold_build) - def _action_hold(self, *args, **kwargs): - """Action to be taken when a build is placed on hold.""" - if self.can_hold: - self.status = BuildStatus.ON_HOLD.value - self.save() + @inventree_transition( + field=status, + source=[BuildStatus.PENDING, BuildStatus.PRODUCTION, BuildStatus.ON_HOLD], + target=BuildStatus.CANCELLED, + ) + def cancel_build(self, user=None, **kwargs): + """Transition this Build to CANCELLED status. - trigger_event(BuildEvents.HOLD, id=self.pk) - - @transaction.atomic - def cancel_build(self, user, **kwargs): - """Mark the Build as CANCELLED. - - - Delete any pending BuildItem objects (but do not remove items from stock) - - Set build status to CANCELLED - - Save the Build object + Offloads expensive cleanup operations (de-allocating stock, removing + incomplete outputs) to a background task. """ - return self.handle_transition( - self.status, - BuildStatus.CANCELLED.value, - self, - self._action_cancel, - user=user, - **kwargs, - ) - - def _action_cancel(self, *args, **kwargs): - """Action to be taken when a build is cancelled.""" import build.tasks - user = kwargs.pop('user', None) - remove_allocated_stock = kwargs.get('remove_allocated_stock', False) remove_incomplete_outputs = kwargs.get('remove_incomplete_outputs', False) @@ -805,8 +1075,7 @@ class Build( self.completion_date = InvenTree.helpers.current_date() self.completed_by = user - self.status = BuildStatus.CANCELLED.value - self.save() + # endregion fsm @transaction.atomic def deallocate_stock(self, build_line=None, output=None): @@ -964,7 +1233,7 @@ class Build( # Remove the build output from the database # This is a special case where serialized stock can be deleted, - # independedent of the global setting which normally prevents deletion of serialized stock items + # independent of the global setting which normally prevents deletion of serialized stock items output.delete(ignore_serial_check=True) @transaction.atomic @@ -976,7 +1245,9 @@ class Build( items_to_delete = [] lines = self.untracked_line_items.all() - lines = lines.exclude(bom_item__consumable=True) + lines = lines.exclude( + part.models.BomItem.consumable_filter(prefix='bom_item__') + ) lines = lines.annotate(allocated=annotate_allocated_quantity()) for build_line in lines: @@ -986,7 +1257,17 @@ class Build( continue # Find BuildItem objects to trim - for item in BuildItem.objects.filter(build_line=build_line): + # Lock these rows (in pk order, to avoid deadlocks against other + # allocation operations) so a concurrent allocation update cannot + # be silently overwritten by the quantity decrement below + items = ( + BuildItem.objects + .select_for_update() + .filter(build_line=build_line) + .order_by('pk') + ) + + for item in items: # Previous item completed the job if reduce_by <= 0: break @@ -1013,20 +1294,6 @@ class Build( """Returns a QuerySet object of all BuildItem objects which point back to this Build.""" return BuildItem.objects.filter(build_line__build=self) - def subtract_allocated_stock(self, user) -> None: - """Removes the allocated untracked items from stock.""" - # Find all BuildItem objects which point to this build - items = self.allocated_stock.filter( - build_line__bom_item__sub_part__trackable=False - ) - - # Remove stock - for item in items: - item.complete_allocation(user=user) - - # Delete allocation - items.all().delete() - @transaction.atomic def scrap_build_output( self, output: stock.models.StockItem, quantity, location, **kwargs @@ -1041,6 +1308,15 @@ class Build( if not output: raise ValidationError(_('No build output specified')) + # Re-check the state of the output itself: + # It may have changed since the scrap request was validated + # (e.g. a duplicated background task, or a concurrent request) + if not output.is_building: + raise ValidationError(_('Build output has already been completed')) + + if output.build != self: + raise ValidationError(_('Build output does not match Build Order')) + # If quantity is not specified, assume the entire output quantity if quantity is None: quantity = output.quantity @@ -1073,12 +1349,11 @@ class Build( allocated_items = output.items_to_install.all() # Complete or discard allocations - for build_item in allocated_items: - if not discard_allocations: - build_item.complete_allocation(user=user) + if not discard_allocations: + self.complete_allocations(build_items=allocated_items, user=user) # Delete allocations - allocated_items.delete() + allocated_items.all().delete() output.add_tracking_entry( StockHistoryCode.BUILD_OUTPUT_REJECTED, @@ -1092,6 +1367,70 @@ class Build( }, ) + def can_complete_output( + self, + output: stock.models.StockItem, + quantity: Optional[decimal.Decimal] = None, + required_tests=None, + ) -> bool: + """Determine if the given build output can be completed. + + Arguments: + output: The StockItem instance (build output) to check + quantity: The quantity to complete (defaults to entire output quantity) + required_tests: Optional list of required tests to check against (defaults to the part's required tests) + + Returns: + True if the build output can be completed, False otherwise + + Raises: + ValidationError: If the build output cannot be completed, with an appropriate message + """ + # Re-check the state of the output itself: + # It may have changed since the completion request was validated + # (e.g. a duplicated background task, or a concurrent request) + if not output.is_building: + raise ValidationError(_('Build output has already been completed')) + + if output.build != self: + raise ValidationError(_('Build output does not match Build Order')) + + prevent_incomplete = get_global_setting( + 'PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS' + ) + + if prevent_incomplete and not output.passedAllRequiredTests( + required_tests=required_tests + ): + raise ValidationError(_('Build output has not passed all required tests')) + + # Ensure that none of the allocated items are themselves still "in production" + allocated_items = output.items_to_install.all().filter( + stock_item__is_building=True + ) + + if allocated_items.exists(): + raise ValidationError(_('Allocated stock items are still in production')) + + if quantity is not None and quantity != output.quantity: + # Cannot split a build output with allocated items + if output.items_to_install.exists(): + raise ValidationError({ + 'quantity': _( + 'Cannot partially complete a build output with allocated items' + ) + }) + + if quantity <= 0: + raise ValidationError({ + 'quantity': _('Quantity must be greater than zero') + }) + + if quantity > output.quantity: + raise ValidationError({ + 'quantity': _('Quantity cannot be greater than the output quantity') + }) + @transaction.atomic def complete_build_output( self, @@ -1117,55 +1456,21 @@ class Build( notes = kwargs.get('notes', '') required_tests = kwargs.get('required_tests', output.part.getRequiredTests()) - prevent_on_incomplete = kwargs.get( - 'prevent_on_incomplete', - prevent_build_output_complete_on_incompleted_tests(), + + self.can_complete_output( + output, quantity=quantity, required_tests=required_tests ) - if prevent_on_incomplete and not output.passedAllRequiredTests( - required_tests=required_tests - ): - msg = _('Build output has not passed all required tests') - - if serial := output.serial: - msg = _(f'Build output {serial} has not passed all required tests') - - raise ValidationError(msg) - - # List the allocated BuildItem objects for the given output - allocated_items = output.items_to_install.all() - - # Ensure that none of the allocated items are themselves still "in production" - for build_item in allocated_items: - if build_item.stock_item.is_building: - raise ValidationError( - _('Allocated stock items are still in production') - ) - # If a partial quantity is provided, split the stock output if quantity is not None and quantity != output.quantity: - # Cannot split a build output with allocated items - if allocated_items.count() > 0: - raise ValidationError( - _('Cannot partially complete a build output with allocated items') - ) - - if quantity <= 0: - raise ValidationError({ - 'quantity': _('Quantity must be greater than zero') - }) - - if quantity > output.quantity: - raise ValidationError({ - 'quantity': _('Quantity cannot be greater than the output quantity') - }) - # Split the stock item output = output.splitStock(quantity, user=user, allow_production=True) - for build_item in allocated_items: - # Complete the allocation of stock for that item - build_item.complete_allocation(user=user) + allocated_items = output.items_to_install.all().select_related( + 'stock_item', 'stock_item__part' + ) + + self.complete_allocations(build_items=allocated_items, user=user) # Delete the BuildItem objects from the database allocated_items.all().delete() @@ -1196,9 +1501,128 @@ class Build( trigger_event(BuildEvents.OUTPUT_COMPLETED, id=output.pk, build_id=self.pk) # Increase the completed quantity for this build - self.completed += output.quantity + # Increment at the database level to prevent lost updates + # (multiple outputs may be completed concurrently) + self.completed = F('completed') + output.quantity + self.save(update_fields=['completed']) + self.refresh_from_db(fields=['completed']) - self.save() + @transaction.atomic + def allocate_stock(self, items: list[dict]): + """Allocated provided stock items against this Build. + + Arguments: + items: A list of dictionaries containing the following keys: + - build_line: The BuildLine instance to allocate against + - stock_item: The StockItem instance to allocate + - quantity: The quantity to allocate + - output: Optional StockItem (build output) to install into + + This function will create new BuildItem objects, or update existing ones + """ + to_create = {} + to_update = {} + + # Lock this build's database row: allocation requests are serialized + # against each other (and against consume / complete operations), + # so concurrent requests cannot both read the same starting quantity + Build.objects.select_for_update().get(pk=self.pk) + + # Bulk-fetch any BuildItems which already exist for these (build_line, stock_item) + # pairs, keyed by (build_line_id, stock_item_id, install_into_id). Looking these up + # from a dict below avoids the one-query-per-item cost of a per-entry .filter().first() + # call, which otherwise dominates the query count for a large allocation request. + existing_items = { + ( + existing.build_line_id, + existing.stock_item_id, + existing.install_into_id, + ): existing + for existing in BuildItem.objects.filter( + build_line__in={item['build_line'] for item in items}, + stock_item__in={item['stock_item'] for item in items}, + ) + } + + # Net additional quantity being requested against each StockItem by this call + # (regardless of whether it lands in a new or an existing BuildItem row) + requested = {} + stock_items = {} + + for item in items: + build_line = item['build_line'] + stock_item = item['stock_item'] + quantity = item['quantity'] + output = item.get('output', None) + + # Ignore allocation for consumable BOM items + if build_line.bom_item.is_consumable: + continue + + filters = { + 'build_line': build_line, + 'stock_item': stock_item, + 'install_into': output, + } + + key = (build_line.pk, stock_item.pk, output.pk if output else None) + + # If a BuildItem already exists for this allocation, update it + if build_item := existing_items.get(key): + build_item.quantity += quantity + to_update[build_item.pk] = build_item + elif build_item := to_create.get(key): + # Duplicate entry within this request - merge the quantities + build_item.quantity += quantity + else: + # This is a new BuildItem + to_create[key] = BuildItem(quantity=quantity, **filters) + + stock_items[stock_item.pk] = stock_item + requested[stock_item.pk] = requested.get(stock_item.pk, 0) + quantity + + # Lock each referenced StockItem (in a consistent order, to avoid deadlocks + # against other allocation requests touching an overlapping set of items), + # and re-validate that the requested allocation still fits within the + # (now-locked, now-current) unallocated quantity of each item. + # + # Both the locking and the allocated-quantity lookup are done in bulk (rather + # than one query per StockItem) - critical for keeping the query count bounded + # when a single request references a large number of stock items. + pks = sorted(requested.keys()) + + locked_quantities = dict( + stock.models.StockItem.objects + .select_for_update() + .filter(pk__in=pks) + .order_by('pk') + .values_list('pk', 'quantity') + ) + + if len(locked_quantities) != len(pks): + raise ValidationError({'stock_item': _('Stock item no longer exists')}) + + allocated_quantities = stock.models.StockItem.bulk_allocation_count( + stock_items.values() + ) + + for pk in pks: + stock_item = stock_items[pk] + stock_item.quantity = locked_quantities[pk] + + available = max( + stock_item.quantity - allocated_quantities.get(pk, decimal.Decimal(0)), + decimal.Decimal(0), + ) + + if requested[pk] > available: + q = InvenTree.helpers.clean_decimal(available) + raise ValidationError({ + 'quantity': _(f'Available quantity ({q}) exceeded') + }) + + BuildItem.objects.bulk_create(to_create.values(), batch_size=250) + BuildItem.objects.bulk_update(to_update.values(), ['quantity'], batch_size=250) @transaction.atomic def auto_allocate_stock( @@ -1233,13 +1657,16 @@ class Build( return allocations tracked_line_items = self.tracked_line_items.filter( - bom_item__consumable=False, bom_item__sub_part__virtual=False + part.models.BomItem.consumable_filter( + consumable=False, prefix='bom_item__' + ), + bom_item__sub_part__virtual=False, ) for line_item in tracked_line_items: bom_item = line_item.bom_item - if bom_item.consumable: + if bom_item.is_consumable: # Do not auto-allocate stock to consumable BOM items continue @@ -1342,6 +1769,8 @@ class Build( interchangeable = kwargs.get('interchangeable', False) substitutes = kwargs.get('substitutes', True) optional_items = kwargs.get('optional_items', False) + stock_sort_by = kwargs.get('stock_sort_by', stock.models.STOCK_SORT_DEFAULT) + line_ids = kwargs.get('line_ids') def stock_sort(item, bom_item, variant_parts): if item.part == bom_item.sub_part: @@ -1350,14 +1779,35 @@ class Build( return 2 return 3 - new_items = [] - # Select only "untracked" line items - for line_item in self.untracked_line_items.all(): + untracked_lines = self.untracked_line_items.all() + + if line_ids: + untracked_lines = untracked_lines.filter(pk__in=line_ids) + + untracked_lines = untracked_lines.select_related( + 'bom_item', 'bom_item__sub_part' + ).prefetch_related('bom_item__substitutes__part') + + # Pre-compute the outstanding (unallocated) quantity for every line in a single + # query, instead of one aggregate query per line via BuildLine.unallocated_quantity() + untracked_lines = untracked_lines.annotate( + allocated=annotate_allocated_quantity(), + required=annotate_required_quantity(), + ) + + # First pass: resolve the candidate stock items for each line. We defer the actual + # allocation quantity math until every candidate stock item's outstanding allocated + # quantity can be resolved in a single bulk query (see below), rather than querying + # it (x3) per stock item as each line is processed. + line_data = [] + candidate_stock = {} + + for line_item in untracked_lines: # Find the referenced BomItem bom_item = line_item.bom_item - if bom_item.consumable: + if bom_item.is_consumable: # Do not auto-allocate stock to consumable BOM items continue @@ -1365,23 +1815,32 @@ class Build( # User has specified that optional_items are to be ignored continue - variant_parts = bom_item.sub_part.get_descendants(include_self=False) - - unallocated_quantity = line_item.unallocated_quantity() + unallocated_quantity = max(line_item.required - line_item.allocated, 0) if unallocated_quantity <= 0: # This BomItem is fully allocated, we can continue continue + variant_parts = ( + list(bom_item.sub_part.get_descendants(include_self=False)) + if bom_item.allow_variants + else [] + ) + # Check which parts we can "use" (may include variants and substitutes) available_parts = bom_item.get_valid_parts_for_allocation( - allow_variants=True, allow_inactive=False, allow_substitutes=substitutes + allow_variants=True, + allow_inactive=False, + allow_substitutes=substitutes, + variant_parts=variant_parts, ) # Look for available stock items - available_stock = stock.models.StockItem.objects.filter( - stock.models.StockItem.IN_STOCK_FILTER - ) + # select_related('part') avoids a per-item query in the stock_sort() key + # function below, which inspects item.part for every candidate. + available_stock = stock.models.StockItem.objects.select_related( + 'part' + ).filter(stock.models.StockItem.IN_STOCK_FILTER) # Filter by list of available parts available_stock = available_stock.filter(part__in=list(available_parts)) @@ -1410,55 +1869,78 @@ class Build( location__in=list(sublocations) ) + # Apply secondary ORM ordering before the Python match-quality stable-sort. + if stock_sort_by == stock.models.StockSortOrder.EXPIRY_SOONEST: + available_stock = available_stock.order_by( + F('expiry_date').asc(nulls_last=True) + ) + else: + available_stock = available_stock.order_by(stock_sort_by) + """ Next, we sort the available stock items with the following priority: 1. Direct part matches (+1) 2. Variant part matches (+2) 3. Substitute part matches (+3) - This ensures that allocation priority is first given to "direct" parts + This ensures that allocation priority is first given to "direct" parts. + Python's stable sort preserves the secondary ORM ordering within each group. """ available_stock = sorted( available_stock, key=lambda item, b=bom_item, v=variant_parts: stock_sort(item, b, v), ) - if len(available_stock) == 1 or interchangeable: - # Either there is only a single stock item available, - # or all items are "interchangeable" and we don't care where we take stock from + if len(available_stock) != 1 and not interchangeable: + # Multiple stock items are available, but they are not interchangeable - + # the user must manually decide how to allocate them. + continue - for stock_item in available_stock: - # Skip inactive parts - if not stock_item.part.active: - continue + for stock_item in available_stock: + candidate_stock[stock_item.pk] = stock_item - # How much of the stock item is "available" for allocation? - quantity = min( - unallocated_quantity, stock_item.unallocated_quantity() - ) + line_data.append((line_item, unallocated_quantity, available_stock)) - if quantity > 0: - try: - new_items.append( - BuildItem( - build_line=line_item, - stock_item=stock_item, - quantity=quantity, - ) + # Bulk-resolve the outstanding allocated quantity for every candidate stock item + # identified above, in a fixed number of queries rather than 3 queries per item. + allocated_by_pk = stock.models.StockItem.bulk_allocation_count( + candidate_stock.values() + ) + + new_items = [] + + for line_item, unallocated_quantity, available_stock in line_data: + # Either there is only a single stock item available, or all items are + # "interchangeable" and we don't care where we take stock from + for stock_item in available_stock: + # How much of the stock item is "available" for allocation? + stock_unallocated = max( + stock_item.quantity - allocated_by_pk.get(stock_item.pk, 0), 0 + ) + quantity = min(unallocated_quantity, stock_unallocated) + + if quantity > 0: + try: + new_items.append( + BuildItem( + build_line=line_item, + stock_item=stock_item, + quantity=quantity, ) + ) - # Subtract the required quantity - unallocated_quantity -= quantity + # Subtract the required quantity + unallocated_quantity -= quantity - except (ValidationError, serializers.ValidationError) as exc: - # Re-raise with a Django-compatible validation payload - raise ValidationError( - serializers.as_serializer_error(exc) - ) from exc + except (ValidationError, serializers.ValidationError) as exc: + # Re-raise with a Django-compatible validation payload + raise ValidationError( + serializers.as_serializer_error(exc) + ) from exc - if unallocated_quantity <= 0: - # We have now fully-allocated this BomItem - no need to continue! - break + if unallocated_quantity <= 0: + # We have now fully-allocated this BomItem - no need to continue! + break # Bulk-create the new BuildItem objects BuildItem.objects.bulk_create(new_items, batch_size=250) @@ -1468,7 +1950,9 @@ class Build( lines = self.build_lines.all() # Remove any 'consumable' line items - lines = lines.exclude(bom_item__consumable=True) + lines = lines.exclude( + part.models.BomItem.consumable_filter(prefix='bom_item__') + ) if tracked is True: lines = lines.filter(bom_item__sub_part__trackable=True) @@ -1505,7 +1989,9 @@ class Build( we need to test all "trackable" BuildLine objects """ lines = self.build_lines.filter(bom_item__sub_part__trackable=True) - lines = lines.exclude(bom_item__consumable=True) + lines = lines.exclude( + part.models.BomItem.consumable_filter(prefix='bom_item__') + ) # Find any lines which have not been fully allocated for line in lines: @@ -1529,7 +2015,9 @@ class Build( Returns: True if any BuildLine has been over-allocated. """ - lines = self.build_lines.all().exclude(bom_item__consumable=True) + lines = self.build_lines.all().exclude( + part.models.BomItem.consumable_filter(prefix='bom_item__') + ) lines = lines.prefetch_related('allocations') @@ -1596,7 +2084,7 @@ class Build( """Rebuild required quantity field for each BuildLine object.""" lines_to_update = [] - for line in self.build_lines.all(): + for line in self.build_lines.select_related('bom_item').all(): line.quantity = line.bom_item.get_required_quantity(self.quantity) lines_to_update.append(line) @@ -1758,7 +2246,7 @@ class BuildLine(report.mixins.InvenTreeReportMixin, InvenTree.models.InvenTreeMo def is_fully_allocated(self) -> bool: """Return True if this BuildLine is fully allocated.""" - if self.bom_item.consumable: + if self.bom_item.is_consumable: return True required = max(0, self.quantity - self.consumed) @@ -1954,71 +2442,26 @@ class BuildItem(InvenTree.models.InvenTreeMetadataModel): """Return the BomItem associated with this BuildItem.""" return self.build_line.bom_item if self.build_line else None - @transaction.atomic - def complete_allocation(self, quantity=None, notes: str = '', user=None) -> None: + def complete_allocation( + self, quantity: Optional[decimal.Decimal] = None, notes: str = '', user=None + ) -> None: """Complete the allocation of this BuildItem into the output stock item. + A thin wrapper around Build.complete_allocations(), for completing a single BuildItem. + Arguments: quantity: The quantity to allocate (default is the full quantity) notes: Additional notes to add to the transaction user: The user completing the allocation - - - If the referenced part is trackable, the stock item will be *installed* into the build output - - If the referenced part is *not* trackable, the stock item will be *consumed* by the build order - - TODO: This is quite expensive (in terms of number of database hits) - and requires some thought - TODO: Revisit, and refactor! - """ - # If the quantity is not provided, use the quantity of this BuildItem - if quantity is None: - quantity = self.quantity + quantities = {self.pk: quantity} if quantity is not None else None - item = self.stock_item - - # Ensure we are not allocating more than available - if quantity > item.quantity: - quantity = item.quantity - - # Split the allocated stock if there are more available than allocated - if item.quantity > quantity: - item = item.splitStock(quantity, None, user, notes=notes) - - # For a trackable part, special consideration needed! - if item.part.trackable: - # Make sure we are pointing to the new item - self.stock_item = item - self.save() - - # Install the stock item into the output - self.install_into.installStockItem( - item, quantity, user, notes, build=self.build - ) - - else: - # Mark the item as "consumed" by the build order - item.consumed_by = self.build - item.location = None - item.save(add_note=False) - - item.add_tracking_entry( - StockHistoryCode.BUILD_CONSUMED, - user, - notes=notes, - deltas={'buildorder': self.build.pk, 'quantity': float(item.quantity)}, - ) - - # Increase the "consumed" count for the associated BuildLine - self.build_line.consumed += quantity - self.build_line.save() - - # Decrease the allocated quantity - self.quantity = max(0, self.quantity - quantity) - - if self.quantity <= 0: - self.delete() - else: - self.save() + self.build.complete_allocations( + BuildItem.objects.filter(pk=self.pk), + quantities=quantities, + notes=notes, + user=user, + ) build_line = models.ForeignKey( BuildLine, on_delete=models.CASCADE, null=True, related_name='allocations' diff --git a/src/backend/InvenTree/build/serializers.py b/src/backend/InvenTree/build/serializers.py index d7cc0e5729..97edd4350d 100644 --- a/src/backend/InvenTree/build/serializers.py +++ b/src/backend/InvenTree/build/serializers.py @@ -1,6 +1,8 @@ """JSON serializers for Build API.""" +from collections.abc import Callable from decimal import Decimal +from typing import Optional from django.core.exceptions import ValidationError as DjangoValidationError from django.db import models, transaction @@ -22,20 +24,26 @@ from rest_framework import serializers from rest_framework.serializers import ValidationError import common.filters -import common.settings import company.serializers import InvenTree.helpers import part.filters import part.serializers as part_serializers +import stock.models as stock_models from common.settings import get_global_setting from generic.states.fields import InvenTreeCustomStatusSerializerMixin +from InvenTree.fields import PrefetchedPrimaryKeyRelatedField from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.serializers import ( + BulkPrefetchSerializerMixin, + CustomStatusSerializerMixin, + DuplicateOptionsSerializer, FilterableSerializerMixin, InvenTreeDecimalField, InvenTreeModelSerializer, + InvenTreeTaggitSerializer, NotesFieldMixin, OptionalField, + PrefetchSpec, ) from stock.generators import generate_batch_code from stock.models import StockItem, StockLocation @@ -49,17 +57,22 @@ from users.serializers import OwnerSerializer, UserSerializer from .models import Build, BuildItem, BuildLine from .status_codes import BuildStatus +from .validators import check_build_output class BuildSerializer( + CustomStatusSerializerMixin, FilterableSerializerMixin, NotesFieldMixin, + InvenTreeTaggitSerializer, DataImportExportSerializerMixin, InvenTreeCustomStatusSerializerMixin, InvenTreeModelSerializer, ): """Serializes a Build object.""" + SKIP_CREATE_FIELDS = ['duplicate'] + class Meta: """Serializer metaclass.""" @@ -73,6 +86,7 @@ class BuildSerializer( 'completed', 'completion_date', 'destination', + 'duplicate', 'external', 'parent', 'part', @@ -100,6 +114,7 @@ class BuildSerializer( 'parameters', 'priority', 'level', + 'tags', ] read_only_fields = [ 'completed', @@ -115,8 +130,6 @@ class BuildSerializer( level = serializers.IntegerField(label=_('Build Level'), read_only=True) - status_text = serializers.CharField(source='get_status_display', read_only=True) - part_detail = OptionalField( serializer_class=part_serializers.PartBriefSerializer, serializer_kwargs={'source': 'part', 'many': False, 'read_only': True}, @@ -126,6 +139,8 @@ class BuildSerializer( parameters = common.filters.enable_parameters_filter() + tags = common.filters.enable_tags_filter() + part_name = serializers.CharField( source='part.name', read_only=True, label=_('Part Name') ) @@ -182,12 +197,29 @@ class BuildSerializer( return queryset + duplicate = DuplicateOptionsSerializer(Build.objects.all(), copy_parameters=True) + def __init__(self, *args, **kwargs): """Determine if extra serializer fields are required.""" kwargs.pop('create', False) super().__init__(*args, **kwargs) + @transaction.atomic + def create(self, validated_data): + """Create a new Build instance, optionally copying data from an existing build.""" + duplicate = validated_data.pop('duplicate', None) + + instance = super().create(validated_data) + + if duplicate: + original = duplicate['original'] + + if duplicate.get('copy_parameters', True): + instance.copy_parameters_from(original) + + return instance + def validate_reference(self, reference): """Custom validation for the Build reference field.""" # Ensure the reference matches the required pattern @@ -254,11 +286,19 @@ class BuildOutputSerializer(serializers.Serializer): class BuildOutputQuantitySerializer(BuildOutputSerializer): """Build output with quantity field.""" + # Optional callable to validate the output field, if required + output_validator: Optional[Callable] = None + class Meta: """Serializer metaclass.""" fields = [*BuildOutputSerializer.Meta.fields, 'quantity'] + def __init__(self, *args, **kwargs): + """Initialize the serializer.""" + self.output_validator = kwargs.pop('output_validator', None) + super().__init__(*args, **kwargs) + quantity = serializers.DecimalField( max_digits=15, decimal_places=5, @@ -286,6 +326,10 @@ class BuildOutputQuantitySerializer(BuildOutputSerializer): 'quantity': _('Quantity cannot be greater than the output quantity') }) + if self.output_validator: + # Call the parent serializer's output validator, if provided + self.output_validator(output, quantity=quantity) + return data @@ -397,13 +441,6 @@ class BuildOutputCreateSerializer(serializers.Serializer): quantity = data['quantity'] serial_numbers = data.get('serial_numbers', '') - if part.trackable and not serial_numbers: - raise ValidationError({ - 'serial_numbers': _( - 'Serial numbers must be provided for trackable parts' - ) - }) - if serial_numbers: try: self.serials = InvenTree.helpers.extract_serial_numbers( @@ -521,7 +558,9 @@ class BuildOutputCompleteSerializer(serializers.Serializer): 'notes', ] - outputs = BuildOutputQuantitySerializer(many=True, required=True) + outputs = BuildOutputQuantitySerializer( + many=True, required=True, output_validator=check_build_output + ) location = serializers.PrimaryKeyRelatedField( queryset=StockLocation.objects.all(), @@ -531,6 +570,15 @@ class BuildOutputCompleteSerializer(serializers.Serializer): help_text=_('Location for completed build outputs'), ) + def validate_location(self, location): + """Validate the provided location.""" + if location and location.structural: + raise ValidationError( + _('Structural locations cannot be assigned stock items') + ) + + return location + status_custom_key = StockStatusCustomSerializer(default=StockStatus.OK.value) accept_incomplete_allocation = serializers.BooleanField( @@ -548,30 +596,6 @@ class BuildOutputCompleteSerializer(serializers.Serializer): outputs = data.get('outputs', []) - if common.settings.prevent_build_output_complete_on_incompleted_tests(): - errors = [] - for output in outputs: - stock_item = output['output'] - if ( - stock_item.hasRequiredTests() - and not stock_item.passedAllRequiredTests() - ): - serial = stock_item.serial - - if serial: - errors.append( - _( - f'Build output {serial} has not passed all required tests' - ) - ) - else: - errors.append( - _('Build output has not passed all required tests') - ) - - if errors: - raise ValidationError(errors) - if len(outputs) == 0: raise ValidationError(_('A list of build outputs must be provided')) @@ -839,7 +863,8 @@ class BuildAllocationItemSerializer(serializers.Serializer): fields = ['build_item', 'stock_item', 'quantity', 'output'] - build_line = serializers.PrimaryKeyRelatedField( + build_line = PrefetchedPrimaryKeyRelatedField( + cache_key='_build_line', queryset=BuildLine.objects.all(), many=False, allow_null=False, @@ -867,7 +892,8 @@ class BuildAllocationItemSerializer(serializers.Serializer): return build_line - stock_item = serializers.PrimaryKeyRelatedField( + stock_item = PrefetchedPrimaryKeyRelatedField( + cache_key='_stock_item', queryset=StockItem.objects.all(), many=False, allow_null=False, @@ -893,7 +919,8 @@ class BuildAllocationItemSerializer(serializers.Serializer): return quantity - output = serializers.PrimaryKeyRelatedField( + output = PrefetchedPrimaryKeyRelatedField( + cache_key='_output', queryset=StockItem.objects.filter(is_building=True), many=False, allow_null=True, @@ -912,11 +939,26 @@ class BuildAllocationItemSerializer(serializers.Serializer): # build = self.context['build'] - # TODO: Check that the "stock item" is valid for the referenced "sub_part" - # Note: Because of allow_variants options, it may not be a direct match! + # Check that the "stock item" is valid for the referenced "sub_part" + # Fast path: direct part match, avoids querying substitutes / variants below + # (which would otherwise cost extra queries per line for bulk allocations) + if stock_item.part_id != build_line.bom_item.sub_part_id and ( + not build_line.bom_item.is_stock_item_valid(stock_item) + ): + raise ValidationError({ + 'stock_item': _('Selected stock item does not match BOM line') + }) # Check that the quantity does not exceed the available amount from the stock item - q = stock_item.unallocated_quantity() + allocated = self.context.get('_stock_item_allocated') + + if allocated is not None: + q = max( + stock_item.quantity - allocated.get(stock_item.pk, Decimal(0)), + Decimal(0), + ) + else: + q = stock_item.unallocated_quantity() if quantity > q: q = InvenTree.helpers.clean_decimal(q) @@ -942,7 +984,7 @@ class BuildAllocationItemSerializer(serializers.Serializer): return data -class BuildAllocationSerializer(serializers.Serializer): +class BuildAllocationSerializer(BulkPrefetchSerializerMixin, serializers.Serializer): """Serializer for allocating stock items against a build order.""" class Meta: @@ -950,8 +992,33 @@ class BuildAllocationSerializer(serializers.Serializer): fields = ['items'] + prefetch_fields = [ + PrefetchSpec( + 'items', + 'build_line', + BuildLine.objects.select_related( + 'build', 'bom_item__part', 'bom_item__sub_part' + ), + '_build_line', + ), + PrefetchSpec('items', 'stock_item', StockItem.objects.all(), '_stock_item'), + PrefetchSpec( + 'items', 'output', StockItem.objects.filter(is_building=True), '_output' + ), + ] + items = BuildAllocationItemSerializer(many=True) + def after_prefetch(self, data): + """Bulk-compute allocated quantities for every referenced stock item. + + BuildAllocationItemSerializer.validate() checks each stock item's unallocated. + """ + stock_items = self.context.get('_stock_item', {}).values() + self.context['_stock_item_allocated'] = StockItem.bulk_allocation_count( + stock_items + ) + def validate(self, data): """Validation.""" data = super().validate(data) @@ -968,38 +1035,8 @@ class BuildAllocationSerializer(serializers.Serializer): data = self.validated_data items = data.get('items', []) - - with transaction.atomic(): - for item in items: - build_line = item['build_line'] - stock_item = item['stock_item'] - quantity = item['quantity'] - output = item.get('output', None) - - # Ignore allocation for consumable BOM items - if build_line.bom_item.consumable: - continue - - params = { - 'build_line': build_line, - 'stock_item': stock_item, - 'install_into': output, - } - - try: - if build_item := BuildItem.objects.filter(**params).first(): - # Find an existing BuildItem for this stock item - # If it exists, increase the quantity - build_item.quantity += quantity - build_item.save() - else: - # Create a new BuildItem to allocate stock - build_item = BuildItem.objects.create( - quantity=quantity, **params - ) - except (ValidationError, DjangoValidationError) as exc: - # Catch model errors and re-throw as DRF errors - raise ValidationError(detail=serializers.as_serializer_error(exc)) + build = self.context['build'] + build.allocate_stock(items) class BuildAutoAllocationSerializer(serializers.Serializer): @@ -1065,6 +1102,24 @@ class BuildAutoAllocationSerializer(serializers.Serializer): help_text=_('Select item type to auto-allocate'), ) + stock_sort_by = serializers.ChoiceField( + default=stock_models.STOCK_SORT_DEFAULT, + choices=stock_models.STOCK_SORT_CHOICES, + label=_('Stock Priority'), + help_text=_('Preferred order in which matching stock items are consumed'), + ) + + build_lines = serializers.PrimaryKeyRelatedField( + queryset=BuildLine.objects.all(), + many=True, + required=False, + default=list, + label=_('Build Lines'), + help_text=_( + 'Limit allocation to these build lines (leave blank to allocate all lines)' + ), + ) + class BuildItemSerializer( FilterableSerializerMixin, DataImportExportSerializerMixin, InvenTreeModelSerializer @@ -1352,7 +1407,7 @@ class BuildLineSerializer( source='bom_item.reference', label=_('Reference'), read_only=True ) consumable = serializers.BooleanField( - source='bom_item.consumable', label=_('Consumable'), read_only=True + source='bom_item.is_consumable', label=_('Consumable'), read_only=True ) optional = serializers.BooleanField( source='bom_item.optional', label=_('Optional'), read_only=True diff --git a/src/backend/InvenTree/build/tasks.py b/src/backend/InvenTree/build/tasks.py index 0dcac04bb8..ad90443493 100644 --- a/src/backend/InvenTree/build/tasks.py +++ b/src/backend/InvenTree/build/tasks.py @@ -6,6 +6,7 @@ from typing import Optional from django.contrib.auth.models import User from django.db import transaction +from django.db.models import Q from django.utils.translation import gettext_lazy as _ import structlog @@ -49,7 +50,7 @@ def consume_build_stock( items: Optional dict of BuildItem IDs (and quantities)to consume user_id: The ID of the user who initiated the stock consumption """ - from build.models import Build, BuildItem, BuildLine + from build.models import Build, BuildItem build = Build.objects.get(pk=build_id) user = User.objects.filter(pk=user_id).first() if user_id else None @@ -58,24 +59,19 @@ def consume_build_stock( items = items or {} notes = kwargs.pop('notes', '') - # Extract the relevant BuildLine and BuildItem objects - with transaction.atomic(): - # Consume each of the specified BuildLine objects - for line_id in lines: - if build_line := BuildLine.objects.filter(pk=line_id, build=build).first(): - for item in build_line.allocations.all(): - item.complete_allocation( - quantity=item.quantity, notes=notes, user=user - ) + # Condense the provided lines and items into a single BuildItem queryset, + # preselecting the related StockItem to avoid per-item queries downstream + build_items = ( + BuildItem.objects + .filter( + Q(build_line__pk__in=lines) | Q(pk__in=items.keys()), + build_line__build=build, + ) + .select_related('stock_item', 'stock_item__part') + .distinct() + ) - # Consume each of the specified BuildItem objects - for item_id, quantity in items.items(): - if build_item := BuildItem.objects.filter( - pk=item_id, build_line__build=build - ).first(): - build_item.complete_allocation( - quantity=quantity, notes=notes, user=user - ) + build.complete_allocations(build_items, quantities=items, notes=notes, user=user) @tracer.start_as_current_span('complete_build_allocations') @@ -97,7 +93,7 @@ def complete_build_allocations(build_id: int, user_id: int): else: user = None - build_order.complete_allocations(user) + build_order.complete_outstanding_allocations(user) @tracer.start_as_current_span('delete_build_outputs') @@ -115,9 +111,21 @@ def delete_build_outputs(build_id: int, output_ids: list, **kwargs): with transaction.atomic(): for output_id in output_ids: - output = StockItem.objects.filter(pk=output_id).first() - if output: - build.delete_output(output) + # Lock the output row, and re-check that it is still "in production" - + # it may have been processed already (e.g. by a duplicated task) + output = StockItem.objects.select_for_update().filter(pk=output_id).first() + + if not output: + continue + + if not output.is_building: + logger.warning( + 'Build output <%s> is no longer in production - skipping deletion', + output.pk, + ) + continue + + build.delete_output(output) @tracer.start_as_current_span('scrap_build_outputs') @@ -149,16 +157,33 @@ def scrap_build_outputs( with transaction.atomic(): for item in outputs: - output = StockItem.objects.filter(pk=item['output_id']).first() - if output: - build.scrap_build_output( - output, - item.get('quantity'), - location, - user=user, - notes=notes, - discard_allocations=discard_allocations, + # Lock the output row, and re-check that it is still "in production" - + # it may have been processed already (e.g. by a duplicated task) + output = ( + StockItem.objects + .select_for_update() + .filter(pk=item['output_id']) + .first() + ) + + if not output: + continue + + if not output.is_building: + logger.warning( + 'Build output <%s> is no longer in production - skipping scrap', + output.pk, ) + continue + + build.scrap_build_output( + output, + item.get('quantity'), + location, + user=user, + notes=notes, + discard_allocations=discard_allocations, + ) @tracer.start_as_current_span('complete_build_outputs') @@ -194,17 +219,34 @@ def complete_build_outputs( with transaction.atomic(): for item in outputs: - output = StockItem.objects.filter(pk=item['output_id']).first() - if output: - build.complete_build_output( - output, - user, - quantity=item.get('quantity'), - location=location, - status=status, - notes=notes, - required_tests=required_tests, + # Lock the output row, and re-check that it is still "in production" - + # it may have been processed already (e.g. by a duplicated task) + output = ( + StockItem.objects + .select_for_update() + .filter(pk=item['output_id']) + .first() + ) + + if not output: + continue + + if not output.is_building: + logger.warning( + 'Build output <%s> is no longer in production - skipping completion', + output.pk, ) + continue + + build.complete_build_output( + output, + user, + quantity=item.get('quantity'), + location=location, + status=status, + notes=notes, + required_tests=required_tests, + ) @tracer.start_as_current_span('cancel_build') @@ -257,15 +299,34 @@ def complete_build(build_id: int, user_id: int, trim_allocated_stock: bool = Fal trim_allocated_stock: If True, trim any allocated stock which was not consumed """ from build.models import Build + from build.status_codes import BuildStatus - build = Build.objects.get(pk=build_id) - user = User.objects.filter(pk=user_id).first() if user_id else None + with transaction.atomic(): + # Lock the build row: concurrent completion tasks (duplicate task + # delivery, or repeated completion requests while the build is still + # IN PRODUCTION) are serialized, and the status is re-checked below + build = Build.objects.select_for_update().get(pk=build_id) - if trim_allocated_stock: - build.trim_allocated_stock() + if build.status == BuildStatus.COMPLETE.value: + logger.warning( + 'Build order <%s> is already complete - skipping completion task', + build.pk, + ) + return - # Complete any remaining allocations for this build order - complete_build_allocations(build_id, user_id) + user = User.objects.filter(pk=user_id).first() if user_id else None + + if trim_allocated_stock: + build.trim_allocated_stock() + + # Complete any remaining allocations for this build order + complete_build_allocations(build_id, user_id) + + # Mark the build as completed + build.completion_date = InvenTree.helpers.current_date() + build.completed_by = user + build.status = BuildStatus.COMPLETE.value + build.save() # Register an event trigger_event(BuildEvents.COMPLETED, id=build.pk) diff --git a/src/backend/InvenTree/build/test_api.py b/src/backend/InvenTree/build/test_api.py index 9cd8427c9b..7b7685b0ba 100644 --- a/src/backend/InvenTree/build/test_api.py +++ b/src/backend/InvenTree/build/test_api.py @@ -3,17 +3,20 @@ from datetime import datetime, timedelta from typing import Optional +from django.db.models import Sum from django.urls import reverse +from django_q.models import OrmQ from rest_framework import status from build.models import Build, BuildItem, BuildLine from build.status_codes import BuildStatus from common.settings import set_global_setting from InvenTree.unit_test import InvenTreeAPITestCase -from part.models import BomItem, Part -from stock.models import StockItem -from stock.status_codes import StockStatus +from part.models import BomItem, BomItemSubstitute, Part, PartTestTemplate +from stock.events import StockEvents +from stock.models import StockItem, StockItemTracking, StockLocation, StockSortOrder +from stock.status_codes import StockHistoryCode, StockStatus class TestBuildAPI(InvenTreeAPITestCase): @@ -495,6 +498,39 @@ class BuildTest(BuildAPITest): 'This build output has already been completed', str(response.data) ) + def test_complete_build_output_structural_location(self): + """Test that a structural location is rejected by the BuildOutputComplete API. + + Ref: this validation must happen synchronously in the serializer, + before the completion is offloaded to the background worker. + """ + bo = Build.objects.get(pk=1) + + # Create a new build output + create_url = reverse('api-build-output-create', kwargs={'pk': bo.pk}) + response = self.post(create_url, {'quantity': 1}, expected_code=201) + output = StockItem.objects.get(pk=response.data[0]['pk']) + + structural_location = StockLocation.objects.create( + name='Structural location', structural=True + ) + + complete_url = reverse('api-build-output-complete', kwargs={'pk': bo.pk}) + + response = self.post( + complete_url, + {'outputs': [{'output': output.pk}], 'location': structural_location.pk}, + expected_code=400, + ) + + self.assertIn( + 'Structural locations cannot be assigned stock items', str(response.data) + ) + + # None of the outputs should have been completed + output.refresh_from_db() + self.assertTrue(output.is_building) + def test_download_build_orders(self): """Test that we can download a list of build orders via the API.""" required_cols = [ @@ -687,7 +723,7 @@ class BuildAllocationTest(BuildAPITest): wrong_line = None for line in lines: - if line.bom_item.sub_part.pk != si.pk: + if line.bom_item.sub_part.pk != si.part.pk: wrong_line = line break @@ -837,9 +873,7 @@ class BuildAllocationTest(BuildAPITest): ) # Test a fractional quantity when the *available* quantity is less than 1 - si = StockItem.objects.create( - part=si.part, quantity=0.3159, tree_id=0, level=0, lft=0, rght=0 - ) + si = StockItem.objects.create(part=si.part, quantity=0.3159) self.post( self.url, @@ -1359,9 +1393,10 @@ class BuildOutputCreateTest(BuildAPITest): # Stock items have increased self.assertEqual(n_items + 5, part.stock_items.count()) - # Serial numbers have been created + # Serial numbers have been created, each with a creation_date for sn in range(1, 6): self.assertTrue(part.stock_items.filter(serial=sn).exists()) + self.assertIsNotNone(part.stock_items.get(serial=sn).creation_date) def test_create_unserialized_output(self): """Create an unserialized build output via the API.""" @@ -1383,6 +1418,38 @@ class BuildOutputCreateTest(BuildAPITest): # Stock items have increased self.assertEqual(n_items + 1, part.stock_items.count()) + # The new output must have a creation_date set + self.assertIsNotNone(part.stock_items.order_by('-pk').first().creation_date) + + def test_create_unserialized_output_trackable_part(self): + """A build output for a trackable part may be created without serial numbers. + + This allows a batch quantity to be created (e.g. from an external build order) + which can be serialized at some later stage in the process. + """ + build_id = 1 + url = reverse('api-build-output-create', kwargs={'pk': build_id}) + + build = Build.objects.get(pk=build_id) + part = build.part + + part.trackable = True + part.save() + + n_outputs = build.output_count + n_items = part.stock_items.count() + + # Create a single non-serialized output, even though the part is trackable + self.post(url, data={'quantity': 10}, expected_code=201) + + # A single build output has been created (not one per unit of quantity) + self.assertEqual(n_outputs + 1, build.output_count) + self.assertEqual(n_items + 1, part.stock_items.count()) + + output = part.stock_items.order_by('-pk').first() + self.assertIsNone(output.serial) + self.assertEqual(output.quantity, 10) + class BuildOutputScrapTest(BuildAPITest): """Unit tests for scrapping build outputs.""" @@ -1527,10 +1594,15 @@ class BuildOutputScrapTest(BuildAPITest): 'notes': 'Partial complete', } - # Ensure that an invalid quantity raises an error - for q in [-4, 0, 999]: + # Ensure that an invalid quantity raises an error, with the expected message + for q, expected_message in [ + (-4, 'Ensure this value is greater than or equal to 0'), + (0, 'Quantity must be greater than zero'), + (999, 'Quantity cannot be greater than the output quantity'), + ]: data['outputs'][0]['quantity'] = q - self.post(url, data, expected_code=400) + response = self.post(url, data, expected_code=400) + self.assertIn(expected_message, str(response.data)) # Partially complete the output (with a valid quantity) data['outputs'][0]['quantity'] = 4 @@ -1548,6 +1620,94 @@ class BuildOutputScrapTest(BuildAPITest): self.assertEqual(completed_output.status, StockStatus.OK) self.assertFalse(completed_output.is_building) + def test_complete_with_required_tests(self): + """Test that build output completion is blocked if required tests have not passed.""" + build = Build.objects.get(pk=1) + output = build.create_build_output(1).first() + + template = PartTestTemplate.objects.create( + part=build.part, test_name='Required test', required=True + ) + + set_global_setting( + 'PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS', True, change_user=None + ) + + url = reverse('api-build-output-complete', kwargs={'pk': build.pk}) + + data = {'outputs': [{'output': output.pk}], 'location': 1} + + response = self.post(url, data, expected_code=400) + + self.assertIn( + 'Build output has not passed all required tests', str(response.data) + ) + + # Add a passing test result - the output should now be able to be completed + output.add_test_result(template=template, result=True) + + self.post(url, data, expected_code=200) + + def test_complete_still_in_production(self): + """Test that build output completion is blocked if an allocated item is still in production.""" + build = Build.objects.get(pk=1) + output = build.create_build_output(1).first() + + build.create_build_line_items() + line = build.build_lines.first() + + sub_build = Build.objects.create( + part=line.bom_item.sub_part, + quantity=1, + title='Sub-build', + reference='BO-9998', + ) + + in_production = StockItem.objects.create( + part=line.bom_item.sub_part, quantity=1, is_building=True, build=sub_build + ) + + BuildItem.objects.create( + build_line=line, stock_item=in_production, quantity=1, install_into=output + ) + + url = reverse('api-build-output-complete', kwargs={'pk': build.pk}) + + response = self.post( + url, {'outputs': [{'output': output.pk}], 'location': 1}, expected_code=400 + ) + + self.assertIn( + 'Allocated stock items are still in production', str(response.data) + ) + + def test_partial_complete_with_allocated_items(self): + """Test that a build output with allocated items cannot be partially completed.""" + build = Build.objects.get(pk=1) + output = build.create_build_output(10).first() + + build.create_build_line_items() + line = build.build_lines.first() + + stock_item = StockItem.objects.create(part=line.bom_item.sub_part, quantity=10) + + BuildItem.objects.create( + build_line=line, stock_item=stock_item, quantity=1, install_into=output + ) + + url = reverse('api-build-output-complete', kwargs={'pk': build.pk}) + + response = self.post( + url, + {'outputs': [{'output': output.pk, 'quantity': 4}], 'location': 1}, + expected_code=400, + ) + + self.assertIn( + 'Cannot partially complete a build output with allocated items', + str(response.data), + ) + class BuildOutputCancelTest(BuildAPITest): """Test cancellation of build outputs.""" @@ -1621,6 +1781,246 @@ class BuildLineTests(BuildAPITest): self.assertEqual(n_t + n_f, BuildLine.objects.count()) + def test_filter_available_allocated_consumed_mixed(self): + """Filter BuildLine objects with mixed allocated / consumed / stock states.""" + assembly = Part.objects.create( + name='Available Filter Assembly', + description='Assembly for advanced available filter tests', + assembly=True, + ) + + components = [ + Part.objects.create( + name=f'Available Filter Component {idx}', + description=f'Component {idx}', + component=True, + ) + for idx in range(4) + ] + + # The assembly uses 10x of each component + for component in components: + BomItem.objects.create(part=assembly, sub_part=component, quantity=10) + + # Create a new Build, requiring 100x of each component + build = Build.objects.create( + part=assembly, + reference='BO-9999', + quantity=10, + title='Available Filter Mixed', + ) + + lines = list(build.build_lines.order_by('pk')) + self.assertEqual(len(lines), 4) + + # Build line quantity is 100 for each line (10 * build quantity 10) + for line in lines: + self.assertEqual(line.quantity, 100) + + # Stock allocation baseline for each component + # Note: Quantity values will be updated later + stock_items = [ + StockItem.objects.create(part=component, quantity=1) + for component in components + ] + + # Line 0: AVAILABLE = True + # allocated = 30 + # consumed = 0 + # available = 70 + BuildItem.objects.create( + build_line=lines[0], stock_item=stock_items[0], quantity=30 + ) + + stock_items[0].quantity = 30 + 70 + stock_items[0].save() + + # Line 1: allocated 20 + consumed 30 + available stock 50 => available (100) + BuildItem.objects.create( + build_line=lines[1], stock_item=stock_items[1], quantity=20 + ) + lines[1].consumed = 30 + lines[1].save() + stock_items[1].quantity = 20 + 50 + stock_items[1].save() + + # Line 2: allocated 0 + consumed 10 + available stock 50 => not available (60) + lines[2].consumed = 10 + lines[2].save() + stock_items[2].quantity = 50 + stock_items[2].save() + + # Line 3: allocated 40 + consumed 0 + available stock 20 => not available (60) + BuildItem.objects.create( + build_line=lines[3], stock_item=stock_items[3], quantity=40 + ) + stock_items[3].quantity = 40 + 20 + stock_items[3].save() + + url = reverse('api-build-line-list') + + response_true = self.get(url, {'build': build.pk, 'available': True}) + + response_false = self.get(url, {'build': build.pk, 'available': False}) + + true_ids = {item['pk'] for item in response_true.data} + false_ids = {item['pk'] for item in response_false.data} + + self.assertSetEqual(true_ids, {lines[0].pk, lines[1].pk}) + self.assertSetEqual(false_ids, {lines[2].pk, lines[3].pk}) + self.assertSetEqual(true_ids | false_ids, {line.pk for line in lines}) + + def test_filter_available_substitute_and_variant_stock(self): + """Filter BuildLine objects where availability comes from substitute or variant stock.""" + assembly = Part.objects.create( + name='Available Filter Sub/Var Assembly', + description='Assembly for substitute and variant availability tests', + assembly=True, + ) + + # Substitute path: line should pass via substitute stock + sub_master_ok = Part.objects.create(name='Sub Master OK', component=True) + sub_alt_ok = Part.objects.create(name='Sub Alt OK', component=True) + + # Substitute path: line should fail (insufficient substitute stock) + sub_master_low = Part.objects.create(name='Sub Master Low', component=True) + sub_alt_low = Part.objects.create(name='Sub Alt Low', component=True) + + # Variant path: line should pass via variant stock + var_parent_ok = Part.objects.create( + name='Variant Parent OK', component=True, is_template=True + ) + var_child_ok = Part.objects.create( + name='Variant Child OK', component=True, variant_of=var_parent_ok + ) + + # Variant path: line should fail (insufficient variant stock) + var_parent_low = Part.objects.create( + name='Variant Parent Low', component=True, is_template=True + ) + var_child_low = Part.objects.create( + name='Variant Child Low', component=True, variant_of=var_parent_low + ) + + bom_sub_ok = BomItem.objects.create( + part=assembly, sub_part=sub_master_ok, quantity=10, allow_variants=False + ) + bom_sub_low = BomItem.objects.create( + part=assembly, sub_part=sub_master_low, quantity=10, allow_variants=False + ) + bom_var_ok = BomItem.objects.create( + part=assembly, sub_part=var_parent_ok, quantity=10, allow_variants=True + ) + bom_var_low = BomItem.objects.create( + part=assembly, sub_part=var_parent_low, quantity=10, allow_variants=True + ) + + BomItemSubstitute.objects.create(bom_item=bom_sub_ok, part=sub_alt_ok) + BomItemSubstitute.objects.create(bom_item=bom_sub_low, part=sub_alt_low) + + # Build quantity 10 => each line requires 100 units + build = Build.objects.create( + part=assembly, reference='BO-0987', quantity=10, title='Available Sub/Var' + ) + + lines = list(build.build_lines.order_by('pk')) + self.assertEqual(len(lines), 4) + + # Keep master parts at zero stock so only substitute/variant paths contribute + StockItem.objects.create(part=sub_alt_ok, quantity=100) + StockItem.objects.create(part=sub_alt_low, quantity=40) + StockItem.objects.create(part=var_child_ok, quantity=100) + StockItem.objects.create(part=var_child_low, quantity=40) + + url = reverse('api-build-line-list') + + response_true = self.get(url, {'build': build.pk, 'available': True}) + + response_false = self.get(url, {'build': build.pk, 'available': False}) + + pk_by_bom = {line.bom_item_id: line.pk for line in lines} + + expected_true = {pk_by_bom[bom_sub_ok.pk], pk_by_bom[bom_var_ok.pk]} + expected_false = {pk_by_bom[bom_sub_low.pk], pk_by_bom[bom_var_low.pk]} + + true_ids = {item['pk'] for item in response_true.data} + false_ids = {item['pk'] for item in response_false.data} + + self.assertSetEqual(true_ids, expected_true) + self.assertSetEqual(false_ids, expected_false) + self.assertSetEqual(true_ids | false_ids, {line.pk for line in lines}) + + def test_filter_consumable_via_part(self): + """Filter BuildLine objects by 'consumable' status, accounting for the underlying part. + + A BuildLine should be treated as 'consumable' if either the BOM line + itself is marked as consumable, or the underlying part is marked as consumable. + """ + assembly = Part.objects.create( + name='Consumable Filter Assembly', + description='Assembly for consumable filter tests', + assembly=True, + ) + + plain = Part.objects.create( + name='Consumable Filter Plain Component', + description='A regular component', + component=True, + ) + + consumable_part = Part.objects.create( + name='Consumable Filter Consumable Part', + description='A part marked as consumable', + component=True, + consumable=True, + ) + + consumable_line_part = Part.objects.create( + name='Consumable Filter Consumable BOM Line', + description='A part which is consumable only via its BOM line', + component=True, + ) + + bom_item_plain = BomItem.objects.create( + part=assembly, sub_part=plain, quantity=1 + ) + bom_item_part_consumable = BomItem.objects.create( + part=assembly, sub_part=consumable_part, quantity=1 + ) + bom_item_line_consumable = BomItem.objects.create( + part=assembly, sub_part=consumable_line_part, quantity=1, consumable=True + ) + + build = Build.objects.create( + part=assembly, + reference='BO-9997', + quantity=1, + title='Consumable Filter Build', + ) + + url = reverse('api-build-line-list') + + response = self.get(url, data={'build': build.pk, 'consumable': True}) + returned_bom_items = {item['bom_item'] for item in response.data} + + self.assertIn(bom_item_part_consumable.pk, returned_bom_items) + self.assertIn(bom_item_line_consumable.pk, returned_bom_items) + self.assertNotIn(bom_item_plain.pk, returned_bom_items) + + response = self.get(url, data={'build': build.pk, 'consumable': False}) + returned_bom_items = {item['bom_item'] for item in response.data} + + self.assertIn(bom_item_plain.pk, returned_bom_items) + self.assertNotIn(bom_item_part_consumable.pk, returned_bom_items) + self.assertNotIn(bom_item_line_consumable.pk, returned_bom_items) + + # Check that the serialized 'consumable' field reflects the combined status + response = self.get( + url, data={'build': build.pk, 'bom_item': bom_item_part_consumable.pk} + ) + self.assertEqual(len(response.data), 1) + self.assertTrue(response.data[0]['consumable']) + def test_output_options(self): """Test output options for the BuildLine endpoint.""" self.run_output_test( @@ -1811,3 +2211,825 @@ class BuildConsumeTest(BuildAPITest): for line in self.build.build_lines.all(): self.assertEqual(line.consumed, 100) + + def test_consume_many_lines(self): + """Test consuming stock against a build order with a large number of BOM lines. + + - Create 100 sub-components for a new assembly + - Create a build order against the assembly + - Create a stock item for each component - some with exactly the required + quantity, others with more than required (to test stock splitting) + - Every 10th line is instead allocated from *two* different stock items, + whose quantities combined equal the required quantity (to test multiple + BuildItems being allocated against a single BuildLine) + - Allocate stock against each build line + - Complete the build order (via output creation, output completion, and finish) + - Check that every build line is fully consumed + - Check that stock items are reduced (and split) correctly + - Check that associated events are triggered + - Check that required low-stock checks are triggered for each component + - Check that the correct stock tracking entries are created for each split stock item + """ + N = 100 + bom_quantity = 5 + build_quantity = 10 + required_quantity = bom_quantity * build_quantity + + # Every MULTI_ITEM_STRIDE'th line is allocated from two stock items instead of one + MULTI_ITEM_STRIDE = 10 + + assembly = Part.objects.create( + name='Large Test Assembly', + description='Assembly with a large number of BOM lines', + assembly=True, + ) + + components = [ + Part.objects.create( + name=f'Large Test Component {i}', + description=f'Large Test Component Description {i}', + component=True, + ) + for i in range(N) + ] + + for component in components: + BomItem.objects.create( + part=assembly, sub_part=component, quantity=bom_quantity + ) + + build = Build.objects.create( + part=assembly, + reference='BO-12350', + quantity=build_quantity, + title='Large Test Build', + ) + + self.assertEqual(build.build_lines.count(), N) + + # Create stock item(s) for each component: + # - Every MULTI_ITEM_STRIDE'th line gets *two* stock items, whose quantities + # combined equal the required quantity (no splitting needed for either) + # - Of the rest, odd-indexed components get more stock than is required (to + # test splitting), even-indexed components get exactly the required quantity + stock_items = [] + + for idx, component in enumerate(components): + if idx % MULTI_ITEM_STRIDE == 0: + first_quantity = required_quantity * 3 // 5 + stock_items.append([ + StockItem.objects.create(part=component, quantity=first_quantity), + StockItem.objects.create( + part=component, quantity=required_quantity - first_quantity + ), + ]) + else: + stock_items.append([ + StockItem.objects.create( + part=component, + quantity=required_quantity + (25 if idx % 2 else 0), + ) + ]) + + # Starting point (before splitting stock) + N_STOCK_ITEMS = StockItem.objects.count() + + # Allocate stock against each build line - lines with multiple stock items get + # one allocation entry per stock item, with quantities summing to the required amount + allocation_items = [] + + for line, items in zip(build.build_lines.all(), stock_items, strict=True): + if len(items) > 1: + for si in items: + allocation_items.append({ + 'build_line': line.pk, + 'stock_item': si.pk, + 'quantity': si.quantity, + }) + else: + allocation_items.append({ + 'build_line': line.pk, + 'stock_item': items[0].pk, + 'quantity': required_quantity, + }) + + data = {'items': allocation_items} + + self.post( + reverse('api-build-allocate', kwargs={'pk': build.pk}), + data, + expected_code=201, + benchmark=True, + max_query_time=1.0, + max_query_count=50, + ) + + n_multi_item_lines = len(range(0, N, MULTI_ITEM_STRIDE)) + self.assertEqual(build.allocated_stock.count(), N + n_multi_item_lines) + self.assertTrue(build.are_untracked_parts_allocated) + + # Create (and complete) a single build output for the full build quantity + build.create_build_output(build_quantity) + output = build.incomplete_outputs.first() + + self.post( + reverse('api-build-output-complete', kwargs={'pk': build.pk}), + { + 'outputs': [{'output': output.pk}], + 'location': 1, + 'status': StockStatus.OK.value, + }, + expected_code=200, + benchmark=True, + max_query_time=0.5, + max_query_count=200, + ) + + build.refresh_from_db() + self.assertEqual(build.completed, build_quantity) + self.assertTrue(build.can_complete) + + # Enable plugin events, and queue them (rather than firing synchronously), + # so we can inspect exactly what was queued once the build is finished + set_global_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + # Start with a fresh slate for the OrmQ queue, so we can inspect exactly what is queued during the build finish + OrmQ.objects.all().delete() + + # Finish the build order - this consumes all allocated stock + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + self.post( + reverse('api-build-finish', kwargs={'pk': build.pk}), + {}, + expected_code=201, + benchmark=True, + max_query_count=180, + max_query_time=1.5, + ) + + build.refresh_from_db() + self.assertTrue(build.is_complete) + + queued_tasks = list(OrmQ.objects.all()) + + # register_event tasks queued for StockEvents.ITEM_SPLIT, one per split component + split_event_tasks = [ + task + for task in queued_tasks + if task.func() == 'plugin.base.event.events.register_event' + and task.args() == (StockEvents.ITEM_SPLIT,) + ] + self.assertEqual(len(split_event_tasks), N // 2) + + # 'notify_low_stock_if_required' should be queued once per distinct part touched - + # every one of the N components here is a distinct part + low_stock_tasks = [ + task + for task in queued_tasks + if task.func() == 'part.tasks.notify_low_stock_if_required' + ] + self.assertEqual( + {task.args()[0] for task in low_stock_tasks}, + {component.pk for component in components}, + ) + + # All lines should be fully consumed, and no allocations should remain + self.assertEqual(build.allocated_stock.count(), 0) + self.assertEqual(build.build_lines.count(), N) + + for line in build.build_lines.all(): + self.assertEqual(line.consumed, required_quantity) + + # Check that each original stock item was correctly reduced / split + for idx, (component, items) in enumerate( + zip(components, stock_items, strict=True) + ): + for si in items: + si.refresh_from_db() + + if idx % MULTI_ITEM_STRIDE == 0: + # Two different stock items were allocated against this line - each + # should be fully consumed directly (no splitting), and combined they + # should cover the full required quantity + self.assertEqual(len(items), 2) + + consumed_total = sum(si.quantity for si in items) + self.assertEqual(consumed_total, required_quantity) + + for si in items: + self.assertEqual(si.consumed_by, build) + + self.assertFalse( + StockItemTracking.objects.filter( + item=si, + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value, + ).exists() + ) + self.assertTrue( + StockItemTracking.objects.filter( + item=si, + tracking_type=StockHistoryCode.BUILD_CONSUMED.value, + deltas__buildorder=build.pk, + ).exists() + ) + + # Total quantity of stock for this component is unchanged + total_quantity = StockItem.objects.filter(part=component).aggregate( + total=Sum('quantity') + )['total'] + self.assertEqual(total_quantity, required_quantity) + + continue + + stock_item = items[0] + + if idx % 2: + # Excess stock - original item should be split, retaining the remainder + self.assertEqual(stock_item.quantity, 25) + self.assertIsNone(stock_item.consumed_by) + + # A new stock item should have been split off, and consumed by the build + consumed_items = StockItem.objects.filter( + part=component, consumed_by=build + ) + self.assertEqual(consumed_items.count(), 1) + consumed_item = consumed_items.first() + self.assertEqual(consumed_item.quantity, required_quantity) + self.assertNotEqual(consumed_item.pk, stock_item.pk) + + # Split tracking entries: one on the new (split-off) item, one on the original + self.assertTrue( + StockItemTracking.objects.filter( + item=consumed_item, + tracking_type=StockHistoryCode.SPLIT_FROM_PARENT.value, + deltas__stockitem=stock_item.pk, + ).exists() + ) + self.assertTrue( + StockItemTracking.objects.filter( + item=stock_item, + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value, + ).exists() + ) + + # The ITEM_SPLIT event should reference the new item as 'id' and the + # original item as 'parent' + self.assertTrue( + any( + task.kwargs() + == {'id': consumed_item.pk, 'parent': stock_item.pk} + for task in split_event_tasks + ) + ) + + # Consumption is recorded against the new (split-off) item + self.assertTrue( + StockItemTracking.objects.filter( + item=consumed_item, + tracking_type=StockHistoryCode.BUILD_CONSUMED.value, + deltas__buildorder=build.pk, + ).exists() + ) + else: + # Exact stock - original item should be consumed directly (no split) + self.assertEqual(stock_item.quantity, required_quantity) + self.assertEqual(stock_item.consumed_by, build) + + # No split occurred - consumption is recorded directly against this item + self.assertFalse( + StockItemTracking.objects.filter( + item=stock_item, + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value, + ).exists() + ) + self.assertTrue( + StockItemTracking.objects.filter( + item=stock_item, + tracking_type=StockHistoryCode.BUILD_CONSUMED.value, + deltas__buildorder=build.pk, + ).exists() + ) + + # In either case, total quantity of stock for this component is unchanged + total_quantity = StockItem.objects.filter(part=component).aggregate( + total=Sum('quantity') + )['total'] + self.assertEqual(total_quantity, required_quantity + (25 if idx % 2 else 0)) + + # The total number of StockItem instances in the DB has also increased + self.assertEqual(StockItem.objects.count(), N_STOCK_ITEMS + 1 + (N // 2)) + + def test_consume_tracked_allocations(self): + """Test consuming of tracked allocations against a BuildOrder.""" + set_global_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + tracked_assembly = Part.objects.create( + name='Tracked Test Assembly', + description='Trackable assembly for install-path testing', + assembly=True, + trackable=True, + ) + + tracked_component = Part.objects.create( + name='Tracked Test Component', + description='Trackable component for install-path testing', + trackable=True, + component=True, + ) + + BomItem.objects.create( + part=tracked_assembly, sub_part=tracked_component, quantity=1 + ) + + tracked_build = Build.objects.create( + part=tracked_assembly, + reference='BO-99002', + quantity=2, + title='Tracked Test Build', + ) + + serials = ['901', '902'] + + for sn in serials: + StockItem.objects.create(part=tracked_component, quantity=1, serial=sn) + + # Auto-allocate serialized outputs against matching component serial numbers + response = self.post( + reverse('api-build-output-create', kwargs={'pk': tracked_build.pk}), + { + 'quantity': 2, + 'serial_numbers': ', '.join(serials), + 'auto_allocate': True, + }, + expected_code=201, + ) + + outputs = { + entry['serial']: StockItem.objects.get( + part=tracked_assembly, serial=entry['serial'] + ) + for entry in response.data + } + tracked_components = { + sn: StockItem.objects.get(part=tracked_component, serial=sn) + for sn in serials + } + + OrmQ.objects.all().delete() + + # Consume the tracked allocations directly (rather than completing the output), + # to route them through Build.complete_allocations() and exercise the install path + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + self.post( + reverse('api-build-consume', kwargs={'pk': tracked_build.pk}), + { + 'lines': [ + {'build_line': line.pk} + for line in tracked_build.build_lines.all() + ] + }, + expected_code=200, + ) + + self.assertEqual(tracked_build.allocated_stock.count(), 0) + + install_event_tasks = [ + task + for task in OrmQ.objects.all() + if task.func() == 'plugin.base.event.events.register_event' + and task.args() == (StockEvents.ITEM_INSTALLED_INTO_ASSEMBLY,) + ] + self.assertEqual(len(install_event_tasks), len(serials)) + + for sn in serials: + component_item = tracked_components[sn] + output_item = outputs[sn] + + component_item.refresh_from_db() + + # The component is now installed into (and consumed by) the output + self.assertEqual(component_item.belongs_to, output_item) + self.assertEqual(component_item.consumed_by, tracked_build) + + self.assertTrue( + any( + task.kwargs() + == {'id': component_item.pk, 'assembly_id': output_item.pk} + for task in install_event_tasks + ) + ) + + self.assertTrue( + StockItemTracking.objects.filter( + item=component_item, + tracking_type=StockHistoryCode.INSTALLED_INTO_ASSEMBLY.value, + deltas__stockitem=output_item.pk, + ).exists() + ) + self.assertTrue( + StockItemTracking.objects.filter( + item=output_item, + tracking_type=StockHistoryCode.INSTALLED_CHILD_ITEM.value, + deltas__stockitem=component_item.pk, + ).exists() + ) + + +class BuildCustomStatusTest(BuildAPITest): + """Tests for custom status values on Build orders.""" + + url = reverse('api-build-list') + + def test_custom_status_query_count(self): + """Test that listing Build orders with custom statuses does not cause N+1 queries. + + Ensures that resolving 'status_text' for custom status values is O(1) + in database queries, not O(N) relative to the number of results. + """ + from django.contrib.contenttypes.models import ContentType + + from common.models import InvenTreeCustomUserStateModel + + build_content_type = ContentType.objects.get_for_model(Build) + + # 10 custom status values - different keys, labels, and logical_keys + logical_keys = [ + BuildStatus.PENDING.value, + BuildStatus.PRODUCTION.value, + BuildStatus.ON_HOLD.value, + BuildStatus.CANCELLED.value, + BuildStatus.COMPLETE.value, + BuildStatus.PENDING.value, + BuildStatus.PRODUCTION.value, + BuildStatus.ON_HOLD.value, + BuildStatus.CANCELLED.value, + BuildStatus.COMPLETE.value, + ] + + custom_statuses = [ + InvenTreeCustomUserStateModel.objects.create( + key=3000 + i, + name=f'BuildCustomStatus{i}', + label=f'Build Custom Status Label {i}', + color='secondary', + logical_key=logical_keys[i], + model=build_content_type, + reference_status='BuildStatus', + ) + for i in range(10) + ] + + part = Part.objects.filter(assembly=True).first() + + # Build is an MPTT tree model; bulk_create requires tree fields to be + # populated manually. All new orders are root nodes (no parent) so each + # gets its own unique tree_id. + from django.db.models import Max + + next_tree_id = (Build.objects.aggregate(m=Max('tree_id'))['m'] or 0) + 1 + + # Create 100 build orders, cycling through the 10 custom statuses + Build.objects.bulk_create([ + Build( + part=part, + reference=f'BO-QTEST-{i}', + quantity=1, + status=custom_statuses[i % 10].logical_key, + status_custom_key=custom_statuses[i % 10].key, + lft=1, + rght=2, + level=0, + tree_id=next_tree_id + i, + ) + for i in range(100) + ]) + + # Lookup: custom_key -> custom_status_object, for quick per-row assertions + custom_lookup = {cs.key: cs for cs in custom_statuses} + + # Query count must stay below the fixed threshold regardless of limit. + # An N+1 bug would push limit=50 or limit=100 well over the threshold. + for limit in [1, 10, 50, 100]: + response = self.get( + self.url, data={'limit': limit}, expected_code=200, max_query_count=50 + ) + + for result in response.data['results']: + cs = custom_lookup.get(result['status_custom_key']) + + if cs is None: + # Build from fixtures - no custom status assigned + continue + + self.assertEqual(result['status'], cs.logical_key) + self.assertEqual(result['status_custom_key'], cs.key) + self.assertEqual(result['status_text'], cs.label) + + +class BuildAutoAllocateAPITest(InvenTreeAPITestCase): + """API integration tests for BuildAutoAllocate endpoint back-ports (stock_sort_by, build_lines).""" + + fixtures = ['company', 'users'] + + roles = ['build.add', 'build.change'] + + @classmethod + def setUpTestData(cls): + """Create shared parts, locations and build data for all tests.""" + super().setUpTestData() + + cls.assembly = Part.objects.create( + name='AutoAlloc Assembly', description='', assembly=True + ) + cls.component = Part.objects.create( + name='AutoAlloc Component', description='', component=True + ) + cls.component_b = Part.objects.create( + name='AutoAlloc Component B', description='', component=True + ) + + cls.loc_a = StockLocation.objects.create(name='BuildShelf A') + cls.loc_b = StockLocation.objects.create(name='BuildShelf B') + + def _next_ref(self): + """Return a valid Build reference using the system-generated next value.""" + return Build.generate_batch_code() + + def _make_build(self, quantity=10): + """Create a fresh Build with one untracked BOM line (component only).""" + build = Build.objects.create( + part=self.assembly, + reference=f'BO-{9000 + Build.objects.count():04d}', + quantity=quantity, + ) + BomItem.objects.create(part=self.assembly, sub_part=self.component, quantity=1) + build.create_build_line_items() + return build + + def _url(self, pk): + return reverse('api-build-auto-allocate', kwargs={'pk': pk}) + + def _create_build_two_lines(self, quantity=5): + """Create a Build with two untracked BOM lines (component + component_b).""" + build = Build.objects.create( + part=self.assembly, + reference=f'BO-{9000 + Build.objects.count():04d}', + quantity=quantity, + ) + BomItem.objects.create(part=self.assembly, sub_part=self.component, quantity=1) + BomItem.objects.create( + part=self.assembly, sub_part=self.component_b, quantity=1 + ) + build.create_build_line_items() + return build + + # ------------------------------------------------------------------ + # Validation + # ------------------------------------------------------------------ + + def test_invalid_stock_sort_by_rejected(self): + """An unrecognised stock_sort_by value is rejected with 400.""" + build = self._make_build() + self.post( + self._url(build.pk), {'stock_sort_by': 'not_valid'}, expected_code=400 + ) + + # ------------------------------------------------------------------ + # stock_sort_by behaviour + # ------------------------------------------------------------------ + + def test_stock_sort_by_quantity_asc(self): + """stock_sort_by=QUANTITY_ASC consumes the smallest lot first.""" + build = self._make_build(quantity=15) + small = StockItem.objects.create(part=self.component, quantity=5) + StockItem.objects.create(part=self.component, quantity=100) + + self.post( + self._url(build.pk), + { + 'stock_sort_by': str(StockSortOrder.QUANTITY_ASC), + 'interchangeable': True, + }, + expected_code=200, + ) + + allocs = BuildItem.objects.filter(build_line__build=build) + self.assertTrue(any(a.stock_item == small and a.quantity == 5 for a in allocs)) + + def test_stock_sort_by_quantity_desc(self): + """stock_sort_by=QUANTITY_DESC consumes the largest lot first, covering requirement in one allocation.""" + build = self._make_build(quantity=15) + StockItem.objects.create(part=self.component, quantity=5) + large = StockItem.objects.create(part=self.component, quantity=100) + + self.post( + self._url(build.pk), + { + 'stock_sort_by': str(StockSortOrder.QUANTITY_DESC), + 'interchangeable': True, + }, + expected_code=200, + ) + + allocs = BuildItem.objects.filter(build_line__build=build) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().stock_item, large) + self.assertEqual(allocs.first().quantity, 15) + + # ------------------------------------------------------------------ + # build_lines filtering + # ------------------------------------------------------------------ + + def test_build_lines_subset_only_allocates_selected_lines(self): + """When build_lines is specified only those lines are allocated.""" + build = self._create_build_two_lines() + + StockItem.objects.create(part=self.component, quantity=50) + StockItem.objects.create(part=self.component_b, quantity=50) + + line_a = build.build_lines.filter(bom_item__sub_part=self.component).first() + + self.post( + self._url(build.pk), + {'build_lines': [line_a.pk], 'interchangeable': True}, + expected_code=200, + ) + + alloc_a = BuildItem.objects.filter( + build_line__build=build, stock_item__part=self.component + ) + alloc_b = BuildItem.objects.filter( + build_line__build=build, stock_item__part=self.component_b + ) + + self.assertTrue(alloc_a.exists()) + self.assertFalse(alloc_b.exists()) + + def test_build_lines_empty_allocates_all(self): + """When build_lines is omitted, all untracked lines are allocated.""" + build = self._create_build_two_lines() + + StockItem.objects.create(part=self.component, quantity=50) + StockItem.objects.create(part=self.component_b, quantity=50) + + self.post(self._url(build.pk), {'interchangeable': True}, expected_code=200) + + alloc_a = BuildItem.objects.filter( + build_line__build=build, stock_item__part=self.component + ) + alloc_b = BuildItem.objects.filter( + build_line__build=build, stock_item__part=self.component_b + ) + + self.assertTrue(alloc_a.exists()) + self.assertTrue(alloc_b.exists()) + + # ------------------------------------------------------------------ + # Variant stock / sort priority + # ------------------------------------------------------------------ + + def test_direct_match_preferred_over_variant_stock(self): + """Direct part matches are allocated ahead of variant stock (sort priority 1 vs 2).""" + build = self._make_build(quantity=5) + + bom_item = BomItem.objects.get(part=self.assembly, sub_part=self.component) + bom_item.allow_variants = True + bom_item.save() + + self.component.is_template = True + self.component.save() + + variant = Part.objects.create( + name='AutoAlloc Component Variant', + description='', + component=True, + variant_of=self.component, + ) + + direct_stock = StockItem.objects.create(part=self.component, quantity=5) + StockItem.objects.create(part=variant, quantity=100) + + self.post(self._url(build.pk), {'interchangeable': True}, expected_code=200) + + allocs = BuildItem.objects.filter(build_line__build=build) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().stock_item, direct_stock) + + # ------------------------------------------------------------------ + # Location filtering + # ------------------------------------------------------------------ + + def test_location_filters_allocation(self): + """The 'location' filter restricts allocation to stock within that location.""" + build = self._make_build(quantity=5) + + in_location = StockItem.objects.create( + part=self.component, quantity=5, location=self.loc_a + ) + StockItem.objects.create(part=self.component, quantity=100, location=self.loc_b) + + self.post( + self._url(build.pk), + {'location': self.loc_a.pk, 'interchangeable': True}, + expected_code=200, + ) + + allocs = BuildItem.objects.filter(build_line__build=build) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().stock_item, in_location) + + def test_exclude_location_filters_allocation(self): + """The 'exclude_location' filter excludes stock within that location.""" + build = self._make_build(quantity=5) + + StockItem.objects.create(part=self.component, quantity=100, location=self.loc_a) + allowed = StockItem.objects.create( + part=self.component, quantity=5, location=self.loc_b + ) + + self.post( + self._url(build.pk), + {'exclude_location': self.loc_a.pk, 'interchangeable': True}, + expected_code=200, + ) + + allocs = BuildItem.objects.filter(build_line__build=build) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().stock_item, allowed) + + # ------------------------------------------------------------------ + # Large number of build lines (performance / bulk allocation) + # ------------------------------------------------------------------ + + def test_many_build_lines_allocated_correctly(self): + """A build with 100 BOM lines, each with sufficient dedicated stock, is fully auto-allocated. + + This test is a performance benchmark for the auto-allocate endpoint, + to ensure that auto-allocating 100x items does not cause an excessive amount of DB hits. + """ + assembly = Part.objects.create( + name='AutoAlloc Big Assembly', description='', assembly=True + ) + build = Build.objects.create( + part=assembly, + reference=f'BO-{9000 + Build.objects.count():04d}', + quantity=10, + ) + + components = [ + Part.objects.create( + name=f'AutoAlloc Bulk Component {i}', + description='', + component=True, + tree_id=0, + level=0, + lft=0, + rght=0, + ) + for i in range(100) + ] + + # Create BomItem for each component, and a stock item with sufficient quantity to cover the build + bom_items = [ + BomItem(part=assembly, sub_part=component, quantity=13) + for component in components + ] + + BomItem.objects.bulk_create(bom_items) + + # Create multiple stock items for each component, with a total sufficient stock to fulfil each line + stock_items = [] + + for _i in range(4): + for component in components: + # Total of 160 stock for each component + stock_items.append(StockItem(part=component, quantity=40)) + + StockItem.objects.bulk_create(stock_items) + + build.create_build_line_items() + + self.assertEqual(build.build_lines.count(), 100) + + self.post( + self._url(build.pk), + {'interchangeable': True}, + expected_code=200, + benchmark=True, + max_query_count=150, + ) + + allocs = BuildItem.objects.filter(build_line__build=build) + + # Every line should have received exactly one allocation, covering the full requirement. + self.assertEqual(allocs.count(), 400) + + for component in components: + fa = allocs.filter(stock_item__part=component) + self.assertEqual(fa.count(), 4) + allocated = sum(a.quantity for a in fa) + self.assertEqual(allocated, 130) # 130 allocated to each line diff --git a/src/backend/InvenTree/build/test_build.py b/src/backend/InvenTree/build/test_build.py index 5c571252ec..2fd09cfd54 100644 --- a/src/backend/InvenTree/build/test_build.py +++ b/src/backend/InvenTree/build/test_build.py @@ -1,12 +1,17 @@ """Unit tests for the 'build' models.""" +import threading +import time import uuid from datetime import datetime, timedelta +from unittest import mock from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.core.exceptions import ValidationError +from django.db import connection, transaction from django.db.models import Sum +from django.test import TransactionTestCase, skipUnlessDBFeature from django.test.utils import override_settings from django.urls import reverse @@ -26,7 +31,12 @@ from InvenTree.unit_test import ( ) from order.models import PurchaseOrder, PurchaseOrderLineItem from part.models import BomItem, BomItemSubstitute, Part, PartTestTemplate -from stock.models import StockItem, StockItemTestResult, StockLocation +from stock.models import ( + StockItem, + StockItemTestResult, + StockItemTracking, + StockLocation, +) from stock.status_codes import StockStatus from users.models import Owner @@ -473,6 +483,8 @@ class BuildTest(BuildTestBase): self.build.complete_build(None) + # The status is updated by the (synchronous, in tests) background task + self.build.refresh_from_db() self.assertEqual(self.build.status, status.BuildStatus.COMPLETE) # Check stock items are in expected state. @@ -527,15 +539,14 @@ class BuildTest(BuildTestBase): # Return a partial quantity of each item to stock for item in consumed_items: - self.assertEqual(item.get_descendant_count(), 0) q = item.quantity self.assertGreater(item.quantity, 1) item.return_to_stock(location, merge=False, quantity=1) item.refresh_from_db() self.assertEqual(item.quantity, q - 1) - self.assertEqual(item.get_descendant_count(), 1) + self.assertEqual(item.children.count(), 1) self.assertFalse(item.is_in_stock()) - child = item.get_descendants().first() + child = item.children.first() self.assertTrue(child.is_in_stock()) def test_change_part(self): @@ -582,6 +593,40 @@ class BuildTest(BuildTestBase): initial_output_count, ) + def test_cancel_stale_instance_is_noop(self): + """A second cancellation attempt with a stale build instance must be a no-op. + + Regression test: _action_cancel() offloaded the cancellation task + unconditionally, using no idempotency check at all, so two concurrent + cancellation requests (each holding its own instance of the build) could + both offload the cancellation task (duplicate events and notifications). + The status is now re-read (under lock) from the database, and a build + which is already cancelled is skipped. + """ + self.build.issue_build() + self.allocate_stock(None, {self.stock_1_2: 50}) + + # Two "concurrent" requests each hold their own instance of the build + build_a = Build.objects.get(pk=self.build.pk) + build_b = Build.objects.get(pk=self.build.pk) + + build_a.cancel_build(None) + + self.build.refresh_from_db() + self.assertEqual(self.build.status, status.BuildStatus.CANCELLED) + + # The second (stale) instance still believes the build is in production - + # cancellation must be skipped based on the database state + self.assertEqual(build_b.status, status.BuildStatus.PRODUCTION) + + with self.assertRaises(ValidationError) as err: + build_b.cancel_build(None) + + self.assertIn('Build Order is already Cancelled', str(err.exception)) + + self.build.refresh_from_db() + self.assertEqual(self.build.status, status.BuildStatus.CANCELLED) + def test_complete(self): """Test completion of a build output.""" self.stock_1_1.quantity = 1000 @@ -622,6 +667,8 @@ class BuildTest(BuildTestBase): self.build.complete_build(None) + # The status is updated by the (synchronous, in tests) background task + self.build.refresh_from_db() self.assertEqual(self.build.status, status.BuildStatus.COMPLETE) # the original BuildItem objects should have been deleted! @@ -643,6 +690,178 @@ class BuildTest(BuildTestBase): for output in outputs: self.assertFalse(output.is_building) + def test_complete_output_stale_build_instance(self): + """The 'completed' count is incremented atomically at the database level. + + Simulates two concurrent processes completing different outputs of the + same build, each holding its own (stale) copy of the Build instance. + """ + self.stock_1_1.quantity = 1000 + self.stock_1_1.save() + + self.stock_2_1.quantity = 30 + self.stock_2_1.save() + + self.build.issue_build() + + # Allocate non-tracked parts + self.allocate_stock( + None, + { + self.stock_1_1: self.stock_1_1.quantity, + self.stock_1_2: 10, + self.stock_2_1: 30, + }, + ) + + # Allocate tracked parts against each output + self.allocate_stock(self.output_1, {self.stock_3_1: 6}) + self.allocate_stock(self.output_2, {self.stock_3_1: 14}) + + # Two independent in-memory copies of the same build + build_a = Build.objects.get(pk=self.build.pk) + build_b = Build.objects.get(pk=self.build.pk) + + build_a.complete_build_output(self.output_1, None) + build_b.complete_build_output(self.output_2, None) + + # Both completions must be counted + self.build.refresh_from_db() + self.assertEqual(self.build.completed, 10) + + def test_complete_allocations_sums_consumed(self): + """Completing multiple allocations against one BuildLine sums the consumed count. + + (Concurrent completions are serialized by the Build row lock inside + complete_allocations, so only the sequential arithmetic is tested here.) + """ + self.build.issue_build() + + self.allocate_stock(None, {self.stock_1_1: 3, self.stock_1_2: 5}) + + self.build.complete_allocations( + BuildItem.objects.filter(build_line=self.line_1), user=self.user + ) + + # Both consumed quantities must be counted + self.line_1.refresh_from_db() + self.assertEqual(self.line_1.consumed, 8) + + def test_complete_allocation_wrapper(self): + """BuildItem.complete_allocation() is a thin wrapper around Build.complete_allocations(). + + Regression test: complete_allocation() was removed when complete_allocations() was + introduced, but some call sites still complete a single BuildItem at a time. + """ + self.build.issue_build() + + self.allocate_stock(None, {self.stock_1_1: 3}) + alloc = BuildItem.objects.get(build_line=self.line_1, stock_item=self.stock_1_1) + + alloc.complete_allocation(user=self.user) + + self.stock_1_1.refresh_from_db() + self.line_1.refresh_from_db() + + self.assertEqual(self.stock_1_1.consumed_by, self.build) + self.assertEqual(self.line_1.consumed, 3) + self.assertFalse(BuildItem.objects.filter(pk=alloc.pk).exists()) + + def test_complete_zero_quantity_allocation(self): + """A zero-quantity allocation is skipped cleanly on completion. + + Regression test: completing a BuildItem with quantity=0 (permitted by + the model validators) crashed, blocking build completion until the + empty allocation was manually removed. + """ + self.build.issue_build() + + # An allocation with zero quantity, against an item with stock available + alloc = BuildItem.objects.create( + build_line=self.line_1, stock_item=self.stock_1_2, quantity=0 + ) + + n_items = StockItem.objects.count() + + # Completing the allocation must not crash, and performs no stock operations + self.build.complete_allocations( + BuildItem.objects.filter(pk=alloc.pk), user=self.user + ) + + self.assertEqual(StockItem.objects.count(), n_items) + + self.stock_1_2.refresh_from_db() + self.assertEqual(self.stock_1_2.quantity, 100) + self.assertIsNone(self.stock_1_2.consumed_by) + + self.line_1.refresh_from_db() + self.assertEqual(self.line_1.consumed, 0) + + alloc.delete() + + # An allocation whose stock item has been depleted elsewhere + # is also skipped cleanly (allocated quantity clamps to zero) + depleted = StockItem.objects.create( + part=self.sub_part_1, quantity=5, delete_on_deplete=False + ) + alloc = BuildItem.objects.create( + build_line=self.line_1, stock_item=depleted, quantity=5 + ) + + depleted.take_stock(5, self.user) + depleted.refresh_from_db() + self.assertEqual(depleted.quantity, 0) + + self.build.complete_allocations( + BuildItem.objects.filter(pk=alloc.pk), user=self.user + ) + + depleted.refresh_from_db() + self.assertIsNone(depleted.consumed_by) + + self.line_1.refresh_from_db() + self.assertEqual(self.line_1.consumed, 0) + + def test_complete_allocation_stale_item_instance(self): + """complete_allocation() must not clamp/split using a stale stock_item.quantity. + + Regression test: the allocated quantity was clamped, and the choice between + consuming the item directly versus splitting off a portion of it, was made + using self.stock_item.quantity as cached in memory on the BuildItem. If a + concurrent operation reduced the stock item's quantity after the BuildItem + was loaded, the stale value could select the "split" branch when only the + entire (now-reduced) item is actually available - causing splitStock() to + reject the now-oversized split. The stock item's row is now locked and its + quantity refreshed before the clamp/split decision is made. + """ + self.build.issue_build() + + # A partial allocation - less than the full stock item quantity + alloc = BuildItem.objects.create( + build_line=self.line_1, stock_item=self.stock_1_2, quantity=60 + ) + + # Load a second copy of the allocation, caching the stock item's original quantity + stale_alloc = BuildItem.objects.get(pk=alloc.pk) + self.assertEqual(stale_alloc.stock_item.quantity, 100) + + # Reduce the available stock *after* the stale copy was loaded + # (simulating a concurrent stock adjustment elsewhere) + self.stock_1_2.quantity = 40 + self.stock_1_2.save() + + # Completing the (stale) allocation must not raise, and must consume only + # the quantity which is actually available + stale_alloc.complete_allocation(user=self.user) + + self.stock_1_2.refresh_from_db() + self.line_1.refresh_from_db() + + # The entire (now-reduced) item is consumed directly - no split occurs + self.assertEqual(self.stock_1_2.quantity, 40) + self.assertEqual(self.stock_1_2.consumed_by, self.build) + self.assertEqual(self.line_1.consumed, 40) + def test_complete_with_required_tests(self): """Test the prevention completion when a required test is missing feature.""" # with required tests incompleted the save should fail @@ -650,11 +869,15 @@ class BuildTest(BuildTestBase): 'PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS', True, change_user=None ) - with self.assertRaises(ValidationError): + with self.assertRaises(ValidationError) as exc: self.build_w_tests_trackable.complete_build_output( self.stockitem_with_required_test, None ) + self.assertIn( + 'Build output has not passed all required tests', str(exc.exception) + ) + # let's complete the required test and see if it could be saved StockItemTestResult.objects.create( stock_item=self.stockitem_with_required_test, @@ -671,6 +894,59 @@ class BuildTest(BuildTestBase): self.stockitem_wo_required_test, None ) + def test_complete_output_still_in_production(self): + """Test that a build output cannot be completed if allocated stock is still in production.""" + # Create a stock item of the tracked sub-part, which is itself still "in production" + sub_build = Build.objects.create( + reference=generate_next_build_reference(), + title='Building a sub-part', + part=self.sub_part_3, + quantity=2, + issued_by=get_user_model().objects.get(pk=1), + ) + + in_production = StockItem.objects.create( + part=self.sub_part_3, quantity=2, is_building=True, build=sub_build + ) + + self.allocate_stock(self.output_1, {in_production: 2}) + + with self.assertRaises(ValidationError) as exc: + self.build.complete_build_output(self.output_1, None) + + self.assertIn( + 'Allocated stock items are still in production', str(exc.exception) + ) + + def test_partial_complete_with_allocated_items(self): + """Test that a build output with tracked allocations cannot be partially completed.""" + # Allocate tracked stock against output_1 (quantity=3) + self.allocate_stock(self.output_1, {self.stock_3_1: 6}) + + with self.assertRaises(ValidationError) as exc: + self.build.complete_build_output(self.output_1, None, quantity=1) + + self.assertIn( + 'Cannot partially complete a build output with allocated items', + str(exc.exception), + ) + + def test_complete_output_invalid_quantity(self): + """Test that invalid quantities are rejected when completing a build output directly.""" + with self.assertRaises(ValidationError) as exc: + self.build.complete_build_output(self.output_1, None, quantity=0) + + self.assertIn('Quantity must be greater than zero', str(exc.exception)) + + with self.assertRaises(ValidationError) as exc: + self.build.complete_build_output( + self.output_1, None, quantity=self.output_1.quantity + 1 + ) + + self.assertIn( + 'Quantity cannot be greater than the output quantity', str(exc.exception) + ) + def test_overdue_notification(self): """Test sending of notifications when a build order is overdue.""" self.ensurePluginsLoaded() @@ -904,11 +1180,8 @@ class AutoAllocationTests(BuildTestBase): self.assertEqual(self.line_1.allocations.count(), 2) self.assertEqual(self.line_2.allocations.count(), 6) - for item in self.line_1.allocations.all(): - item.complete_allocation() - - for item in self.line_2.allocations.all(): - item.complete_allocation() + self.build.complete_allocations(self.line_1.allocations.all()) + self.build.complete_allocations(self.line_2.allocations.all()) self.line_1.refresh_from_db() self.line_2.refresh_from_db() @@ -941,6 +1214,38 @@ class AutoAllocationTests(BuildTestBase): self.assertEqual(self.build.allocated_stock.count(), N - 8) + def test_consumable_via_part(self): + """A BOM line should be treated as consumable if the underlying part is consumable. + + Even though 'bom_item_1' itself is not marked as consumable, marking + 'sub_part_1' as consumable should have the same effect as marking the + BOM line itself as consumable. + """ + self.sub_part_1.consumable = True + self.sub_part_1.save() + + self.assertFalse(self.bom_item_1.consumable) + self.assertTrue(self.bom_item_1.is_consumable) + + # The BuildLine should be treated as fully allocated, without any stock allocated + self.assertEqual(self.line_1.allocated_quantity(), 0) + self.assertTrue(self.line_1.is_fully_allocated()) + + # The build should not consider this line when checking for unallocated lines + unallocated_lines = self.build.unallocated_lines(tracked=False) + self.assertNotIn(self.line_1, unallocated_lines) + + # Auto-allocation should skip this line, even though stock exists + self.build.auto_allocate_stock( + interchangeable=True, substitutes=True, optional_items=True + ) + + self.assertEqual(self.line_1.allocated_quantity(), 0) + self.assertEqual(BuildItem.objects.filter(build_line=self.line_1).count(), 0) + + # The other (non-consumable) line should still be allocated as normal + self.assertEqual(self.line_2.allocated_quantity(), 30) + class ExternalBuildTest(InvenTreeAPITestCase): """Unit tests for external build order functionality.""" @@ -1073,6 +1378,9 @@ class ExternalBuildTest(InvenTreeAPITestCase): # Mark the build order as completed build.complete_build(self.user) + + # The status is updated by the (synchronous, in tests) background task + build.refresh_from_db() self.assertEqual(build.status, BuildStatus.COMPLETE) # Receive the rest of the line item @@ -1174,6 +1482,134 @@ class BuildTaskTests(BuildTestBase): self.build.complete_build_output(self.output_1, None) self.build.complete_build_output(self.output_2, None) + def test_complete_build_task_is_idempotent(self): + """A duplicated completion task run must be a no-op. + + Regression test: the completion task had no build lock and no status + re-check, so a redelivered (or double-enqueued) task re-ran the + completion side effects (duplicate COMPLETED event and notifications). + """ + from build.tasks import complete_build + + self._setup_complete_build() + self.build.complete_build(self.user) + + self.build.refresh_from_db() + self.assertEqual(self.build.status, BuildStatus.COMPLETE) + + n_consumed = StockItem.objects.filter(consumed_by=self.build).count() + n_tracking = StockItemTracking.objects.count() + + # A redelivered task run must skip based on the (locked) database state + with mock.patch('build.tasks.trigger_event') as trigger: + complete_build(self.build.pk, self.user.pk) + trigger.assert_not_called() + + self.assertEqual( + StockItem.objects.filter(consumed_by=self.build).count(), n_consumed + ) + self.assertEqual(StockItemTracking.objects.count(), n_tracking) + + def test_allocate_stock_merges_quantities(self): + """Repeated allocations against the same (line, stock item) accumulate. + + Regression test: allocate_stock() never added merged BuildItems to its + 'to_update' set, so allocating against an existing allocation silently + discarded the requested quantity. Duplicate entries within a single + request also overwrote (rather than summed) each other. + """ + self.build.issue_build() + + items = [ + {'build_line': self.line_1, 'stock_item': self.stock_1_2, 'quantity': 10} + ] + + self.build.allocate_stock(items) + + alloc = BuildItem.objects.get(build_line=self.line_1, stock_item=self.stock_1_2) + self.assertEqual(alloc.quantity, 10) + + # A second allocation against the same (line, stock item) merges quantities + self.build.allocate_stock(items) + + alloc.refresh_from_db() + self.assertEqual(alloc.quantity, 20) + + # Duplicate entries within a single request are also merged + self.build.allocate_stock([ + {'build_line': self.line_1, 'stock_item': self.stock_1_1, 'quantity': 1}, + {'build_line': self.line_1, 'stock_item': self.stock_1_1, 'quantity': 2}, + ]) + + alloc = BuildItem.objects.get(build_line=self.line_1, stock_item=self.stock_1_1) + self.assertEqual(alloc.quantity, 3) + + # ----------------------------------------------------------------------- + # complete_build_outputs / scrap_build_outputs tasks + # ----------------------------------------------------------------------- + + def test_complete_outputs_task_is_idempotent(self): + """Duplicate execution of the output completion task must not double-count. + + Regression test: the task never re-checked 'is_building', so a duplicated + (or redelivered) task run completed the same outputs twice - inflating the + 'completed' count for the build order and duplicating stock history. + """ + self.build.issue_build() + + outputs = [{'output_id': self.output_1.pk}, {'output_id': self.output_2.pk}] + + build.tasks.complete_build_outputs( + self.build.pk, + outputs, + self.location.pk, + StockStatus.OK.value, + user_id=self.user.pk, + ) + + self.build.refresh_from_db() + self.output_1.refresh_from_db() + + self.assertEqual(self.build.completed, 10) + self.assertFalse(self.output_1.is_building) + + n_tracking = StockItemTracking.objects.count() + + # Run the task again (simulating a duplicated / redelivered task) + build.tasks.complete_build_outputs( + self.build.pk, + outputs, + self.location.pk, + StockStatus.OK.value, + user_id=self.user.pk, + ) + + # The 'completed' count has not been double-counted, + # and no additional stock history has been generated + self.build.refresh_from_db() + self.assertEqual(self.build.completed, 10) + self.assertEqual(StockItemTracking.objects.count(), n_tracking) + + def test_complete_output_twice_rejected(self): + """Completing or scrapping an already-completed output must be rejected. + + Regression test: neither complete_build_output() nor scrap_build_output() + re-checked the 'is_building' state of the output. + """ + self.build.issue_build() + + self.build.complete_build_output(self.output_1, None) + + with self.assertRaises(ValidationError): + self.build.complete_build_output(self.output_1, None) + + with self.assertRaises(ValidationError): + self.build.scrap_build_output(self.output_1, None, self.location) + + # An output belonging to a *different* build order is also rejected + with self.assertRaises(ValidationError): + self.build.complete_build_output(self.stockitem_wo_required_test, None) + # ----------------------------------------------------------------------- # cancel_build task # ----------------------------------------------------------------------- @@ -1396,3 +1832,346 @@ class BuildTaskTests(BuildTestBase): self.assertFalse(output.is_building) # status=None should resolve to StockStatus.OK (the model default) self.assertEqual(output.status, StockStatus.OK.value) + + +@skipUnlessDBFeature('has_select_for_update') +class BuildTrimAllocatedStockConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for Build.trim_allocated_stock(). + + Uses two real threads (each with its own database connection) to reproduce + an actual overlapping-transaction race, rather than the "stale in-memory + instance" trick used elsewhere - trim_allocated_stock() always re-queries the + BuildItem rows fresh, so a stale Python object cannot reproduce this bug. + """ + + fixtures = ['users'] + + def setUp(self): + """Create a minimal build/allocation setup for the concurrency test.""" + super().setUp() + + self.user = get_user_model().objects.get(pk=1) + + self.assembly = Part.objects.create( + name='Concurrency assembly', + description='Assembly for trim_allocated_stock concurrency test', + assembly=True, + ) + self.sub_part = Part.objects.create( + name='Concurrency component', + description='Component for trim_allocated_stock concurrency test', + component=True, + ) + + BomItem.objects.create(part=self.assembly, sub_part=self.sub_part, quantity=1) + + self.build = Build.objects.create( + reference=generate_next_build_reference(), + part=self.assembly, + quantity=1, + issued_by=self.user, + ) + + self.build_line = BuildLine.objects.get(build=self.build) + + self.stock_item = StockItem.objects.create(part=self.sub_part, quantity=100) + + # Over-allocate: only 1 is required, but 10 have been allocated + self.build_item = BuildItem.objects.create( + build_line=self.build_line, stock_item=self.stock_item, quantity=10 + ) + + def test_trim_allocated_stock_does_not_lose_concurrent_allocation(self): + """trim_allocated_stock() must not lose a concurrent allocation update. + + Regression test: BuildItem rows were read via a plain (unlocked) queryset, + reduced in Python, and written back with bulk_update(). A concurrent request + that increased the same BuildItem's quantity (e.g. a new allocation, which + locks the row via select_for_update while saving - see + BuildAllocationSerializer) could commit in between the read and the write, + and would be silently discarded by the stale trim calculation. The + BuildItem rows are now locked (select_for_update) before being read, so + the trim always operates on the latest committed quantity. + """ + lock_acquired = threading.Event() + release_lock = threading.Event() + errors = [] + + def concurrent_allocation_increase(): + """Simulate a second request increasing the allocation. + + Holds a row-level lock on the BuildItem (as the real allocation + endpoint does) until told to proceed, so the trim thread below is + forced to block on the same row. + """ + try: + with transaction.atomic(): + item = BuildItem.objects.select_for_update().get( + pk=self.build_item.pk + ) + lock_acquired.set() + release_lock.wait(timeout=5) + item.quantity += 5 + item.save() + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + def run_trim(): + try: + self.build.trim_allocated_stock() + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + alloc_thread = threading.Thread(target=concurrent_allocation_increase) + alloc_thread.start() + + # Wait until the other thread holds the row lock + self.assertTrue(lock_acquired.wait(timeout=5)) + + trim_thread = threading.Thread(target=run_trim) + trim_thread.start() + + # Give the trim thread a moment to reach (and block on) the row lock + time.sleep(0.5) + + # Release the lock - the concurrent allocation increase commits first + release_lock.set() + + alloc_thread.join(timeout=5) + trim_thread.join(timeout=5) + + self.assertFalse(alloc_thread.is_alive()) + self.assertFalse(trim_thread.is_alive()) + self.assertEqual(errors, []) + + self.build_item.refresh_from_db() + + # The concurrent increase (+5, giving 15) must not have been lost: the + # trim reduces by 9 (10 originally allocated - 1 actually needed) from + # whatever is actually committed, leaving 15 - 9 = 6. A lost update + # would instead leave 15 (the trim's reduction discarded) or 1 (the + # concurrent increase discarded). + self.assertEqual(self.build_item.quantity, 6) + + +@skipUnlessDBFeature('has_select_for_update') +class BuildSubtractAllocatedStockConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for Build.complete_outstanding_allocations(). + + Uses two real threads (each with its own database connection) to reproduce + duplicated/overlapping execution - e.g. a redelivered 'complete_build' or + 'cancel_build' background task - which cannot be reproduced with a single + stale Python instance, since this method always re-queries the BuildItem + rows fresh. + """ + + fixtures = ['users'] + + def setUp(self): + """Create a minimal build/allocation setup for the concurrency test.""" + super().setUp() + + self.user = get_user_model().objects.get(pk=1) + + self.assembly = Part.objects.create( + name='Concurrency assembly 2', + description='Assembly for subtract_allocated_stock concurrency test', + assembly=True, + ) + self.sub_part = Part.objects.create( + name='Concurrency component 2', + description='Component for subtract_allocated_stock concurrency test', + component=True, + ) + + BomItem.objects.create(part=self.assembly, sub_part=self.sub_part, quantity=1) + + self.build = Build.objects.create( + reference=generate_next_build_reference(), + part=self.assembly, + quantity=1, + issued_by=self.user, + ) + + self.build_line = BuildLine.objects.get(build=self.build) + + self.stock_item = StockItem.objects.create(part=self.sub_part, quantity=10) + + self.build_item = BuildItem.objects.create( + build_line=self.build_line, stock_item=self.stock_item, quantity=10 + ) + + def test_subtract_allocated_stock_is_not_processed_twice(self): + """A duplicated/concurrent call to complete_outstanding_allocations() must not double-consume. + + Regression test: BuildItem allocation rows were read via a plain (unlocked) + queryset before being consumed and deleted. Two overlapping calls to this + method (e.g. a redelivered completion/cancellation background task) could + each read the same still-existing allocation and both call + complete_allocation() on it - double-counting the BuildLine's 'consumed' + quantity. The BuildItem rows are now locked (select_for_update) before + being processed, so a duplicate call finds nothing left to do. + """ + start_barrier = threading.Barrier(2, timeout=5) + errors = [] + + def run_subtract(): + try: + start_barrier.wait() + self.build.complete_outstanding_allocations(self.user) + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + thread_a = threading.Thread(target=run_subtract) + thread_b = threading.Thread(target=run_subtract) + + thread_a.start() + thread_b.start() + + thread_a.join(timeout=5) + thread_b.join(timeout=5) + + self.assertFalse(thread_a.is_alive()) + self.assertFalse(thread_b.is_alive()) + self.assertEqual(errors, []) + + self.build_line.refresh_from_db() + + # The allocation must only have been consumed once, no matter which + # thread "won" the race for the row lock + self.assertEqual(self.build_line.consumed, 10) + self.assertFalse(BuildItem.objects.filter(pk=self.build_item.pk).exists()) + + +@skipUnlessDBFeature('has_select_for_update') +class BuildAllocateStockConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for Build.allocate_stock(). + + Uses two real threads (each with its own database connection) to reproduce + the reported race: two concurrent allocation requests, against two + different Builds but the *same* StockItem, could each read the item's + unallocated quantity before either had committed, and both create a + BuildItem for the full quantity - over-allocating the StockItem. Because + the requests target different Builds, the pre-existing Build-row lock + does not serialize them. + + allocate_stock() now locks the referenced StockItem (select_for_update, + via StockItem.lock_quantity()) and re-validates the unallocated quantity + under that lock before writing, so only one of two concurrent + full-quantity allocation requests against a shared StockItem may succeed. + """ + + fixtures = ['users'] + + def setUp(self): + """Create two Builds which both require the same shared StockItem.""" + super().setUp() + + self.user = get_user_model().objects.get(pk=1) + + self.assembly_a = Part.objects.create( + name='Concurrency assembly A', + description='Assembly for allocate_stock concurrency test', + assembly=True, + ) + self.assembly_b = Part.objects.create( + name='Concurrency assembly B', + description='Assembly for allocate_stock concurrency test', + assembly=True, + ) + self.sub_part = Part.objects.create( + name='Shared concurrency component', + description='Component for allocate_stock concurrency test', + component=True, + ) + + BomItem.objects.create(part=self.assembly_a, sub_part=self.sub_part, quantity=1) + BomItem.objects.create(part=self.assembly_b, sub_part=self.sub_part, quantity=1) + + self.build_a = Build.objects.create( + reference=generate_next_build_reference(), + part=self.assembly_a, + quantity=1, + issued_by=self.user, + ) + self.build_b = Build.objects.create( + reference=generate_next_build_reference(), + part=self.assembly_b, + quantity=1, + issued_by=self.user, + ) + + self.build_line_a = BuildLine.objects.get(build=self.build_a) + self.build_line_b = BuildLine.objects.get(build=self.build_b) + + # Only enough stock for *one* of the two full-quantity allocations below + self.stock_item = StockItem.objects.create(part=self.sub_part, quantity=5) + + def test_concurrent_allocation_does_not_over_allocate(self): + """Two concurrent full-quantity allocation requests must not both succeed.""" + start_barrier = threading.Barrier(2, timeout=5) + errors = [] + results = [] + + # Wrap StockItem.lock_quantity() so both threads reach the (real, + # database-level) row lock at the same time - one wins the lock and + # proceeds, the other blocks until the winner's transaction completes. + original_lock_quantity = StockItem.lock_quantity + + def synced_lock_quantity(self_item): + start_barrier.wait(timeout=5) + return original_lock_quantity(self_item) + + def allocate(build, build_line): + try: + build.allocate_stock([ + { + 'build_line': build_line, + 'stock_item': self.stock_item, + 'quantity': 5, + } + ]) + results.append('ok') + except ValidationError: + results.append('rejected') + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + thread_a = threading.Thread( + target=allocate, args=(self.build_a, self.build_line_a) + ) + thread_b = threading.Thread( + target=allocate, args=(self.build_b, self.build_line_b) + ) + + with mock.patch.object(StockItem, 'lock_quantity', synced_lock_quantity): + thread_a.start() + thread_b.start() + + thread_a.join(timeout=5) + thread_b.join(timeout=5) + + self.assertFalse(thread_a.is_alive()) + self.assertFalse(thread_b.is_alive()) + self.assertEqual(errors, []) + + # Exactly one request must have been rejected as over-allocating + self.assertEqual(sorted(results), ['ok', 'rejected']) + + total_allocated = ( + BuildItem.objects.filter(stock_item=self.stock_item).aggregate( + q=Sum('quantity') + )['q'] + or 0 + ) + + self.assertEqual(total_allocated, 5) + self.assertLessEqual(total_allocated, self.stock_item.quantity) diff --git a/src/backend/InvenTree/build/validators.py b/src/backend/InvenTree/build/validators.py index a4213c8750..28279dc798 100644 --- a/src/backend/InvenTree/build/validators.py +++ b/src/backend/InvenTree/build/validators.py @@ -21,3 +21,13 @@ def validate_build_order_reference(value): # If we get to here, run the "default" validation routine Build.validate_reference_field(value) + + +def check_build_output(output, quantity=None): + """Run a validation check against each output before accepting it for completion. + + Arguments: + output (StockItem): The build output to check + quantity (Decimal, optional): The quantity to complete. If None, the full output quantity is assumed. + """ + output.build.can_complete_output(output, quantity=quantity) diff --git a/src/backend/InvenTree/common/admin.py b/src/backend/InvenTree/common/admin.py index 5703423afc..00db4a66d1 100644 --- a/src/backend/InvenTree/common/admin.py +++ b/src/backend/InvenTree/common/admin.py @@ -10,7 +10,7 @@ import common.validators class ParameterTemplateAdmin(admin.ModelAdmin): """Admin interface for ParameterTemplate objects.""" - list_display = ('name', 'description', 'model_type', 'units') + list_display = ('name', 'description', 'model_type', 'units', 'unique') search_fields = ('name', 'description') @@ -79,27 +79,44 @@ class AttachmentAdmin(admin.ModelAdmin): @admin.register(common.models.DataOutput) class DataOutputAdmin(admin.ModelAdmin): - """Admin interface for DataOutput objects.""" + """Admin interface for DataOutput objects - view and delete only.""" list_display = ('user', 'created', 'output_type', 'output') list_filter = ('user', 'output_type') + def has_add_permission(self, request): + """Prevent addition of new DataOutput objects via the admin interface.""" + return False + + def has_change_permission(self, request, obj=None): + """Prevent modification of DataOutput objects via the admin interface.""" + return False + @admin.register(common.models.BarcodeScanResult) class BarcodeScanResultAdmin(admin.ModelAdmin): - """Admin interface for BarcodeScanResult objects.""" + """Admin interface for BarcodeScanResult objects - read-only audit log.""" list_display = ('data', 'timestamp', 'user', 'endpoint', 'result') list_filter = ('user', 'endpoint', 'result') + def has_add_permission(self, request): + """Prevent addition of new BarcodeScanResult objects via the admin interface.""" + return False + + def has_change_permission(self, request, obj=None): + """Prevent modification of BarcodeScanResult objects via the admin interface.""" + return False + @admin.register(common.models.ProjectCode) class ProjectCodeAdmin(admin.ModelAdmin): """Admin settings for ProjectCode.""" - list_display = ('code', 'description') + list_display = ('code', 'description', 'active') + list_filter = ('active',) search_fields = ('code', 'description') @@ -139,14 +156,22 @@ class WebhookAdmin(admin.ModelAdmin): @admin.register(common.models.NotificationEntry) class NotificationEntryAdmin(admin.ModelAdmin): - """Admin settings for NotificationEntry.""" + """Admin settings for NotificationEntry - view and delete only.""" list_display = ('key', 'uid', 'updated') + def has_add_permission(self, request): + """Prevent addition of new NotificationEntry objects via the admin interface.""" + return False + + def has_change_permission(self, request, obj=None): + """Prevent modification of NotificationEntry objects via the admin interface.""" + return False + @admin.register(common.models.NotificationMessage) class NotificationMessageAdmin(admin.ModelAdmin): - """Admin settings for NotificationMessage.""" + """Admin settings for NotificationMessage - view and delete only.""" list_display = ( 'age_human', @@ -162,14 +187,46 @@ class NotificationMessageAdmin(admin.ModelAdmin): search_fields = ('name', 'category', 'message') + def has_add_permission(self, request): + """Prevent addition of new NotificationMessage objects via the admin interface.""" + return False + + def has_change_permission(self, request, obj=None): + """Prevent modification of NotificationMessage objects via the admin interface.""" + return False + @admin.register(common.models.NewsFeedEntry) class NewsFeedEntryAdmin(admin.ModelAdmin): - """Admin settings for NewsFeedEntry.""" + """Admin settings for NewsFeedEntry - view and delete only.""" list_display = ('title', 'author', 'published', 'summary') + def has_add_permission(self, request): + """Prevent addition of new NewsFeedEntry objects via the admin interface.""" + return False -admin.site.register(common.models.WebhookMessage, admin.ModelAdmin) -admin.site.register(common.models.EmailMessage, admin.ModelAdmin) -admin.site.register(common.models.EmailThread, admin.ModelAdmin) + def has_change_permission(self, request, obj=None): + """Prevent modification of NewsFeedEntry objects via the admin interface.""" + return False + + +class ReadOnlyAdmin(admin.ModelAdmin): + """Base admin class that prevents all modifications.""" + + def has_add_permission(self, request): + """Prevent addition of new objects via the admin interface.""" + return False + + def has_change_permission(self, request, obj=None): + """Prevent modification of objects via the admin interface.""" + return False + + def has_delete_permission(self, request, obj=None): + """Prevent deletion of objects via the admin interface.""" + return False + + +admin.site.register(common.models.WebhookMessage, ReadOnlyAdmin) +admin.site.register(common.models.EmailMessage, ReadOnlyAdmin) +admin.site.register(common.models.EmailThread, ReadOnlyAdmin) diff --git a/src/backend/InvenTree/common/api.py b/src/backend/InvenTree/common/api.py index 2f3d0b59f2..885d3efd69 100644 --- a/src/backend/InvenTree/common/api.py +++ b/src/backend/InvenTree/common/api.py @@ -36,6 +36,7 @@ from rest_framework.permissions import IsAdminUser, IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView from sql_util.utils import SubqueryCount +from taggit.models import Tag import common.filters import common.models @@ -53,6 +54,7 @@ from InvenTree.api import ( BulkDeleteViewsetMixin, GenericMetadataView, SimpleGenericMetadataView, + meta_path, ) from InvenTree.config import CONFIG_LOOKUPS from InvenTree.filters import ORDER_FILTER, SEARCH_ORDER_FILTER @@ -477,9 +479,7 @@ class NotesImageList(ListCreateAPI): def perform_create(self, serializer): """Create (upload) a new notes image.""" - image = serializer.save() - image.user = self.request.user - image.save() + serializer.save(user=self.request.user) class ProjectCodeList(DataExportViewMixin, ListCreateAPI): @@ -491,7 +491,7 @@ class ProjectCodeList(DataExportViewMixin, ListCreateAPI): filter_backends = SEARCH_ORDER_FILTER ordering_fields = ['code'] - + filterset_fields = ['active'] search_fields = ['code', 'description'] @@ -503,6 +503,48 @@ class ProjectCodeDetail(RetrieveUpdateDestroyAPI): permission_classes = [IsStaffOrReadOnlyScope] +class TagFilter(FilterSet): + """Custom filters for the TagList API endpoint.""" + + class Meta: + """Metaclass options for the filterset.""" + + model = Tag + fields = [] + + model_type = rest_filters.CharFilter(method='filter_model_type', label='Model Type') + + def filter_model_type(self, queryset, name, value): + """Filter to tags which have been applied to the given model type.""" + ct = common.filters.determine_content_type(value) + + if ct is None: + raise ValidationError({'model_type': f'Invalid model type: {value}'}) + + return queryset.filter(taggit_taggeditem_items__content_type=ct).distinct() + + +class TagMixin: + """Mixin class for Tag views.""" + + serializer_class = common.serializers.TagSerializer + queryset = Tag.objects.all() + permission_classes = [IsStaffOrReadOnlyScope] + + +class TagList(TagMixin, ListCreateAPI): + """List view for all tags.""" + + filterset_class = TagFilter + filter_backends = SEARCH_ORDER_FILTER + ordering_fields = ['name'] + search_fields = ['name'] + + +class TagDetail(TagMixin, RetrieveUpdateDestroyAPI): + """Detail view for a particular tag.""" + + class CustomUnitViewset(DataExportViewMixin, viewsets.ModelViewSet): """List view for custom units.""" @@ -535,7 +577,7 @@ class CustomUnitViewset(DataExportViewMixin, viewsets.ModelViewSet): return { 'name': k, 'is_alias': reg.get_name(k) == k, - 'compatible_units': [str(a) for a in unit.compatible_units()], + 'compatible_units': [str(a) for a in unit.compatible_units()], # ty:ignore[missing-argument] 'isdimensionless': unit.dimensionless, } @@ -744,6 +786,8 @@ class AttachmentFilter(FilterSet): return queryset.exclude(attachment=None).exclude(attachment='') return queryset.filter(Q(attachment=None) | Q(attachment='')).distinct() + tags = common.filters.TagsFilter() + class AttachmentMixin: """Mixin class for Attachment views.""" @@ -764,9 +808,7 @@ class AttachmentList(AttachmentMixin, BulkDeleteMixin, ListCreateAPI): def perform_create(self, serializer): """Save the user information when a file is uploaded.""" - attachment = serializer.save() - attachment.upload_user = self.request.user - attachment.save() + serializer.save(upload_user=self.request.user) def validate_delete(self, queryset, request) -> None: """Ensure that the user has correct permissions for a bulk-delete. @@ -835,7 +877,7 @@ class ParameterTemplateFilter(FilterSet): """Metaclass options.""" model = common.models.ParameterTemplate - fields = ['name', 'units', 'checkbox', 'enabled'] + fields = ['name', 'units', 'checkbox', 'enabled', 'unique'] has_choices = rest_filters.BooleanFilter( method='filter_has_choices', label='Has Choice' @@ -1161,29 +1203,25 @@ class IconList(ListAPI): return list(get_icon_packs().values()) -class SelectionListList(ListCreateAPI): +class SelectionListMixin(OutputOptionsMixin): + """Mixin for SelectionList views.""" + + queryset = common.models.SelectionList.objects.all() + serializer_class = common.serializers.SelectionListSerializer + permission_classes = [IsAuthenticatedOrReadScope] + + def get_queryset(self): + """Override the queryset method to include entry count.""" + return self.serializer_class.annotate_queryset(super().get_queryset()) + + +class SelectionListList(SelectionListMixin, ListCreateAPI): """List view for SelectionList objects.""" - queryset = common.models.SelectionList.objects.all() - serializer_class = common.serializers.SelectionListSerializer - permission_classes = [IsAuthenticatedOrReadScope] - def get_queryset(self): - """Override the queryset method to include entry count.""" - return self.serializer_class.annotate_queryset(super().get_queryset()) - - -class SelectionListDetail(RetrieveUpdateDestroyAPI): +class SelectionListDetail(SelectionListMixin, RetrieveUpdateDestroyAPI): """Detail view for a SelectionList object.""" - queryset = common.models.SelectionList.objects.all() - serializer_class = common.serializers.SelectionListSerializer - permission_classes = [IsAuthenticatedOrReadScope] - - def get_queryset(self): - """Override the queryset method to include entry count.""" - return self.serializer_class.annotate_queryset(super().get_queryset()) - class EntryMixin: """Mixin for SelectionEntry views.""" @@ -1200,6 +1238,12 @@ class EntryMixin: queryset = queryset.prefetch_related('list') return queryset + def perform_destroy(self, instance): + """Prevent deletion of entries belonging to a locked selection list.""" + if instance.list.locked: + raise PermissionDenied(_('Selection list is locked')) + super().perform_destroy(instance) + class SelectionEntryList(EntryMixin, ListCreateAPI): """List view for SelectionEntry objects.""" @@ -1357,6 +1401,7 @@ class ObservabilityEndSerializer(serializers.Serializer): class ObservabilityEnd(CreateAPI): """Endpoint for observability tools.""" + # Note: This endpoint can be called anonymously, as it needs to function before the user is authenticated (e.g. during login) permission_classes = [AllowAnyOrReadScope] serializer_class = ObservabilityEndSerializer @@ -1476,7 +1521,13 @@ common_api_urls = [ path( 'attachment/', include([ - path('/', AttachmentDetail.as_view(), name='api-attachment-detail'), + path( + '/', + include([ + meta_path(common.models.Attachment), + path('', AttachmentDetail.as_view(), name='api-attachment-detail'), + ]), + ), path('', AttachmentList.as_view(), name='api-attachment-list'), ]), ), @@ -1489,8 +1540,14 @@ common_api_urls = [ include([ path( '/', - ParameterTemplateDetail.as_view(), - name='api-parameter-template-detail', + include([ + meta_path(common.models.ParameterTemplate), + path( + '', + ParameterTemplateDetail.as_view(), + name='api-parameter-template-detail', + ), + ]), ), path( '', @@ -1499,7 +1556,13 @@ common_api_urls = [ ), ]), ), - path('/', ParameterDetail.as_view(), name='api-parameter-detail'), + path( + '/', + include([ + meta_path(common.models.Parameter), + path('', ParameterDetail.as_view(), name='api-parameter-detail'), + ]), + ), path('', ParameterList.as_view(), name='api-parameter-list'), ]), ), @@ -1524,11 +1587,25 @@ common_api_urls = [ 'project-code/', include([ path( - '/', ProjectCodeDetail.as_view(), name='api-project-code-detail' + '/', + include([ + meta_path(common.models.ProjectCode), + path( + '', ProjectCodeDetail.as_view(), name='api-project-code-detail' + ), + ]), ), path('', ProjectCodeList.as_view(), name='api-project-code-list'), ]), ), + # Tags (via django-taggit) + path( + 'tag/', + include([ + path('/', TagDetail.as_view(), name='api-tag-detail'), + path('', TagList.as_view(), name='api-tag-list'), + ]), + ), # Flags path( 'flags/', diff --git a/src/backend/InvenTree/common/currency.py b/src/backend/InvenTree/common/currency.py index adb3b55cff..ca936c6e2d 100644 --- a/src/backend/InvenTree/common/currency.py +++ b/src/backend/InvenTree/common/currency.py @@ -162,13 +162,21 @@ def currency_exchange_plugins() -> Optional[list]: def get_price( instance, quantity, - moq=True, - multiples=True, - currency=None, + moq: bool = True, + multiples: bool = True, + currency: Optional[str] = None, break_name: str = 'price_breaks', ): """Calculate the price based on quantity price breaks. + Arguments: + instance: The model instance which contains the price break information + quantity: The quantity to calculate the price for + moq: If True, then minimum order quantity will be observed (CURRENTLY NOT IMPLEMENTED) + multiples: If True, then order multiples will be observed + currency: The currency code to use for the calculation (default is None) + break_name: The name of the price break field on the instance (default is 'price_breaks') + - Don't forget to add in flat-fee cost (base_cost field) - If MOQ (minimum order quantity) is required, bump quantity - If order multiples are to be observed, then we need to calculate based on that, too @@ -185,7 +193,7 @@ def get_price( return None # Check if quantity is fraction and disable multiples - multiples = quantity % 1 == 0 + multiples = multiples and (quantity % 1 == 0) # Order multiples if multiples: diff --git a/src/backend/InvenTree/common/filters.py b/src/backend/InvenTree/common/filters.py index c3cff3677d..e8a2d0741e 100644 --- a/src/backend/InvenTree/common/filters.py +++ b/src/backend/InvenTree/common/filters.py @@ -19,6 +19,7 @@ from django.db.models import ( from django.db.models.query import QuerySet from django.utils.translation import gettext_lazy as _ +import django_filters.rest_framework.filters as rest_filters from rest_framework import serializers from taggit.serializers import TagListSerializerField @@ -93,6 +94,36 @@ def filter_content_type( return queryset.filter(q) +class TagsFilter(rest_filters.CharFilter): + """Filter which accepts a comma-separated list of tag names and returns only objects that have ALL of the specified tags. + + Example usage in a FilterSet: + tags = TagsFilter(label=_('Tags')) + + Example query: + ?tags=apple,banana → returns only items tagged with both 'apple' AND 'banana' + """ + + def __init__(self, *args, **kwargs): + """Initialize the filter.""" + if 'label' not in kwargs: + kwargs['label'] = _('Tags') + + super().__init__(*args, **kwargs) + + def filter(self, qs, value): + """Filter queryset to items matching all provided tag names.""" + if not value: + return qs + + tag_names = [t.strip() for t in value.split(',') if t.strip()] + + for tag in tag_names: + qs = qs.filter(tags__name__iexact=tag) + + return qs.distinct() + + """A list of valid operators for filtering part parameters.""" PARAMETER_FILTER_OPERATORS: list[str] = ['gt', 'gte', 'lt', 'lte', 'ne', 'icontains'] diff --git a/src/backend/InvenTree/common/migrations/0044_notificationmessage_charfield_pk.py b/src/backend/InvenTree/common/migrations/0044_notificationmessage_charfield_pk.py new file mode 100644 index 0000000000..79ed6c44e7 --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0044_notificationmessage_charfield_pk.py @@ -0,0 +1,29 @@ +"""Migration to change NotificationMessage object_id fields from PositiveIntegerField to CharField. + +This allows notifications to reference models that use non-integer primary keys, +such as UUIDField (e.g. MachineConfig), without a database overflow error. + +See: https://github.com/inventree/InvenTree/issues/12131 +""" + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0043_auto_20260518_1206'), + ] + + operations = [ + migrations.AlterField( + model_name='notificationmessage', + name='target_object_id', + field=models.CharField(max_length=255), + ), + migrations.AlterField( + model_name='notificationmessage', + name='source_object_id', + field=models.CharField(max_length=255, null=True, blank=True), + ), + ] diff --git a/src/backend/InvenTree/common/migrations/0045_projectcode_active.py b/src/backend/InvenTree/common/migrations/0045_projectcode_active.py new file mode 100644 index 0000000000..c0a8461972 --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0045_projectcode_active.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.15 on 2026-06-25 03:13 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("common", "0044_notificationmessage_charfield_pk"), + ] + + operations = [ + migrations.AddField( + model_name="projectcode", + name="active", + field=models.BooleanField( + default=True, + help_text="Is this project code active?", + verbose_name="Active", + ), + ), + ] diff --git a/src/backend/InvenTree/common/migrations/0046_alter_emailmessage_global_id_and_more.py b/src/backend/InvenTree/common/migrations/0046_alter_emailmessage_global_id_and_more.py new file mode 100644 index 0000000000..5ead5a53bf --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0046_alter_emailmessage_global_id_and_more.py @@ -0,0 +1,59 @@ +"""Migration to store UUID primary keys as char(32) on MySQL / MariaDB. + +On MariaDB 10.7+, Django 5.x creates UUIDField columns with the native 'uuid' +type and writes 36-character (hyphenated) values. Databases migrated under older +Django / MariaDB versions retain char(32) columns, into which the new values +do not fit. + +See: https://github.com/inventree/InvenTree/issues/12270 +""" + +import uuid + +from django.db import migrations + +import InvenTree.fields + + +class Migration(migrations.Migration): + dependencies = [('common', '0045_projectcode_active')] + + operations = [ + migrations.AlterField( + model_name='emailmessage', + name='global_id', + field=InvenTree.fields.InvenTreeUUIDField( + default=uuid.uuid4, + editable=False, + help_text='Unique identifier for this message', + primary_key=True, + serialize=False, + unique=True, + verbose_name='Global ID', + ), + ), + migrations.AlterField( + model_name='emailthread', + name='global_id', + field=InvenTree.fields.InvenTreeUUIDField( + default=uuid.uuid4, + editable=False, + help_text='Unique identifier for this thread', + primary_key=True, + serialize=False, + verbose_name='Global ID', + ), + ), + migrations.AlterField( + model_name='webhookmessage', + name='message_id', + field=InvenTree.fields.InvenTreeUUIDField( + default=uuid.uuid4, + editable=False, + help_text='Unique identifier for this message', + primary_key=True, + serialize=False, + verbose_name='Message ID', + ), + ), + ] diff --git a/src/backend/InvenTree/common/migrations/0047_parametertemplate_unique.py b/src/backend/InvenTree/common/migrations/0047_parametertemplate_unique.py new file mode 100644 index 0000000000..cc2ee1eed3 --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0047_parametertemplate_unique.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.15 on 2026-07-14 00:05 + +from django.db import migrations, models +from common.models import ParameterTemplate + +class Migration(migrations.Migration): + + dependencies = [ + ("common", "0046_alter_emailmessage_global_id_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="parametertemplate", + name="unique", + field=models.PositiveIntegerField( + choices=ParameterTemplate.UniqueOptions.choices, + default=0, + help_text="Enforce uniqueness of linked parameter values against this template", + verbose_name="Uniqueness", + ), + ), + ] diff --git a/src/backend/InvenTree/common/migrations/0048_notificationmessage_link.py b/src/backend/InvenTree/common/migrations/0048_notificationmessage_link.py new file mode 100644 index 0000000000..577f5f4340 --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0048_notificationmessage_link.py @@ -0,0 +1,24 @@ +"""Add link field to notification messages.""" + +# Generated by Django 5.2.15 on 2026-07-20 01:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + """Add the optional notification link field.""" + + dependencies = [('common', '0047_parametertemplate_unique')] + + operations = [ + migrations.AddField( + model_name='notificationmessage', + name='link', + field=models.URLField( + blank=True, + help_text='Optional explicit URL associated with this notification', + max_length=500, + null=True, + ), + ) + ] diff --git a/src/backend/InvenTree/common/migrations/0049_notificationentry_charfield_uid.py b/src/backend/InvenTree/common/migrations/0049_notificationentry_charfield_uid.py new file mode 100644 index 0000000000..889597ed2e --- /dev/null +++ b/src/backend/InvenTree/common/migrations/0049_notificationentry_charfield_uid.py @@ -0,0 +1,18 @@ +"""Allow notification entries to reference UUID primary keys.""" + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0048_notificationmessage_link'), + ] + + operations = [ + migrations.AlterField( + model_name='notificationentry', + name='uid', + field=models.CharField(max_length=255), + ), + ] diff --git a/src/backend/InvenTree/common/models.py b/src/backend/InvenTree/common/models.py index a53d2640b4..321b45a3c3 100644 --- a/src/backend/InvenTree/common/models.py +++ b/src/backend/InvenTree/common/models.py @@ -50,7 +50,6 @@ from djmoney.contrib.exchange.models import convert_money from opentelemetry import trace from PIL import Image from rest_framework.exceptions import PermissionDenied -from taggit.managers import TaggableManager import common.validators import InvenTree.conversion @@ -182,6 +181,12 @@ class ProjectCode(InvenTree.models.InvenTreeMetadataModel): help_text=_('Project description'), ) + active = models.BooleanField( + default=True, + verbose_name=_('Active'), + help_text=_('Is this project code active?'), + ) + responsible = models.ForeignKey( users.models.Owner, on_delete=models.SET_NULL, @@ -1383,21 +1388,27 @@ class PriceBreak(MetaMixin): help_text=_('Unit price at specified quantity'), ) - def convert_to(self, currency_code): + def convert_to(self, currency_code: str, raise_error: bool = False): """Convert the unit-price at this price break to the specified currency code. - Args: + Arguments: currency_code: The currency code to convert to (e.g "USD" or "AUD") + raise_error: If True, raise an error if the conversion fails. If False, return None. """ try: converted = convert_money(self.price, currency_code) - except MissingRate: + except MissingRate: # pragma: no cover + InvenTree.exceptions.log_error('PriceBreak.convert_to') logger.warning( 'No currency conversion rate available for %s -> %s', self.price_currency, currency_code, ) - return self.price.amount + + if raise_error: + raise + + return None return converted.amount @@ -1579,7 +1590,7 @@ class WebhookMessage(models.Model): worked_on: Was the work on this message finished? """ - message_id = models.UUIDField( + message_id = InvenTree.fields.InvenTreeUUIDField( verbose_name=_('Message ID'), help_text=_('Unique identifier for this message'), primary_key=True, @@ -1645,10 +1656,12 @@ class NotificationEntry(MetaMixin): key = models.CharField(max_length=250, blank=False) - uid = models.IntegerField() + # Notification references may point to models with UUID primary keys. + # Store the value as text so both integer and non-integer identifiers work. + uid = models.CharField(max_length=255) @classmethod - def check_recent(cls, key: str, uid: int, delta: timedelta): + def check_recent(cls, key: str, uid: str | int | uuid.UUID, delta: timedelta): """Test if a particular notification has been sent in the specified time period.""" since = InvenTree.helpers.current_date() - delta @@ -1657,7 +1670,7 @@ class NotificationEntry(MetaMixin): return entries.exists() @classmethod - def notify(cls, key: str, uid: int): + def notify(cls, key: str, uid: str | int | uuid.UUID): """Notify the database that a particular notification has been sent out.""" entry, _ = cls.objects.get_or_create(key=key, uid=uid) @@ -1679,7 +1692,7 @@ class NotificationMessage(models.Model): ContentType, on_delete=models.CASCADE, related_name='notification_target' ) - target_object_id = models.PositiveIntegerField() + target_object_id = models.CharField(max_length=255) target_object = GenericForeignKey('target_content_type', 'target_object_id') @@ -1692,7 +1705,7 @@ class NotificationMessage(models.Model): blank=True, ) - source_object_id = models.PositiveIntegerField(null=True, blank=True) + source_object_id = models.CharField(max_length=255, null=True, blank=True) source_object = GenericForeignKey('source_content_type', 'source_object_id') @@ -1712,6 +1725,13 @@ class NotificationMessage(models.Model): message = models.CharField(max_length=250, blank=True, null=True) + link = models.URLField( + max_length=500, + blank=True, + null=True, + help_text=_('Optional explicit URL associated with this notification'), + ) + creation = models.DateTimeField(auto_now_add=True) read = models.BooleanField(default=False) @@ -1923,7 +1943,11 @@ def rename_attachment(instance, filename: str): ) -class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): +class Attachment( + InvenTree.models.MetadataMixin, + InvenTree.models.InvenTreeTagsMixin, + InvenTree.models.InvenTreeModel, +): """Class which represents an uploaded file attachment. An attachment can be either an uploaded file, or an external URL. @@ -2031,9 +2055,12 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel def __str__(self): """Human name for attachment.""" - if self.attachment is not None: + if self.attachment and self.attachment.name: return os.path.basename(self.attachment.name) - return str(self.link) + elif self.link: + return str(self.link) + else: + return super().__str__() def validate_rename(self, filename: str): """Validate that the provided filename is valid, for renaming an attachment.""" @@ -2156,8 +2183,6 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel default=0, verbose_name=_('File size'), help_text=_('File size in bytes') ) - tags = TaggableManager(blank=True) - @property def basename(self): """Base name/path for attachment.""" @@ -2627,6 +2652,19 @@ class ParameterTemplate( choice_fnc = common.validators.parameter_template_model_options + class UniqueOptions(models.IntegerChoices): + """Enumeration of uniqueness options for a ParameterTemplate. + + Attributes: + NONE: No uniqueness requirement is enforced (default) + MODEL_TYPE: Linked parameter values must be unique for a given model type + GLOBAL: Linked parameter values must be unique across all model types + """ + + NONE = 0, _('No uniqueness required') + MODEL_TYPE = 1, _('Unique for model type') + GLOBAL = 2, _('Globally unique') + @staticmethod def get_api_url() -> str: """Return the API URL associated with the ParameterTemplate model.""" @@ -2770,6 +2808,15 @@ class ParameterTemplate( help_text=_('Is this parameter template enabled?'), ) + unique = models.PositiveIntegerField( + default=UniqueOptions.NONE, + choices=UniqueOptions.choices, + verbose_name=_('Uniqueness'), + help_text=_( + 'Enforce uniqueness of linked parameter values against this template' + ), + ) + @receiver( post_save, sender=ParameterTemplate, dispatch_uid='post_save_parameter_template' @@ -2875,6 +2922,13 @@ class Parameter( except ValidationError as e: raise ValidationError({'data': e.message}) + # Validate the parameter data against any uniqueness requirements imposed by the template + self.validate_uniqueness() + + if InvenTree.ready.isReadOnlyCommand(): + # Skip plugin validation checks during read-only management commands + return + # Finally, run custom validation checks (via plugins) from plugin import PluginMixinEnum, registry @@ -2918,6 +2972,42 @@ class Parameter( if math.isnan(self.data_numeric) or math.isinf(self.data_numeric): self.data_numeric = None + def validate_uniqueness(self): + """Ensure that this Parameter satisfies any uniqueness requirements imposed by its template. + + The ParameterTemplate.unique field determines the scope of the uniqueness check: + + - NONE: No uniqueness check is performed + - MODEL_TYPE: The value must be unique amongst other parameters (for this template) linked to the same model type + - GLOBAL: The value must be unique amongst all other parameters linked to this template + + Note: If the template defines a set of 'units', the comparison is performed against the + normalized 'data_numeric' value, so that equivalent values expressed in different + (but compatible) units are correctly detected as duplicates (e.g. '1k' and '1000' ohms). + """ + uniqueness = self.template.unique + + if uniqueness == ParameterTemplate.UniqueOptions.NONE: + return + + if self.template.units and self.data_numeric is not None: + query = Parameter.objects.filter( + template=self.template, data_numeric=self.data_numeric + ) + else: + query = Parameter.objects.filter( + template=self.template, data__iexact=self.data + ) + + if self.pk: + query = query.exclude(pk=self.pk) + + if uniqueness == ParameterTemplate.UniqueOptions.MODEL_TYPE: + query = query.filter(model_type=self.model_type) + + if query.exists(): + raise ValidationError({'data': _('Parameter value must be unique')}) + def check_permission(self, permission, user): """Check if the user has the required permission for this parameter.""" from InvenTree.models import InvenTreeParameterMixin @@ -3255,7 +3345,7 @@ class EmailMessage(models.Model): TRACK_READ = 'track_read', _('Track Read') TRACK_CLICK = 'track_click', _('Track Click') - global_id = models.UUIDField( + global_id = InvenTree.fields.InvenTreeUUIDField( verbose_name=_('Global ID'), help_text=_('Unique identifier for this message'), primary_key=True, @@ -3351,6 +3441,11 @@ class EmailThread(InvenTree.models.InvenTreeMetadataModel): unique_together = [['key', 'global_id']] ordering = ['-updated'] + @staticmethod + def get_api_url(): + """Return the API URL associated with the EmailThread model.""" + return reverse('api-email-list') + key = models.CharField( max_length=250, verbose_name=_('Key'), @@ -3358,7 +3453,7 @@ class EmailThread(InvenTree.models.InvenTreeMetadataModel): blank=True, help_text=_('Unique key for this thread (used to identify the thread)'), ) - global_id = models.UUIDField( + global_id = InvenTree.fields.InvenTreeUUIDField( verbose_name=_('Global ID'), help_text=_('Unique identifier for this thread'), primary_key=True, diff --git a/src/backend/InvenTree/common/notifications.py b/src/backend/InvenTree/common/notifications.py index 880b5ba64e..a332e89a23 100644 --- a/src/backend/InvenTree/common/notifications.py +++ b/src/backend/InvenTree/common/notifications.py @@ -91,6 +91,7 @@ def trigger_notification(obj: Model, category: str = '', obj_ref: str = 'pk', ** obj: The object (model instance) that is triggering the notification category: The category (label) for the notification obj_ref: The reference to the object that should be used for the notification + notification_uid: Explicit deduplication identifier for notifications without a model instance kwargs: Additional arguments to pass to the notification method """ # Check if data is importing currently @@ -105,6 +106,7 @@ def trigger_notification(obj: Model, category: str = '', obj_ref: str = 'pk', ** context = kwargs.get('context', {}) delivery_methods = kwargs.get('delivery_methods') check_recent = kwargs.get('check_recent', True) + notification_uid = kwargs.get('notification_uid') # Resolve object reference refs = [obj_ref, 'pk', 'id', 'uid'] @@ -122,6 +124,8 @@ def trigger_notification(obj: Model, category: str = '', obj_ref: str = 'pk', ** raise KeyError( f"Could not resolve an object reference for '{obj!s}' with {','.join(set(refs))}" ) + elif notification_uid is not None: + obj_ref_value = notification_uid # Check if we have notified recently... delta = timedelta(days=1) diff --git a/src/backend/InvenTree/common/serializers.py b/src/backend/InvenTree/common/serializers.py index c8e2f13920..135539b7d8 100644 --- a/src/backend/InvenTree/common/serializers.py +++ b/src/backend/InvenTree/common/serializers.py @@ -12,6 +12,7 @@ from error_report.models import Error from flags.state import flag_state from rest_framework import serializers from rest_framework.exceptions import PermissionDenied +from taggit.models import Tag import common.filters import common.models as common_models @@ -28,6 +29,7 @@ from InvenTree.serializers import ( InvenTreeAttachmentSerializerField, InvenTreeImageSerializerField, InvenTreeModelSerializer, + InvenTreeTaggitSerializer, OptionalField, ) from plugin import registry as plugin_registry @@ -316,7 +318,9 @@ class NotificationMessageSerializer(InvenTreeModelSerializer): """Function to resolve generic object reference to target.""" target = get_objectreference(obj, 'target_content_type', 'target_object_id') - if target and 'link' not in target: + if target and obj.link: + target['link'] = obj.link + elif target and 'link' not in target: # Check if object has an absolute_url function if hasattr(obj.target_object, 'get_absolute_url'): target['link'] = obj.target_object.get_absolute_url() @@ -415,13 +419,43 @@ class ProjectCodeSerializer(DataImportExportSerializerMixin, InvenTreeModelSeria """Meta options for ProjectCodeSerializer.""" model = common_models.ProjectCode - fields = ['pk', 'code', 'description', 'responsible', 'responsible_detail'] + fields = [ + 'pk', + 'code', + 'description', + 'active', + 'responsible', + 'responsible_detail', + ] responsible_detail = OwnerSerializer( source='responsible', read_only=True, allow_null=True ) +@register_importer() +class TagSerializer(DataImportExportSerializerMixin, InvenTreeModelSerializer): + """Serializer for the Tag model.""" + + class Meta: + """Meta options for TagSerializer.""" + + model = Tag + fields = ['pk', 'name', 'slug'] + read_only_fields = ['pk', 'slug'] + + def validate(self, data): + """Slugify the received name to generate the slug.""" + from django.utils.text import slugify + + name = data.get('name', None) + + if name is not None: + data['slug'] = slugify(name) + + return data + + @register_importer() class CustomStateSerializer(DataImportExportSerializerMixin, InvenTreeModelSerializer): """Serializer for the custom state model.""" @@ -720,7 +754,9 @@ class FailedTaskSerializer(InvenTreeModelSerializer): result = serializers.CharField() -class AttachmentSerializer(FilterableSerializerMixin, InvenTreeModelSerializer): +class AttachmentSerializer( + FilterableSerializerMixin, InvenTreeTaggitSerializer, InvenTreeModelSerializer +): """Serializer class for the Attachment model.""" class Meta: @@ -840,6 +876,7 @@ class ParameterTemplateSerializer( 'choices', 'selectionlist', 'enabled', + 'unique', ] # Note: The choices are overridden at run-time on class initialization @@ -912,9 +949,7 @@ class ParameterSerializer( if not target_model_class.check_related_permission('change', user): raise PermissionDenied(permission_error_msg) - instance = super().save(**kwargs) - instance.updated_by = user - instance.save() + instance = super().save(updated_by=user, **kwargs) return instance @@ -977,15 +1012,17 @@ class SelectionEntrySerializer(InvenTreeModelSerializer): def validate(self, attrs): """Ensure that the selection list is not locked.""" ret = super().validate(attrs) - if self.instance and self.instance.list.locked: + list_obj = attrs.get('list') or (self.instance and self.instance.list) + if list_obj and list_obj.locked: raise serializers.ValidationError({'list': _('Selection list is locked')}) return ret -class SelectionListSerializer(InvenTreeModelSerializer): +class SelectionListSerializer(FilterableSerializerMixin, InvenTreeModelSerializer): """Serializer for a selection list.""" _choices_validated: dict = {} + _choices_provided: bool = False class Meta: """Meta options for SelectionListSerializer.""" @@ -1002,81 +1039,25 @@ class SelectionListSerializer(InvenTreeModelSerializer): 'default', 'created', 'last_updated', - 'choices', 'entry_count', + 'choices', ] default = SelectionEntrySerializer(read_only=True, allow_null=True, many=False) - choices = SelectionEntrySerializer(source='entries', many=True, required=False) entry_count = serializers.IntegerField(read_only=True) + choices = OptionalField( + serializer_class=SelectionEntrySerializer, + serializer_kwargs={'source': 'entries', 'many': True, 'read_only': True}, + prefetch_fields=['entries'], + default_include=True, + ) + @staticmethod def annotate_queryset(queryset): """Add count of entries for each selection list.""" return queryset.annotate(entry_count=Count('entries')) - def is_valid(self, *, raise_exception=False): - """Validate the selection list. Choices are validated separately.""" - choices = ( - self.initial_data.pop('choices') - if self.initial_data.get('choices') is not None - else [] - ) - - # Validate the choices - _choices_validated = [] - db_entries = ( - {a.id: a for a in self.instance.entries.all()} if self.instance else {} - ) - - for choice in choices: - current_inst = db_entries.get(choice.get('id')) - serializer = SelectionEntrySerializer( - instance=current_inst, - data={'list': current_inst.list.pk if current_inst else None, **choice}, - ) - serializer.is_valid(raise_exception=raise_exception) - _choices_validated.append({ - **serializer.validated_data, - 'id': choice.get('id'), - }) - self._choices_validated = _choices_validated - - return super().is_valid(raise_exception=raise_exception) - - def create(self, validated_data): - """Create a new selection list. Save the choices separately.""" - list_entry = common_models.SelectionList.objects.create(**validated_data) - for choice_data in self._choices_validated: - common_models.SelectionListEntry.objects.create(**{ - **choice_data, - 'list': list_entry, - }) - return list_entry - - def update(self, instance, validated_data): - """Update an existing selection list. Save the choices separately.""" - inst_mapping = {inst.id: inst for inst in instance.entries.all()} - existing_ids = {a.get('id') for a in self._choices_validated} - - # Perform creations and updates. - ret = [] - for data in self._choices_validated: - list_inst = data.get('list', None) - inst = inst_mapping.get(data.get('id')) - if inst is None: - if list_inst is None: - data['list'] = instance - ret.append(SelectionEntrySerializer().create(data)) - else: - ret.append(SelectionEntrySerializer().update(inst, data)) - - # Perform deletions. - for entry_id in inst_mapping.keys() - existing_ids: - inst_mapping[entry_id].delete() - - return super().update(instance, validated_data) - def validate(self, attrs): """Ensure that the selection list is not locked.""" ret = super().validate(attrs) diff --git a/src/backend/InvenTree/common/setting/system.py b/src/backend/InvenTree/common/setting/system.py index c646aa843d..abdfd55094 100644 --- a/src/backend/InvenTree/common/setting/system.py +++ b/src/backend/InvenTree/common/setting/system.py @@ -677,6 +677,12 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'REPORT_FETCH_URLS': { + 'name': _('Report URL Fetching'), + 'description': _('Allow fetching of remote URLs when generating reports'), + 'default': False, + 'validator': bool, + }, 'REPORT_LOG_ERRORS': { 'name': _('Log Report Errors'), 'description': _('Log errors which occur when generating reports'), @@ -787,6 +793,14 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'STOCK_MERGE_ON_TRANSFER': { + 'name': _('Merge stock with existing stock on transfer by default'), + 'description': _( + 'Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)' + ), + 'default': False, + 'validator': bool, + }, 'BUILDORDER_REFERENCE_PATTERN': { 'name': _('Build Order Reference Pattern'), 'description': _('Required pattern for generating Build Order reference field'), @@ -937,6 +951,14 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'TRANSFERORDER_EDIT_COMPLETED_ORDERS': { + 'name': _('Edit Completed Transfer Orders'), + 'description': _( + 'Allow editing of transfer orders after they have been completed' + ), + 'default': False, + 'validator': bool, + }, 'SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS': { 'name': _('Block Incomplete Item Tests'), 'description': _( @@ -981,6 +1003,14 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': True, 'validator': bool, }, + 'PURCHASEORDER_MERGE_LINE_ITEMS': { + 'name': _('Merge Purchase Order Line Items'), + 'description': _( + 'Merge new purchase order line items with existing lines that share the same part, destination, and target date' + ), + 'default': True, + 'validator': bool, + }, # login / SSO 'LOGIN_ENABLE_PWD_FORGOT': { 'name': _('Enable password forgot'), @@ -1243,6 +1273,15 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { ('6', _('Saturday')), ], }, + 'CALENDAR_HORIZON_MONTHS': { + 'name': _('Calendar Horizon'), + 'description': _( + 'Number of months into the future to display in calendar views' + ), + 'default': 12, + 'validator': [int, MinValueValidator(1)], + 'units': _('months'), + }, 'TEST_STATION_DATA': { 'name': _('Enable Test Station Data'), 'description': _('Enable test station data collection for test results'), diff --git a/src/backend/InvenTree/common/setting/type.py b/src/backend/InvenTree/common/setting/type.py index 0e788c017f..3a704d5e24 100644 --- a/src/backend/InvenTree/common/setting/type.py +++ b/src/backend/InvenTree/common/setting/type.py @@ -1,19 +1,7 @@ """Types for settings.""" -import sys from collections.abc import Callable -from typing import Any, TypedDict - -if sys.version_info >= (3, 11): - from typing import NotRequired # pragma: no cover -else: - - class NotRequired: # pragma: no cover - """NotRequired type helper is only supported with Python 3.11+.""" - - def __class_getitem__(cls, item): - """Return the item.""" - return item +from typing import Any, NotRequired, TypedDict class SettingsKeyType(TypedDict, total=False): diff --git a/src/backend/InvenTree/common/setting/user.py b/src/backend/InvenTree/common/setting/user.py index c9cae610ba..24d0fccd15 100644 --- a/src/backend/InvenTree/common/setting/user.py +++ b/src/backend/InvenTree/common/setting/user.py @@ -159,6 +159,14 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': 10, 'validator': [int, MinValueValidator(1)], }, + 'SEARCH_RESULTS_PREVIEW_PANEL': { + 'name': _('Search Results Preview Panel'), + 'description': _( + 'Open search results in the preview panel, rather than navigating directly to the result' + ), + 'default': False, + 'validator': bool, + }, 'SEARCH_REGEX': { 'name': _('Regex Search'), 'description': _('Enable regular expressions in search queries'), @@ -223,6 +231,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { ('MMM DD YYYY', 'Feb 22 2022'), ], }, + 'ENABLE_PREVIEW_PANEL': { + 'name': _('Table Preview Panel'), + 'description': _('Display a preview panel when selecting items in tables'), + 'default': False, + 'validator': bool, + }, 'DISPLAY_STOCKTAKE_TAB': { 'name': _('Show Stock History'), 'description': _('Display stock history information in the part detail page'), @@ -235,6 +249,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'SHOW_EXTRA_MODEL_INFO': { + 'name': _('Show Extra Model Information'), + 'description': _('Display extra information in model selection dropdowns'), + 'default': False, + 'validator': bool, + }, 'SHOW_FULL_LOCATION_IN_TABLES': { 'name': _('Show full stock location in tables'), 'description': _( diff --git a/src/backend/InvenTree/common/settings.py b/src/backend/InvenTree/common/settings.py index 0e32fb99a5..3589b41adb 100644 --- a/src/backend/InvenTree/common/settings.py +++ b/src/backend/InvenTree/common/settings.py @@ -13,6 +13,19 @@ import InvenTree.ready logger = structlog.get_logger('inventree') +def plugin_setting_overrides(slug: str) -> dict: + """Return a dictionary of plugin setting overrides for the given plugin slug. + + These values are set via environment variables or configuration file. + """ + from django.conf import settings + + if hasattr(settings, 'PLUGIN_SETTING_OVERRIDES'): + return settings.PLUGIN_SETTING_OVERRIDES.get(slug, {}) or {} + + return {} + + def global_setting_overrides() -> dict: """Return a dictionary of global settings overrides. @@ -129,12 +142,3 @@ def stock_expiry_enabled(): from common.models import InvenTreeSetting return InvenTreeSetting.get_setting('STOCK_ENABLE_EXPIRY', False, create=False) - - -def prevent_build_output_complete_on_incompleted_tests(): - """Returns True if the completion of the build outputs is disabled until the required tests are passed.""" - from common.models import InvenTreeSetting - - return InvenTreeSetting.get_setting( - 'PREVENT_BUILD_COMPLETION_HAVING_INCOMPLETED_TESTS', False, create=False - ) diff --git a/src/backend/InvenTree/common/test_api.py b/src/backend/InvenTree/common/test_api.py index d4875c9014..71602098ca 100644 --- a/src/backend/InvenTree/common/test_api.py +++ b/src/backend/InvenTree/common/test_api.py @@ -2,15 +2,20 @@ import io +from django.core.exceptions import ValidationError from django.core.files.base import ContentFile from django.core.files.storage import default_storage from django.core.files.uploadedfile import SimpleUploadedFile +from django.test.utils import override_settings from django.urls import reverse from PIL import Image +from taggit.models import Tag import common.models -from InvenTree.unit_test import InvenTreeAPITestCase +from common.models import SelectionList, SelectionListEntry +from common.settings import set_global_setting +from InvenTree.unit_test import InvenTreeAPITestCase, findOffloadedEvent class DataOutputAPITests(InvenTreeAPITestCase): @@ -71,6 +76,7 @@ class ParameterAPITests(InvenTreeAPITestCase): 'model_type', 'selectionlist', 'enabled', + 'unique', ]: self.assertIn( field, @@ -565,6 +571,269 @@ class ParameterAPITests(InvenTreeAPITestCase): common.models.Parameter.objects.filter(pk=parameter.pk).exists() ) + @override_settings( + TESTING_TABLE_EVENTS=True, + PLUGIN_TESTING_EVENTS=True, + PLUGIN_TESTING_EVENTS_ASYNC=True, + ) + def test_bulk_create_parameters(self): + """Test bulk creation of parameters via the API. + + Test that: + - The correct number of items are created + - Instance creation events are offloaded to the background worker + """ + from django_q.models import OrmQ + + from part.models import Part + + self.assignRole('part.add') + + OrmQ.objects.all().delete() + + set_global_setting('ENABLE_PLUGINS_EVENTS', True) + + template = common.models.ParameterTemplate.objects.create( + name='Test Parameter', + description='A parameter template for testing bulk creation', + model_type=None, + ) + + # Generate a set of parts + parts = [ + Part.objects.create( + name=f'Test Part {ii}', description='A part for testing' + ) + for ii in range(50) + ] + + N = common.models.Parameter.objects.count() + + # Bulk-create parameters + response = self.post( + reverse('api-parameter-list'), + data=[ + { + 'template': template.pk, + 'model_type': 'part.part', + 'model_id': part.pk, + 'data': f'Test data {part.pk}', + } + for part in parts + ], + benchmark=True, + max_query_count=500, + max_query_time=2.0, + ) + + self.assertEqual(len(response.data), 50) + + # Check that the parameters have been created + self.assertEqual(common.models.Parameter.objects.count(), N + len(parts)) + + # We expect that 50 events have been offloaded to the background worker + self.assertGreaterEqual(OrmQ.objects.count(), len(parts)) + + # There should be a parameter for each part + for part in parts: + self.assertEqual(part.parameters.count(), 1) + parameter = part.parameters.first() + self.assertIsNotNone(parameter) + self.assertIsNotNone(parameter.updated) + self.assertIsNotNone(parameter.updated_by) + self.assertEqual(parameter.updated_by, self.user) + + # Check that an associated event has been offloaded + self.assertIsNotNone( + findOffloadedEvent( + 'part_partparameter.created', matching_kwargs={'id': parameter.pk} + ), + f'No created event found for parameter {parameter.pk}', + ) + + # Check that an extra 'saved' event is *NOT* generated + self.assertIsNone( + findOffloadedEvent( + 'part_partparameter.saved', matching_kwargs={'id': parameter.pk} + ), + f'Unexpected saved event found for parameter {parameter.pk}', + ) + + set_global_setting('ENABLE_PLUGINS_EVENTS', False) + + def test_parameter_uniqueness(self): + """Test the uniqueness options which can be applied to a ParameterTemplate.""" + from company.models import Company + from part.models import Part + + part_a = Part.objects.create(name='Part A', description='A part for testing') + part_b = Part.objects.create(name='Part B', description='A part for testing') + part_c = Part.objects.create(name='Part C', description='A part for testing') + company = Company.objects.create( + name='Test Company', description='A company for testing' + ) + + template = common.models.ParameterTemplate.objects.create( + name='Serial Number', description='A serial number parameter' + ) + + self.assertEqual( + template.unique, common.models.ParameterTemplate.UniqueOptions.NONE + ) + + param_a = common.models.Parameter( + template=template, + model_type=part_a.get_content_type(), + model_id=part_a.pk, + data='ABC123', + ) + param_a.full_clean() + param_a.save() + + # No uniqueness requirement - a duplicate value against a different part is fine + param_b = common.models.Parameter( + template=template, + model_type=part_b.get_content_type(), + model_id=part_b.pk, + data='ABC123', + ) + param_b.full_clean() + param_b.save() + + # Re-saving the existing instance (unchanged) should not raise any errors + param_a.full_clean() + param_a.save() + + # Now, require uniqueness *per model type* + template.unique = common.models.ParameterTemplate.UniqueOptions.MODEL_TYPE + template.save() + + # A new Part with the same value should be rejected + with self.assertRaises(ValidationError): + common.models.Parameter( + template=template, + model_type=part_c.get_content_type(), + model_id=part_c.pk, + data='ABC123', + ).full_clean() + + # A case-insensitive match should also be rejected + with self.assertRaises(ValidationError): + common.models.Parameter( + template=template, + model_type=part_c.get_content_type(), + model_id=part_c.pk, + data='abc123', + ).full_clean() + + # A different model type entirely is not affected by the 'model type' restriction + param_company = common.models.Parameter( + template=template, + model_type=company.get_content_type(), + model_id=company.pk, + data='ABC123', + ) + param_company.full_clean() + param_company.save() + + # Finally, require the value to be *globally* unique + template.unique = common.models.ParameterTemplate.UniqueOptions.GLOBAL + template.save() + + with self.assertRaises(ValidationError): + common.models.Parameter( + template=template, + model_type=part_c.get_content_type(), + model_id=part_c.pk, + data='ABC123', + ).full_clean() + + def test_parameter_uniqueness_units(self): + """Test that uniqueness checks are unit-aware for templates which define units. + + Values expressed in different (but compatible) units which represent the + same physical quantity must be detected as duplicates. + """ + from part.models import Part + + part_a = Part.objects.create(name='Part A', description='A part for testing') + part_b = Part.objects.create(name='Part B', description='A part for testing') + + template = common.models.ParameterTemplate.objects.create( + name='Resistance', + units='ohm', + description='A globally unique resistance parameter', + unique=common.models.ParameterTemplate.UniqueOptions.GLOBAL, + ) + + param_a = common.models.Parameter( + template=template, + model_type=part_a.get_content_type(), + model_id=part_a.pk, + data='1000', + ) + param_a.full_clean() + param_a.save() + + # A value expressed as '1k' ohms is numerically identical to '1000' ohms + with self.assertRaises(ValidationError): + common.models.Parameter( + template=template, + model_type=part_b.get_content_type(), + model_id=part_b.pk, + data='1k', + ).full_clean() + + # A distinct value (in different units) is not a duplicate + param_b = common.models.Parameter( + template=template, + model_type=part_b.get_content_type(), + model_id=part_b.pk, + data='2k', + ) + param_b.full_clean() + param_b.save() + + def test_copy_unique_parameters(self): + """Test that 'unique' parameters are skipped when copying parameters between model instances.""" + from part.models import Part + + part_a = Part.objects.create(name='Part A', description='A part for testing') + part_b = Part.objects.create(name='Part B', description='A part for testing') + + normal_template = common.models.ParameterTemplate.objects.create( + name='Color', description='A normal (non-unique) parameter' + ) + + unique_template = common.models.ParameterTemplate.objects.create( + name='Serial Number', + description='A globally unique parameter', + unique=common.models.ParameterTemplate.UniqueOptions.GLOBAL, + ) + + common.models.Parameter.objects.create( + template=normal_template, + model_type=part_a.get_content_type(), + model_id=part_a.pk, + data='Red', + ) + + common.models.Parameter.objects.create( + template=unique_template, + model_type=part_a.get_content_type(), + model_id=part_a.pk, + data='ABC123', + ) + + # Copy parameters from part_a to part_b + part_b.copy_parameters_from(part_a) + + # The non-unique parameter should have been copied + self.assertEqual(part_b.get_parameter('Color').data, 'Red') + + # The unique parameter should *not* have been copied, to avoid a conflicting value + self.assertIsNone(part_b.get_parameter('Serial Number')) + def test_parameter_annotation(self): """Test that we can annotate parameters against a queryset.""" from company.models import Company @@ -999,3 +1268,287 @@ class AttachmentThumbnailAPITests(InvenTreeAPITestCase): set_global_setting( 'INVENTREE_UPLOAD_MAX_SIZE', original_limit, change_user=None ) + + +class TagAPITests(InvenTreeAPITestCase): + """Tests for the Tag API endpoints and tag-based filtering.""" + + roles = 'all' + + LIST_URL = 'api-tag-list' + DETAIL_URL = 'api-tag-detail' + + def setUp(self): + """Create a small set of tagged objects for filter testing.""" + super().setUp() + + from part.models import Part + + self.part_a = Part.objects.create( + name='Tagged Part A', description='Part with apple and banana tags' + ) + self.part_b = Part.objects.create( + name='Tagged Part B', description='Part with apple tag only' + ) + self.part_c = Part.objects.create( + name='Untagged Part C', description='Part with no tags' + ) + + self.part_a.tags.add('apple', 'banana') + self.part_b.tags.add('apple') + + # ------------------------------------------------------------------ + # Tag list / CRUD + # ------------------------------------------------------------------ + + def test_tag_list(self): + """Tag list endpoint should return all existing tags.""" + url = reverse(self.LIST_URL) + response = self.get(url) + + names = {t['name'] for t in response.data} + self.assertIn('apple', names) + self.assertIn('banana', names) + + def test_tag_create(self): + """Staff users should be able to create tags via POST.""" + url = reverse(self.LIST_URL) + n = Tag.objects.count() + + response = self.post(url, {'name': 'cherry'}, expected_code=201) + self.assertEqual(response.data['name'], 'cherry') + self.assertEqual(Tag.objects.count(), n + 1) + + def test_tag_create_non_staff(self): + """Non-staff users must not be able to create tags.""" + self.user.is_staff = False + self.user.save() + + url = reverse(self.LIST_URL) + self.post(url, {'name': 'forbidden'}, expected_code=403) + + def test_tag_edit(self): + """Staff users should be able to rename a tag via PATCH.""" + tag = Tag.objects.get(name='banana') + url = reverse(self.DETAIL_URL, kwargs={'pk': tag.pk}) + + response = self.patch(url, {'name': 'blueberry'}, expected_code=200) + self.assertEqual(response.data['name'], 'blueberry') + + tag.refresh_from_db() + self.assertEqual(tag.name, 'blueberry') + + def test_tag_delete(self): + """Staff users should be able to delete a tag.""" + tag = Tag.objects.get(name='banana') + url = reverse(self.DETAIL_URL, kwargs={'pk': tag.pk}) + + self.delete(url, expected_code=204) + self.assertFalse(Tag.objects.filter(name='banana').exists()) + + def test_tag_search(self): + """The list endpoint should support free-text search.""" + url = reverse(self.LIST_URL) + + response = self.get(url, data={'search': 'app'}) + names = [t['name'] for t in response.data] + self.assertIn('apple', names) + self.assertNotIn('banana', names) + + # ------------------------------------------------------------------ + # Filter by model type + # ------------------------------------------------------------------ + + def test_tag_filter_model_type(self): + """Tags applied to a given model type should be returned when filtering by model_type.""" + url = reverse(self.LIST_URL) + + # Filter for tags applied to Part objects + response = self.get(url, data={'model_type': 'part.part'}) + names = {t['name'] for t in response.data} + + self.assertIn('apple', names) + self.assertIn('banana', names) + + def test_tag_filter_model_type_unrelated(self): + """Filtering by a model type that has no tagged objects should return an empty list.""" + url = reverse(self.LIST_URL) + + # StockItem has no tagged objects in this test + response = self.get(url, data={'model_type': 'stock.stockitem'}) + self.assertEqual(len(response.data), 0) + + def test_tag_filter_model_type_invalid(self): + """An unrecognised model_type value should return a 400 error.""" + url = reverse(self.LIST_URL) + self.get(url, data={'model_type': 'notanapp.notamodel'}, expected_code=400) + + # ------------------------------------------------------------------ + # Filter Part list by tags + # ------------------------------------------------------------------ + + def test_part_filter_single_tag(self): + """Filtering parts by a single tag should return only parts with that tag.""" + url = reverse('api-part-list') + + response = self.get(url, data={'tags': 'apple'}) + pks = {p['pk'] for p in response.data} + + self.assertIn(self.part_a.pk, pks) + self.assertIn(self.part_b.pk, pks) + self.assertNotIn(self.part_c.pk, pks) + + def test_part_filter_multiple_tags_and(self): + """Filtering by comma-separated tags should return only parts that have ALL tags.""" + url = reverse('api-part-list') + + response = self.get(url, data={'tags': 'apple,banana'}) + pks = {p['pk'] for p in response.data} + + self.assertIn(self.part_a.pk, pks) + self.assertNotIn(self.part_b.pk, pks) # only has 'apple' + self.assertNotIn(self.part_c.pk, pks) # no tags at all + + def test_part_filter_tag_case_insensitive(self): + """Tag filtering should be case-insensitive.""" + url = reverse('api-part-list') + + response = self.get(url, data={'tags': 'APPLE'}) + pks = {p['pk'] for p in response.data} + + self.assertIn(self.part_a.pk, pks) + self.assertIn(self.part_b.pk, pks) + + def test_part_filter_nonexistent_tag(self): + """Filtering by a tag that no part has should return an empty result set.""" + url = reverse('api-part-list') + + response = self.get(url, data={'tags': 'doesnotexist'}) + self.assertEqual(len(response.data), 0) + + def test_part_filter_tag_whitespace(self): + """Whitespace around comma-separated tag names should be ignored.""" + url = reverse('api-part-list') + + response = self.get(url, data={'tags': ' apple , banana '}) + pks = {p['pk'] for p in response.data} + + self.assertIn(self.part_a.pk, pks) + self.assertNotIn(self.part_b.pk, pks) + + # ------------------------------------------------------------------ + # 'tags' as an OptionalField (data inclusion, not filtering) + # ------------------------------------------------------------------ + # + # Every serializer below wires up its 'tags' field via + # `common.filters.enable_tags_filter()`, with `default_include=False` - + # so a plain detail request should never include tag data, and it should + # only appear when the caller explicitly asks for it via `?tags=true`. + + def test_part_detail_tags_excluded_by_default(self): + """A plain part detail request should not include tag data.""" + url = reverse('api-part-detail', kwargs={'pk': self.part_a.pk}) + + response = self.get(url, expected_code=200) + self.assertNotIn('tags', response.data) + + def test_part_detail_tags_included_via_query_param(self): + """Requesting '?tags=true' on part detail should include the part's tag names.""" + url = reverse('api-part-detail', kwargs={'pk': self.part_a.pk}) + + response = self.get(url, data={'tags': 'true'}, expected_code=200) + self.assertIn('tags', response.data) + self.assertEqual(set(response.data['tags']), {'apple', 'banana'}) + + # An untagged part should report an empty list, not omit the field + url = reverse('api-part-detail', kwargs={'pk': self.part_c.pk}) + response = self.get(url, data={'tags': 'true'}, expected_code=200) + self.assertIn('tags', response.data) + self.assertEqual(response.data['tags'], []) + + def test_part_list_tags_query_param_collides_with_tag_filter(self): + """On the list endpoint, '?tags=true' is *not* the OptionalField inclusion flag. + + `PartFilter` (the list endpoint's FilterSet) declares its own 'tags' field + (a `TagsFilter`, for filtering by tag name - see the `test_part_filter_*` + tests above), which shadows the serializer's 'tags' OptionalField: both are + wired to the same query parameter name. django-filter processes the + FilterSet before the serializer runs, so '?tags=true' is filtered as "must + have a tag named 'true'" - which nothing does - rather than being treated + as a request to include each part's tag data. + + This is presumably not the intended behaviour for a client trying to + request tag data on a list endpoint, but it is the current, real + behaviour - this test locks it in so a change to either `PartFilter` or + `enable_tags_filter()` is a deliberate decision rather than an accident. + """ + url = reverse('api-part-list') + + response = self.get(url, data={'tags': 'true'}, expected_code=200) + self.assertEqual(response.data, []) + + +class SelectionListLockedTest(InvenTreeAPITestCase): + """Tests that a locked SelectionList rejects all entry mutations.""" + + def setUp(self): + """Create a locked SelectionList with one entry.""" + super().setUp() + + self.sel_list = SelectionList.objects.create(name='Locked List', locked=True) + self.entry = SelectionListEntry.objects.create( + list=self.sel_list, value='v1', label='Entry 1' + ) + + self.list_url = reverse( + 'api-selectionlist-detail', kwargs={'pk': self.sel_list.pk} + ) + self.entry_list_url = reverse( + 'api-selectionlistentry-list', kwargs={'pk': self.sel_list.pk} + ) + self.entry_detail_url = reverse( + 'api-selectionlistentry-detail', + kwargs={'pk': self.sel_list.pk, 'entrypk': self.entry.pk}, + ) + + def test_create_entry_locked(self): + """POST a new entry to a locked list should be rejected.""" + response = self.post( + self.entry_list_url, + {'list': self.sel_list.pk, 'value': 'v2', 'label': 'Entry 2'}, + expected_code=400, + ) + self.assertIn('list', response.data) + self.assertIn('locked', str(response.data['list']).lower()) + + def test_update_entry_locked(self): + """PATCH an entry on a locked list should be rejected.""" + response = self.patch( + self.entry_detail_url, {'label': 'Changed'}, expected_code=400 + ) + self.assertIn('list', response.data) + self.assertIn('locked', str(response.data['list']).lower()) + + def test_delete_entry_locked(self): + """DELETE an entry from a locked list should be rejected.""" + self.delete(self.entry_detail_url, expected_code=403) + self.assertTrue(SelectionListEntry.objects.filter(pk=self.entry.pk).exists()) + + def test_patch_list_with_choices_locked(self): + """PATCH the list with a choices payload should be rejected when locked.""" + response = self.patch( + self.list_url, + {'choices': [{'value': 'v2', 'label': 'New'}]}, + expected_code=400, + ) + self.assertIn('locked', response.data) + + def test_patch_list_without_choices_preserves_entries(self): + """PATCH the list without choices should not touch entries (even when unlocked).""" + self.sel_list.locked = False + self.sel_list.save() + + self.patch(self.list_url, {'name': 'Renamed List'}, expected_code=200) + + # Entry must still exist — omitting choices must not delete entries + self.assertTrue(SelectionListEntry.objects.filter(pk=self.entry.pk).exists()) diff --git a/src/backend/InvenTree/common/tests.py b/src/backend/InvenTree/common/tests.py index af0420e62d..49463dfc45 100644 --- a/src/backend/InvenTree/common/tests.py +++ b/src/backend/InvenTree/common/tests.py @@ -2,7 +2,9 @@ import io import json +import os import time +import uuid from datetime import timedelta from http import HTTPStatus from unittest import mock @@ -222,6 +224,46 @@ class AttachmentTest(InvenTreeAPITestCase): self.assertIs(type(url), str) self.assertIn(f'/media/attachments/part/{part.pk}/test', url) + def test_str_representation(self): + """Test the __str__ method of the Attachment model. + + - If a file is attached, the string representation should be the file basename. + - If only a link is provided (no file), the string representation should be the link. + - If neither is set, fall back to the default django representation. + """ + part = Part.objects.first() + + # Case 1: Attachment has an uploaded file - string is the file basename + attachment = Attachment.objects.create( + attachment=self.generate_file('test.txt'), + comment='File attachment', + model_type='part', + model_id=part.pk, + ) + + self.assertTrue(str(attachment).startswith('test')) + self.assertTrue(str(attachment).endswith('.txt')) + self.assertEqual(str(attachment), os.path.basename(attachment.attachment.name)) + + # Case 2: Attachment has only a link (no uploaded file) - string is the link + link = 'https://www.example.org' + attachment = Attachment.objects.create( + link=link, comment='Link attachment', model_type='part', model_id=part.pk + ) + + self.assertEqual(str(attachment), link) + + # Case 3: Attachment has neither a file nor a link set + # (bypass 'save' to skip the validation which requires one of these fields) + attachment = Attachment( + comment='Empty attachment', model_type='part', model_id=part.pk + ) + + self.assertFalse(attachment.attachment) + self.assertFalse(attachment.link) + self.assertEqual(str(attachment), super(Attachment, attachment).__str__()) + self.assertEqual(str(attachment), f'Attachment object ({attachment.pk})') + class SettingsTest(InvenTreeTestCase): """Tests for the 'settings' model.""" @@ -1292,6 +1334,18 @@ class NotificationTest(InvenTreeAPITestCase): self.assertTrue(NotificationEntry.check_recent('test.notification', 1, delta)) + def test_uuid_notification_entry(self): + """Notification entries support objects with UUID primary keys.""" + notification_uid = uuid.uuid4() + + NotificationEntry.notify('test.uuid_notification', notification_uid) + + self.assertTrue( + NotificationEntry.check_recent( + 'test.uuid_notification', notification_uid, timedelta(days=1) + ) + ) + def test_api_list(self): """Test list URL.""" url = reverse('api-notifications-list') @@ -1752,6 +1806,22 @@ class ProjectCodesTest(InvenTreeAPITestCase): str(response.data['code']), ) + def test_filter_active(self): + """Test that the 'active' field can be filtered via the API.""" + # Mark one code as inactive + code = ProjectCode.objects.first() + code.active = False + code.save() + + active_count = ProjectCode.objects.filter(active=True).count() + inactive_count = ProjectCode.objects.filter(active=False).count() + + response = self.get(self.url, data={'active': True}, expected_code=200) + self.assertEqual(len(response.data), active_count) + + response = self.get(self.url, data={'active': False}, expected_code=200) + self.assertEqual(len(response.data), inactive_count) + def test_write_access(self): """Test that non-staff users have read-only access.""" # By default user has staff access, can create a new project code @@ -2103,43 +2173,58 @@ class SelectionListTest(InvenTreeAPITestCase): # Test adding a new list via the API response = self.post( reverse('api-selectionlist-list'), - { - 'name': 'New List', - 'active': True, - 'choices': [{'value': '1', 'label': 'Test Entry'}], - }, + {'name': 'New List', 'active': True}, expected_code=201, ) list_pk = response.data['pk'] self.assertEqual(response.data['name'], 'New List') self.assertTrue(response.data['active']) + + entry_list_url = reverse('api-selectionlistentry-list', kwargs={'pk': list_pk}) + + # Add an entry via the entry API + response = self.post( + entry_list_url, + {'list': list_pk, 'value': '1', 'label': 'Test Entry'}, + expected_code=201, + ) + entry_pk = response.data['id'] + self.assertEqual(response.data['value'], '1') + self.assertEqual(response.data['label'], 'Test Entry') + + # Verify the entry appears in the list's choices + response = self.get( + reverse('api-selectionlist-detail', kwargs={'pk': list_pk}), + data={'choices': True}, + expected_code=200, + ) self.assertEqual(len(response.data['choices']), 1) self.assertEqual(response.data['choices'][0]['value'], '1') - # Test editing the list choices via the API (remove and add in same call) - response = self.patch( - reverse('api-selectionlist-detail', kwargs={'pk': list_pk}), - {'choices': [{'value': '2', 'label': 'New Label'}]}, - expected_code=200, + # Edit the entry via the entry detail API + entry_url = reverse( + 'api-selectionlistentry-detail', kwargs={'pk': list_pk, 'entrypk': entry_pk} ) - self.assertEqual(response.data['name'], 'New List') - self.assertTrue(response.data['active']) - self.assertEqual(len(response.data['choices']), 1) - self.assertEqual(response.data['choices'][0]['value'], '2') - self.assertEqual(response.data['choices'][0]['label'], 'New Label') - entry_id = response.data['choices'][0]['id'] + response = self.patch(entry_url, {'label': 'Updated Label'}, expected_code=200) + self.assertEqual(response.data['value'], '1') + self.assertEqual(response.data['label'], 'Updated Label') - # Test changing an entry via list API - response = self.patch( + # Add a second entry, then delete the first via the entry detail API + self.post( + entry_list_url, + {'list': list_pk, 'value': '2', 'label': 'Second Entry'}, + expected_code=201, + ) + self.delete(entry_url, expected_code=204) + + # Verify only the second entry remains + response = self.get( reverse('api-selectionlist-detail', kwargs={'pk': list_pk}), - {'choices': [{'id': entry_id, 'value': '2', 'label': 'New Label Text'}]}, + data={'choices': True}, expected_code=200, ) - self.assertEqual(response.data['name'], 'New List') - self.assertTrue(response.data['active']) self.assertEqual(len(response.data['choices']), 1) self.assertEqual(response.data['choices'][0]['value'], '2') - self.assertEqual(response.data['choices'][0]['label'], 'New Label Text') def test_api_locked(self): """Test editing with locked/unlocked list.""" diff --git a/src/backend/InvenTree/common/validators.py b/src/backend/InvenTree/common/validators.py index 226a42b7d2..d1d9e63ebf 100644 --- a/src/backend/InvenTree/common/validators.py +++ b/src/backend/InvenTree/common/validators.py @@ -4,6 +4,7 @@ import re from django.core.exceptions import SuspiciousFileOperation, ValidationError from django.core.files.storage import default_storage +from django.utils import translation from django.utils.translation import gettext_lazy as _ import common.icons @@ -171,3 +172,17 @@ def validate_variable_string(value: str): """The passed value must be a valid variable identifier string.""" if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', value): raise ValidationError(_('Value must be a valid variable identifier')) + + +def validate_locale(value: str): + """Validate that the provided value is a valid locale string.""" + from babel import Locale + from babel.core import UnknownLocaleError + + if not value: + return + + try: + Locale.parse(translation.to_locale(value)) + except (UnknownLocaleError, ValueError) as e: + raise ValidationError(f"Invalid locale value: '{value}' - {e}") diff --git a/src/backend/InvenTree/company/admin.py b/src/backend/InvenTree/company/admin.py index b35218ad1e..4b0f11138b 100644 --- a/src/backend/InvenTree/company/admin.py +++ b/src/backend/InvenTree/company/admin.py @@ -70,7 +70,7 @@ class AddressAdmin(admin.ModelAdmin): list_display = ('company', 'line1', 'postal_code', 'country') - search_fields = ['company', 'country', 'postal_code'] + search_fields = ['company__name', 'country', 'postal_code'] autocomplete_fields = ['company'] @@ -81,6 +81,6 @@ class ContactAdmin(admin.ModelAdmin): list_display = ('company', 'name', 'role', 'email', 'phone') - search_fields = ['company', 'name', 'email'] + search_fields = ['company__name', 'name', 'email'] autocomplete_fields = ['company'] diff --git a/src/backend/InvenTree/company/api.py b/src/backend/InvenTree/company/api.py index e0639712a5..f57a2fff1a 100644 --- a/src/backend/InvenTree/company/api.py +++ b/src/backend/InvenTree/company/api.py @@ -7,6 +7,7 @@ from django.utils.translation import gettext_lazy as _ import django_filters.rest_framework.filters as rest_filters from django_filters.rest_framework.filterset import FilterSet +import common.filters import part.models from data_exporter.mixins import DataExportViewMixin from InvenTree.api import ListCreateDestroyAPIView, ParameterListMixin @@ -37,6 +38,18 @@ from .serializers import ( ) +class CompanyFilter(FilterSet): + """Custom API filters for the CompanyList endpoint.""" + + class Meta: + """Metaclass options.""" + + model = Company + fields = ['is_customer', 'is_manufacturer', 'is_supplier', 'name', 'active'] + + tags = common.filters.TagsFilter() + + class CompanyMixin(OutputOptionsMixin): """Mixin class for Company API endpoints.""" @@ -62,13 +75,7 @@ class CompanyList(CompanyMixin, ParameterListMixin, DataExportViewMixin, ListCre filter_backends = SEARCH_ORDER_FILTER - filterset_fields = [ - 'is_customer', - 'is_manufacturer', - 'is_supplier', - 'name', - 'active', - ] + filterset_class = CompanyFilter search_fields = ['name', 'description', 'website', 'tax_id'] @@ -145,6 +152,8 @@ class ManufacturerPartFilter(FilterSet): field_name='manufacturer__active', label=_('Manufacturer is Active') ) + tags = common.filters.TagsFilter(label=_('Tags')) + class ManufacturerOutputOptions(OutputConfiguration): """Available output options for the ManufacturerPart endpoints.""" @@ -299,6 +308,8 @@ class SupplierPartFilter(FilterSet): else: return queryset.exclude(in_stock__gt=0) + tags = common.filters.TagsFilter(label=_('Tags')) + class SupplierPartOutputOptions(OutputConfiguration): """Available output options for the SupplierPart endpoints.""" diff --git a/src/backend/InvenTree/company/migrations/0019_auto_20200413_0642.py b/src/backend/InvenTree/company/migrations/0019_auto_20200413_0642.py index 0fc852354b..d4d33f9697 100644 --- a/src/backend/InvenTree/company/migrations/0019_auto_20200413_0642.py +++ b/src/backend/InvenTree/company/migrations/0019_auto_20200413_0642.py @@ -15,7 +15,7 @@ TESTING = 'test' in sys.argv def clear(): if not TESTING: # pragma: no cover - os.system('cls' if os.name == 'nt' else 'clear') + os.system('cls' if os.name == 'nt' else 'clear') # ty:ignore[deprecated] def reverse_association(apps, schema_editor): # pragma: no cover diff --git a/src/backend/InvenTree/company/migrations/0080_company_tags.py b/src/backend/InvenTree/company/migrations/0080_company_tags.py new file mode 100644 index 0000000000..42f3da00a0 --- /dev/null +++ b/src/backend/InvenTree/company/migrations/0080_company_tags.py @@ -0,0 +1,29 @@ +# Generated by Django 5.2.14 on 2026-06-03 10:07 + +import taggit.managers +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("company", "0079_auto_20260212_1054"), + ( + "taggit", + "0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx", + ), + ] + + operations = [ + migrations.AddField( + model_name="company", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/src/backend/InvenTree/company/models.py b/src/backend/InvenTree/company/models.py index 431f7ae11b..0f4453148b 100644 --- a/src/backend/InvenTree/company/models.py +++ b/src/backend/InvenTree/company/models.py @@ -2,7 +2,7 @@ import os from decimal import Decimal -from typing import TypedDict +from typing import Optional, TypedDict from django.apps import apps from django.conf import settings @@ -17,7 +17,6 @@ from django.utils.translation import gettext_lazy as _ from django.utils.translation import pgettext_lazy as __ from moneyed import CURRENCIES -from taggit.managers import TaggableManager import common.currency import common.models @@ -80,6 +79,7 @@ class Company( InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeNotesMixin, + InvenTree.models.InvenTreeTagsMixin, report.mixins.InvenTreeReportMixin, InvenTree.models.InvenTreeImageMixin, InvenTree.models.InvenTreeMetadataModel, @@ -229,7 +229,8 @@ class Company( ) @property - def address(self): + @report.mixins.report_attribute() + def address(self) -> Optional[str]: """Return the string representation for the primary address. This property exists for backwards compatibility @@ -239,7 +240,8 @@ class Company( return str(addr) if addr is not None else None @property - def primary_address(self): + @report.mixins.report_attribute() + def primary_address(self) -> Optional['Address']: """Returns address object of primary address for this Company.""" # We may have a pre-fetched primary address list if hasattr(self, 'primary_address_list'): @@ -254,7 +256,8 @@ class Company( return self.addresses.filter(primary=True).first() @property - def currency_code(self): + @report.mixins.report_attribute() + def currency_code(self) -> str: """Return the currency code associated with this company. - If the currency code is invalid, use the default currency @@ -276,7 +279,8 @@ class Company( return InvenTree.helpers.pui_url(f'/purchasing/manufacturer/{self.id}') @property - def parts(self): + @report.mixins.report_attribute() + def parts(self) -> report.mixins.QuerySet['SupplierPart']: """Return SupplierPart objects which are supplied or manufactured by this company.""" return SupplierPart.objects.filter( Q(supplier=self.id) | Q(manufacturer_part__manufacturer=self.id) @@ -487,6 +491,7 @@ class ManufacturerPart( InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNotesMixin, + InvenTree.models.InvenTreeTagsMixin, InvenTree.models.InvenTreeMetadataModel, ): """Represents a unique part as provided by a Manufacturer Each ManufacturerPart is identified by a MPN (Manufacturer Part Number) Each ManufacturerPart is also linked to a Part object. A Part may be available from multiple manufacturers. @@ -559,8 +564,6 @@ class ManufacturerPart( help_text=_('Manufacturer part description'), ) - tags = TaggableManager(blank=True) - @classmethod def create(cls, part, manufacturer, mpn, description, link=None): """Check if ManufacturerPart instance does not already exist then create it.""" @@ -603,6 +606,7 @@ class SupplierPart( InvenTree.models.InvenTreeParameterMixin, InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeBarcodeMixin, + InvenTree.models.InvenTreeTagsMixin, InvenTree.models.InvenTreeNotesMixin, common.models.MetaMixin, InvenTree.models.InvenTreeModel, @@ -621,7 +625,6 @@ class SupplierPart( note: Longer form note field base_cost: Base charge added to order independent of quantity e.g. "Reeling Fee" multiple: Multiple that the part is provided in - lead_time: Supplier lead time packaging: packaging that the part is supplied in, e.g. "Reel" pack_quantity: Quantity of item supplied in a single pack (e.g. 30ml in a single tube) pack_quantity_native: Pack quantity, converted to "native" units of the referenced part @@ -640,8 +643,6 @@ class SupplierPart( # This model was moved from the 'Part' app db_table = 'part_supplierpart' - tags = TaggableManager(blank=True) - @staticmethod def get_api_url(): """Return the API URL associated with the SupplierPart model.""" @@ -1043,15 +1044,27 @@ class SupplierPriceBreak(common.models.PriceBreak): ) def after_save_supplier_price(sender, instance, created, **kwargs): """Callback function when a SupplierPriceBreak is created or updated.""" - if ( - ( - InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING) - and not InvenTree.ready.isImportingData() - ) - and instance.part - and instance.part.part - ): - instance.part.part.schedule_pricing_update(create=True) + from part.models import Part + + if not InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING): + return + + if InvenTree.ready.isImportingData(): + return + + try: + supplier_part = instance.part + except SupplierPart.DoesNotExist: + # The underlying SupplierPart instance has been deleted + return + + try: + base_part = supplier_part.part + except Part.DoesNotExist: + # The underlying Part instance has been deleted + return + + base_part.schedule_pricing_update(create=True) @receiver( @@ -1061,12 +1074,24 @@ def after_save_supplier_price(sender, instance, created, **kwargs): ) def after_delete_supplier_price(sender, instance, **kwargs): """Callback function when a SupplierPriceBreak is deleted.""" - if ( - ( - InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING) - and not InvenTree.ready.isImportingData() - ) - and instance.part - and instance.part.part - ): - instance.part.part.schedule_pricing_update(create=False) + from part.models import Part + + if not InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING): + return + + if InvenTree.ready.isImportingData(): + return + + try: + supplier_part = instance.part + except SupplierPart.DoesNotExist: + # The underlying SupplierPart instance has been deleted + return + + try: + base_part = supplier_part.part + except Part.DoesNotExist: + # The underlying Part instance has been deleted + return + + base_part.schedule_pricing_update(create=False) diff --git a/src/backend/InvenTree/company/serializers.py b/src/backend/InvenTree/company/serializers.py index 0ff71a39bc..809f06710f 100644 --- a/src/backend/InvenTree/company/serializers.py +++ b/src/backend/InvenTree/company/serializers.py @@ -1,5 +1,6 @@ """JSON serializers for Company app.""" +from django.db import transaction from django.db.models import Prefetch from django.utils.translation import gettext_lazy as _ @@ -14,13 +15,14 @@ from importer.registry import register_importer from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.ready import isGeneratingSchema from InvenTree.serializers import ( + DuplicateOptionsSerializer, FilterableSerializerMixin, InvenTreeCurrencySerializer, InvenTreeDecimalField, InvenTreeImageSerializerField, InvenTreeModelSerializer, InvenTreeMoneySerializer, - InvenTreeTagModelSerializer, + InvenTreeTaggitSerializer, NotesFieldMixin, OptionalField, ) @@ -108,6 +110,7 @@ class AddressBriefSerializer(InvenTreeModelSerializer): class CompanySerializer( FilterableSerializerMixin, DataImportExportSerializerMixin, + InvenTreeTaggitSerializer, NotesFieldMixin, InvenTreeModelSerializer, ): @@ -117,6 +120,8 @@ class CompanySerializer( import_exclude_fields = ['image'] + SKIP_CREATE_FIELDS = ['duplicate'] + class Meta: """Metaclass options.""" @@ -131,6 +136,7 @@ class CompanySerializer( 'email', 'currency', 'contact', + 'duplicate', 'link', 'image', 'active', @@ -143,6 +149,7 @@ class CompanySerializer( 'primary_address', 'tax_id', 'parameters', + 'tags', ] @staticmethod @@ -185,8 +192,27 @@ class CompanySerializer( help_text=_('Default currency used for this supplier'), required=True ) + tags = common.filters.enable_tags_filter() + parameters = common.filters.enable_parameters_filter() + duplicate = DuplicateOptionsSerializer(Company.objects.all(), copy_parameters=True) + + @transaction.atomic + def create(self, validated_data): + """Create a new Company instance, optionally copying data from an existing company.""" + duplicate = validated_data.pop('duplicate', None) + + instance = super().create(validated_data) + + if duplicate: + original = duplicate['original'] + + if duplicate.get('copy_parameters', True): + instance.copy_parameters_from(original) + + return instance + @register_importer() class ContactSerializer(DataImportExportSerializerMixin, InvenTreeModelSerializer): @@ -207,11 +233,14 @@ class ContactSerializer(DataImportExportSerializerMixin, InvenTreeModelSerialize class ManufacturerPartSerializer( FilterableSerializerMixin, DataImportExportSerializerMixin, - InvenTreeTagModelSerializer, + InvenTreeTaggitSerializer, NotesFieldMixin, + InvenTreeModelSerializer, ): """Serializer for ManufacturerPart object.""" + SKIP_CREATE_FIELDS = ['duplicate'] + class Meta: """Metaclass options.""" @@ -224,6 +253,7 @@ class ManufacturerPartSerializer( 'manufacturer', 'manufacturer_detail', 'description', + 'duplicate', 'MPN', 'link', 'barcode_hash', @@ -236,6 +266,25 @@ class ManufacturerPartSerializer( parameters = common.filters.enable_parameters_filter() + duplicate = DuplicateOptionsSerializer( + ManufacturerPart.objects.all(), copy_parameters=True + ) + + @transaction.atomic + def create(self, validated_data): + """Create a new ManufacturerPart instance, optionally copying data from an existing instance.""" + duplicate = validated_data.pop('duplicate', None) + + instance = super().create(validated_data) + + if duplicate: + original = duplicate['original'] + + if duplicate.get('copy_parameters', True): + instance.copy_parameters_from(original) + + return instance + part_detail = OptionalField( serializer_class=part_serializers.PartBriefSerializer, serializer_kwargs={ @@ -308,8 +357,9 @@ class SupplierPriceBreakBriefSerializer( class SupplierPartSerializer( FilterableSerializerMixin, DataImportExportSerializerMixin, - InvenTreeTagModelSerializer, + InvenTreeTaggitSerializer, NotesFieldMixin, + InvenTreeModelSerializer, ): """Serializer for SupplierPart object.""" @@ -317,6 +367,8 @@ class SupplierPartSerializer( export_exclude_fields = ['tags'] + SKIP_CREATE_FIELDS = ['duplicate'] + export_child_fields = [ 'part_detail.name', 'part_detail.description', @@ -333,6 +385,7 @@ class SupplierPartSerializer( 'available', 'availability_updated', 'description', + 'duplicate', 'in_stock', 'on_order', 'link', @@ -488,6 +541,10 @@ class SupplierPartSerializer( # Date fields updated = serializers.DateTimeField(allow_null=True, read_only=True) + duplicate = DuplicateOptionsSerializer( + SupplierPart.objects.all(), copy_parameters=True + ) + @staticmethod def annotate_queryset(queryset): """Annotate the SupplierPart queryset with extra fields. @@ -516,8 +573,11 @@ class SupplierPartSerializer( return response + @transaction.atomic def create(self, validated_data): """Extract manufacturer data and process ManufacturerPart.""" + duplicate = validated_data.pop('duplicate', None) + # Extract 'available' quantity from the serializer available = validated_data.pop('available', None) @@ -535,6 +595,12 @@ class SupplierPartSerializer( kwargs = {'manufacturer': manufacturer, 'MPN': MPN} supplier_part.save(**kwargs) + if duplicate: + original = duplicate['original'] + + if duplicate.get('copy_parameters', True): + supplier_part.copy_parameters_from(original) + return supplier_part diff --git a/src/backend/InvenTree/company/test_api.py b/src/backend/InvenTree/company/test_api.py index 8570991643..7285ac69b9 100644 --- a/src/backend/InvenTree/company/test_api.py +++ b/src/backend/InvenTree/company/test_api.py @@ -478,7 +478,7 @@ class ManufacturerTest(InvenTreeAPITestCase): 'supplier_part', ] - roles = ['part.add', 'part.change'] + roles = ['part.add', 'part.change', 'purchase_order.view'] def test_manufacturer_part_list(self): """Test the ManufacturerPart API list functionality.""" diff --git a/src/backend/InvenTree/company/tests.py b/src/backend/InvenTree/company/tests.py index b5389bfbeb..3187b0ee36 100644 --- a/src/backend/InvenTree/company/tests.py +++ b/src/backend/InvenTree/company/tests.py @@ -1,7 +1,6 @@ """Unit tests for the models in the 'company' app.""" import os -from decimal import Decimal from django.core.exceptions import ValidationError from django.test import TestCase @@ -99,24 +98,6 @@ class CompanySimpleTest(TestCase): self.assertEqual(p(45), 315) self.assertEqual(p(55), 68.75) - def test_part_pricing(self): - """Unit tests for supplier part pricing.""" - m2x4 = Part.objects.get(name='M2x4 LPHS') - - self.assertEqual(m2x4.get_price_info(5.5), '38.5 - 41.25') - self.assertEqual(m2x4.get_price_info(10), '70 - 75') - self.assertEqual(m2x4.get_price_info(100), '125 - 350') - - pmin, pmax = m2x4.get_price_range(5) - self.assertEqual(pmin, 35) - self.assertEqual(pmax, 37.5) - - m3x12 = Part.objects.get(name='M3x12 SHCS') - - self.assertEqual(m3x12.get_price_info(0.3), Decimal('2.4')) - self.assertEqual(m3x12.get_price_info(3), Decimal('24')) - self.assertIsNotNone(m3x12.get_price_info(50)) - def test_currency_validation(self): """Test validation for currency selection.""" # Create a company with a valid currency code (should pass) diff --git a/src/backend/InvenTree/config_template.yaml b/src/backend/InvenTree/config_template.yaml index 4b790e7c17..a3fa90bef5 100644 --- a/src/backend/InvenTree/config_template.yaml +++ b/src/backend/InvenTree/config_template.yaml @@ -162,6 +162,11 @@ cors: # regex: +# Throttling is applied to the API by default to make DoS attacks more difficult; these can be disabled by setting them to None. +# throttle: +# anon: '20/minute' +# user: '60/second' + # MEDIA_ROOT is the local filesystem location for storing uploaded files #media_root: '/home/inventree/data/media' @@ -236,6 +241,12 @@ ldap: # INVENTREE_DEFAULT_CURRENCY: 'CNY' # INVENTREE_RESTRICT_ABOUT: true +# Override plugin settings (by plugin slug) +# Settings specified here will be locked and cannot be changed via the UI +#plugin_settings: +# plugin-slug: +# SETTING_KEY: 'value' + # Storage configuration # Ref: https://docs.inventree.org/en/stable/start/config/#storage-backends storage: diff --git a/src/backend/InvenTree/data_exporter/mixins.py b/src/backend/InvenTree/data_exporter/mixins.py index f40ee113f2..af1b971db8 100644 --- a/src/backend/InvenTree/data_exporter/mixins.py +++ b/src/backend/InvenTree/data_exporter/mixins.py @@ -16,6 +16,7 @@ from taggit.serializers import TagListSerializerField import data_exporter.serializers import data_exporter.tasks import InvenTree.exceptions +import InvenTree.serializers from common.models import DataOutput from InvenTree.helpers import str2bool from InvenTree.tasks import offload_task @@ -64,6 +65,14 @@ class DataExportSerializerMixin: # Exclude fields which are not required for data export for field in self.get_export_exclude_fields(**kwargs): self.fields.pop(field, None) + + # Duplication options are never used for data export + for field in [ + name + for name, field in self.fields.items() + if isinstance(field, InvenTree.serializers.DuplicateOptionsSerializer) + ]: + self.fields.pop(field, None) else: # Exclude fields which are only used for data export for field in self.get_export_only_fields(**kwargs): @@ -99,6 +108,10 @@ class DataExportSerializerMixin: fields.update(self.get_child_fields(name, field)) continue + # Skip 'many' fields (e.g. nested serializers) + if getattr(field, 'many', False): + continue + fields[name] = field return fields diff --git a/src/backend/InvenTree/data_exporter/serializers.py b/src/backend/InvenTree/data_exporter/serializers.py index de535a74a1..c5d01d6196 100644 --- a/src/backend/InvenTree/data_exporter/serializers.py +++ b/src/backend/InvenTree/data_exporter/serializers.py @@ -23,8 +23,18 @@ class DataExportOptionsSerializer(serializers.Serializer): - The exact nature of the available fields depends on which plugin is selected. - The selected plugin may 'extend' the fields available in the serializer. """ - # Reset fields to a known state - self.Meta.fields = ['export_format', 'export_plugin'] + + # Give this instance its own 'Meta.fields' list, appended to below depending + # on which plugin is selected. `Meta` is otherwise a single class-level + # object shared by every instance of this serializer - mutating its 'fields' + # list in place would let concurrent requests selecting different plugins + # corrupt each other's field list. + class Meta(self.Meta): + """Per-instance metaclass options for this serializer.""" + + fields = ['export_format', 'export_plugin'] + + self.Meta = Meta # Generate a list of plugins to choose from # If a model type is provided, use this to filter the list of plugins diff --git a/src/backend/InvenTree/generic/states/__init__.py b/src/backend/InvenTree/generic/states/__init__.py index f0eb63ba64..b33592139a 100644 --- a/src/backend/InvenTree/generic/states/__init__.py +++ b/src/backend/InvenTree/generic/states/__init__.py @@ -6,15 +6,23 @@ There is a rendered state for each state value. The rendered state is used for d States can be extended with custom options for each InvenTree instance - those options are stored in the database and need to link back to state values. """ +from django_fsm import RETURN_VALUE, can_proceed + from . import fields +from .deprecations import Deprecations, deprecated from .states import ColorEnum, StatusCode, StatusCodeMixin -from .transition import StateTransitionMixin, TransitionMethod +from .transition import StateTransitionMixin, TransitionMethod, inventree_transition __all__ = [ + 'RETURN_VALUE', # django_fsm import 'ColorEnum', + 'Deprecations', 'StateTransitionMixin', 'StatusCode', 'StatusCodeMixin', 'TransitionMethod', + 'can_proceed', # django_fsm import + 'deprecated', 'fields', + 'inventree_transition', ] diff --git a/src/backend/InvenTree/generic/states/deprecations.py b/src/backend/InvenTree/generic/states/deprecations.py new file mode 100644 index 0000000000..42af31afa8 --- /dev/null +++ b/src/backend/InvenTree/generic/states/deprecations.py @@ -0,0 +1,27 @@ +"""Helper for deprecating old implementation details.""" + +from enum import Enum +from typing import Any, Optional + +# py (3, 12) does not ship with depreciation decorator, so we need to import it from typing_extensions +try: + from warnings import deprecated as warn_deprecated # ty: ignore[unresolved-import] +except ImportError: + from typing_extensions import deprecated as warn_deprecated + + +class Deprecations(Enum): + """Deprecations for states.""" + + CAN_PROCEED = 'Use can_proceed directly' + + +class deprecated(warn_deprecated): # noqa: N801 + """Deprecation decorator for state transition methods.""" + + def __init__( + self, message: Any | str, version: Optional[str] = None, *args, **kwargs + ): + """Initialize the decorator with a deprecation reason.""" + self.version = version + super().__init__(str(message), *args, **kwargs) diff --git a/src/backend/InvenTree/generic/states/fields.py b/src/backend/InvenTree/generic/states/fields.py index 0ca677b4ab..3a69531b4a 100644 --- a/src/backend/InvenTree/generic/states/fields.py +++ b/src/backend/InvenTree/generic/states/fields.py @@ -3,11 +3,13 @@ from collections.abc import Iterable from typing import Any, Optional +from django.apps import apps as global_apps from django.core.exceptions import ObjectDoesNotExist from django.db import models from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ +from django_fsm import FSMFieldMixin from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import extend_schema_field from rest_framework import serializers @@ -89,11 +91,19 @@ class ExtraCustomChoiceField(CustomChoiceField): return super().to_representation(value) or value -class InvenTreeCustomStatusModelField(models.PositiveIntegerField): +class InvenTreeCustomStatusModelField(FSMFieldMixin, models.PositiveIntegerField): """Custom model field for extendable status codes. - Adds a secondary *_custom_key field to the model which can be used to store additional status information. - Models using this model field must also include the InvenTreeCustomStatusSerializerMixin in all serializers that create or update the value. + Extends Django's PositiveIntegerField with FSM (Finite State Machine) support + via django-fsm-2, enabling use of the @transition decorator directly on model + methods that use this field. + + Adds a secondary *_custom_key field to the model which can be used to store + additional status information. + + Models using this model field must also include the + InvenTreeCustomStatusSerializerMixin in all serializers that create or update + the value. """ def __init__(self, *args, **kwargs): @@ -108,20 +118,38 @@ class InvenTreeCustomStatusModelField(models.PositiveIntegerField): validators.append(CustomStatusCodeValidator(status_class=self.status_class)) kwargs['validators'] = validators + # FSM protection is disabled by default; direct status assignment is still allowed + kwargs.setdefault('protected', False) super().__init__(*args, **kwargs) def deconstruct(self): - """Deconstruct the field for migrations.""" - name, path, args, kwargs = super().deconstruct() + """Deconstruct the field for migrations. + FSM-specific kwargs (protected) are excluded to avoid spurious migrations, + since they do not affect the database schema. + """ + name, path, args, kwargs = super().deconstruct() + kwargs.pop('protected', None) return name, path, args, kwargs def contribute_to_class(self, cls, name): - """Add the _custom_key field to the model.""" + """Add the _custom_key field to the model. + + Only auto-add the companion field for the 'live' app registry. Any other + registry (migration state, or the throwaway model registries that some + backends - e.g. SQLite's table-rebuild routine - construct internally) + either already has the field explicitly declared, or will get it via a + separate migration operation. Auto-adding it there too would create a + duplicate field on the model. + """ cls._meta.supports_custom_status = True - if not hasattr(self, '_custom_key_field') and not hasattr( - cls, f'{name}_custom_key' + is_live_model = cls._meta.apps is global_apps + + if ( + is_live_model + and not hasattr(self, '_custom_key_field') + and not hasattr(cls, f'{name}_custom_key') ): self.add_field(cls, name) @@ -169,7 +197,7 @@ class InvenTreeCustomStatusModelField(models.PositiveIntegerField): class ExtraInvenTreeCustomStatusModelField(models.PositiveIntegerField): - """Custom field used to detect custom extenteded fields. + """Custom field used to detect custom extended fields. This is not intended to be used directly, if you want to support custom states in your model use InvenTreeCustomStatusModelField. """ @@ -190,6 +218,12 @@ class InvenTreeCustomStatusSerializerMixin: _custom_fields_follower: Optional[list] = None _is_gathering = False + # Maps leader field name -> a throwaway instance of that field, built by + # `build_standard_field` as it constructs each leader field. Used by a + # later 'follower' (*_custom_key) field, built later in the same pass, + # to inherit choices/read_only state - see `build_standard_field` below. + _custom_leader_fields: Optional[dict] = None + def update(self, instance, validated_data): """Ensure the custom field is updated if the leader was changed.""" self.gather_custom_fields() @@ -260,6 +294,31 @@ class InvenTreeCustomStatusSerializerMixin: """Use custom field for custom status model. This is required because of DRF overwriting all fields with choice sets. + + Note: This method is called *while* the serializer's `fields` cached_property + is still being constructed (DRF builds fields one at a time, in `Meta.fields` + order). It must not access `self.fields` (or anything that does, like + `self.gather_custom_fields()`) - doing so would re-enter the `fields` + cached_property while it is already being computed, kicking off a second, + fully independent rebuild of the whole field set. Under concurrent access, + whichever of the two competing builds finishes last silently wins and gets + cached - intermittently dropping unrelated fields built earlier in the + original pass (e.g. an OptionalField like `tags`) if the second build + finishes without them. + + Instead, a 'leader' field (e.g. `status`) records a throwaway instance of + itself on `self._custom_leader_fields` as it is built, so that its + 'follower' field (`status_custom_key`), built later in the same pass, can + read its choices/read_only state directly - without touching `self.fields`. + + That throwaway instance must be built the same way DRF's own `get_fields()` + builds the *real* one - which includes merging in `Meta.extra_kwargs` / + `Meta.read_only_fields` (e.g. `status` is typically listed as read-only + there). DRF applies that merge itself, in `get_fields()`, *after* + `build_field()` returns - a step this method is never otherwise party to. + Both `get_extra_kwargs()` and `include_extra_kwargs()` are pure functions + of `self.Meta` / plain dicts, so - unlike `self.fields` - they're safe to + call here. """ field_cls, field_kwargs = super().build_standard_field(field_name, model_field) if issubclass(field_cls, ChoiceField) and isinstance( @@ -268,6 +327,14 @@ class InvenTreeCustomStatusSerializerMixin: field_cls = CustomChoiceField field_kwargs['choice_mdl'] = model_field.model field_kwargs['choice_field'] = model_field.name + + if self._custom_leader_fields is None: + self._custom_leader_fields = {} + leader_extra_kwargs = self.get_extra_kwargs().get(field_name, {}) + leader_kwargs = self.include_extra_kwargs( + dict(field_kwargs), leader_extra_kwargs + ) + self._custom_leader_fields[field_name] = field_cls(**leader_kwargs) elif isinstance(model_field, ExtraInvenTreeCustomStatusModelField): field_cls = ExtraCustomChoiceField field_kwargs['choice_mdl'] = model_field.model @@ -275,10 +342,10 @@ class InvenTreeCustomStatusSerializerMixin: field_kwargs['is_custom'] = True # Inherit choices from leader - self.gather_custom_fields() - if self._custom_fields and field_name in self._custom_fields: - leader_field_name = field_name.replace('_custom_key', '') - leader_field = self.fields[leader_field_name] + leader_field_name = field_name.replace('_custom_key', '') + leader_field = (self._custom_leader_fields or {}).get(leader_field_name) + + if leader_field is not None: if hasattr(leader_field, 'choices'): field_kwargs['choices'] = list(leader_field.choices.items()) elif hasattr(model_field.model, leader_field_name): diff --git a/src/backend/InvenTree/generic/states/states.py b/src/backend/InvenTree/generic/states/states.py index 697166645d..72b531da9e 100644 --- a/src/backend/InvenTree/generic/states/states.py +++ b/src/backend/InvenTree/generic/states/states.py @@ -9,8 +9,8 @@ from typing import Optional logger = logging.getLogger('inventree') -class BaseEnum(enum.IntEnum): # noqa: PLW1641 - """An `Enum` capabile of having its members have docstrings. +class BaseEnum(enum.IntEnum): + """An `Enum` capable of having its members have docstrings. Based on https://stackoverflow.com/questions/19330460/how-do-i-put-docstrings-on-enums """ @@ -42,6 +42,14 @@ class BaseEnum(enum.IntEnum): # noqa: PLW1641 return super().__eq__(obj) + def __hash__(self): + """Return integer hash so enum members are usable as dict keys and in sets. + + Required because we define ``__eq__``: Python sets ``__hash__ = None`` + when ``__eq__`` is overridden without a matching ``__hash__``. + """ + return hash(self.value) + def __ne__(self, obj): """Override inequality operator to allow comparison with int.""" if type(self) is type(obj): @@ -262,7 +270,7 @@ class ColorEnum(Enum): class StatusCodeMixin: """Mixin class which handles custom 'status' fields. - - Implements a 'set_stutus' method which can be used to set the status of an object + - Implements a 'set_status' method which can be used to set the status of an object - Implements a 'get_status' method which can be used to retrieve the status of an object This mixin assumes that the implementing class has a 'status' field, @@ -282,7 +290,11 @@ class StatusCodeMixin: - Ensure custom status code values are correctly updated """ - if self.status_class: + # Only need to verify the custom key against the DB if one is actually set - + # the 'key' column on InvenTreeCustomUserStateModel is non-nullable, so a + # query for key=None (i.e. no custom status) can never match and would only + # ever result in a no-op (custom_key is already None in that case). + if self.status_class and self.get_custom_status() is not None: # Check that the current 'logical key' actually matches the current status code custom_values = self.status_class.custom_queryset().filter( logical_key=self.get_status(), key=self.get_custom_status() diff --git a/src/backend/InvenTree/generic/states/test_transition.py b/src/backend/InvenTree/generic/states/test_transition.py index b8cb3c371d..6c3f248683 100644 --- a/src/backend/InvenTree/generic/states/test_transition.py +++ b/src/backend/InvenTree/generic/states/test_transition.py @@ -2,22 +2,158 @@ from django.core.exceptions import ValidationError +from generic.states import can_proceed from InvenTree.unit_test import InvenTreeTestCase -from order.models import ReturnOrder -from order.status_codes import ReturnOrderStatus +from order.models import PurchaseOrder, ReturnOrder, SalesOrder, TransferOrder +from order.status_codes import ( + PurchaseOrderStatus, + ReturnOrderStatus, + SalesOrderStatus, + TransferOrderStatus, +) from plugin import registry +from users.models import Owner class TransitionTests(InvenTreeTestCase): """Tests for custom state transition logic.""" - fixtures = ['company', 'return_order', 'part', 'stock', 'location', 'category'] - def setUp(self): """Set up the test environment.""" super().setUp() self.ensurePluginsLoaded() + fixtures = [ + 'company', + 'supplier_part', + 'category', + 'part', + 'location', + 'stock', + 'order', + 'sales_order', + 'return_order', + 'transfer_order', + ] + + def test_fsm_decorator_applied_to_purchase_order(self): + """Verify @inventree_transition metadata is attached to PurchaseOrder methods.""" + # Methods decorated with @inventree_transition expose _django_fsm metadata + self.assertTrue(hasattr(PurchaseOrder.place_order, '_django_fsm')) + self.assertTrue(hasattr(PurchaseOrder.complete_order, '_django_fsm')) + self.assertTrue(hasattr(PurchaseOrder.hold_order, '_django_fsm')) + self.assertTrue(hasattr(PurchaseOrder.cancel_order, '_django_fsm')) + + def test_fsm_can_proceed_purchase_order(self): + """Test can_proceed() reflects current state correctly for PurchaseOrder.""" + po = PurchaseOrder.objects.filter( + status=PurchaseOrderStatus.PENDING.value + ).first() + assert po + + # A PENDING order can be placed or cancelled, but not completed + self.assertTrue(po.can_issue) + self.assertTrue(po.can_cancel) + self.assertFalse(can_proceed(po.complete_order)) + self.assertTrue(po.is_open) + + # depreceted methods + self.assertTrue(po.can_hold) + + def test_fsm_purchase_order_transitions(self): + """Test that PurchaseOrder transitions work correctly via @inventree_transition.""" + po = PurchaseOrder.objects.filter( + status=PurchaseOrderStatus.PENDING.value + ).first() + assert po + + # Place the order (PENDING → PLACED) + result = po.place_order() + self.assertTrue(result) + po.refresh_from_db() + self.assertEqual(po.status, PurchaseOrderStatus.PLACED.value) + + # Hold the order (PLACED → ON_HOLD) + result = po.hold_order() + self.assertTrue(result) + po.refresh_from_db() + self.assertEqual(po.status, PurchaseOrderStatus.ON_HOLD.value) + + # Place again from ON_HOLD (ON_HOLD → PLACED) + result = po.place_order() + self.assertTrue(result) + po.refresh_from_db() + self.assertEqual(po.status, PurchaseOrderStatus.PLACED.value) + + # Cancel the order (PLACED → CANCELLED) + result = po.cancel_order() + self.assertTrue(result) + po.refresh_from_db() + self.assertEqual(po.status, PurchaseOrderStatus.CANCELLED.value) + + def test_fsm_sale_order_transitions(self): + """Test that SaleOrder transitions work correctly via @inventree_transition.""" + so = SalesOrder.objects.filter(status=SalesOrderStatus.PENDING.value).first() + assert so + + # deprecated methods + self.assertTrue(so.can_issue) + self.assertTrue(so.can_hold) + self.assertTrue(so.can_cancel) + + def test_fsm_invalid_transition_returns_false(self): + """Test that an invalid transition returns False (backward-compatible behaviour).""" + po = PurchaseOrder.objects.filter( + status=PurchaseOrderStatus.CANCELLED.value + ).first() + assert po + + # Attempting to place a cancelled order must raise + with self.assertRaises(ValidationError): + po.place_order() + + # The order status must remain CANCELLED + po.refresh_from_db() + self.assertEqual(po.status, PurchaseOrderStatus.CANCELLED.value) + + def test_fsm_return_order_transitions(self): + """Test that ReturnOrder transitions work correctly via @inventree_transition.""" + ro = ReturnOrder.objects.filter( + status=ReturnOrderStatus.IN_PROGRESS.value + ).first() + assert ro + + # Can complete an IN_PROGRESS return order + self.assertTrue(can_proceed(ro.complete_order)) + + # Cannot issue an IN_PROGRESS return order (already issued) + self.assertFalse(can_proceed(ro.issue_order)) + + # deprecated methods + self.assertTrue(ro.can_hold) + self.assertTrue(ro.can_cancel) + self.assertFalse(ro.can_issue) + + def test_fsm_transferorder(self): + """Test that TransferOrder transitions work correctly via @inventree_transition.""" + to = TransferOrder.objects.filter( + status=TransferOrderStatus.PENDING.value + ).first() + assert to + + self.assertTrue(to.can_issue) + self.assertTrue(to.can_hold) + self.assertTrue(to.can_cancel) + + def test_fsm_can_issue_property(self): + """Test the can_issue property delegates to can_proceed.""" + po = PurchaseOrder.objects.filter( + status=PurchaseOrderStatus.PENDING.value + ).first() + assert po + + self.assertEqual(po.can_issue, can_proceed(po.place_order)) + def test_return_order(self): """Test transition of a return order.""" # Ensure plugin is enabled @@ -36,6 +172,13 @@ class TransitionTests(InvenTreeTestCase): str(e.exception), ) + ro.responsible = Owner.create(obj=self.user) + ro.save() + result = ro.complete_order() + self.assertEqual(result, '123#abc!') + # There should be no change in the status of the return order + self.assertEqual(ro.status, ReturnOrderStatus.IN_PROGRESS.value) + # Now disable the plugin registry.set_plugin_state('sample-transition', False) @@ -61,9 +204,6 @@ class TransitionTests(InvenTreeTestCase): ro = ReturnOrder.objects.get(pk=2) self.assertEqual(ro.status, ReturnOrderStatus.IN_PROGRESS.value) - # Transition to "ON HOLD" state - ro.hold_order() - # Ensure plugin starts in a known state plugin = registry.get_plugin('sample-broken-transition') plugin.set_setting('BROKEN_GET_METHOD', False) @@ -76,7 +216,7 @@ class TransitionTests(InvenTreeTestCase): with self.assertWarnsMessage(UserWarning, msg): # No error should occur here - ro.complete_order() + ro.hold_order() self.assertEqual(ro.status, ReturnOrderStatus.ON_HOLD.value) # No error should be logged @@ -91,7 +231,7 @@ class TransitionTests(InvenTreeTestCase): ro.issue_order() self.assertEqual(ro.status, ReturnOrderStatus.IN_PROGRESS.value) - # Ensure correct eroror was logged + # Ensure correct error was logged self.assertIn('Invalid transition handler type: 1', str(cm.output[0])) # Now, enable the "WRONG_RETURN_TYPE" setting @@ -121,3 +261,7 @@ class TransitionTests(InvenTreeTestCase): self.assertIn( "ValueError('This is a broken transition plugin!')", str(cm.output[0]) ) + + # Ensure the plugin is now disabled + registry.set_plugin_state('sample-transition', False) + registry.set_plugin_state('sample-broken-transition', False) diff --git a/src/backend/InvenTree/generic/states/transition.py b/src/backend/InvenTree/generic/states/transition.py index 80ae2f7f3c..e33eba079f 100644 --- a/src/backend/InvenTree/generic/states/transition.py +++ b/src/backend/InvenTree/generic/states/transition.py @@ -1,18 +1,138 @@ """Classes and functions for plugin controlled object state transitions.""" from collections.abc import Callable +from enum import Enum +from functools import wraps +from django.core.exceptions import ValidationError +from django.db import transaction from django.db.models import Model import structlog +from django_fsm import TransitionNotAllowed, transition + +from plugin.events import trigger_event + +from .deprecations import deprecated logger = structlog.get_logger('inventree') -class TransitionMethod: - """Base class for all transition classes. +def inventree_transition( + field, source, target, event=None, refresh_field: bool = True, **extra +): + """Decorator that combines ``@django_fsm.transition`` with plugin transitions. - Must implement a method called `transition` that takes both args and kwargs. + Wraps a model method so that: + * Source/target state validation is enforced via ``django_fsm.transition``. + * Plugin transitions are called automatically before the FSM transition executes. + * The model instance is saved after a successful transition. + * The whole operation is wrapped in a database transaction. + + Usage:: + + class MyOrder(StateTransitionMixin, models.Model): + status = InvenTreeCustomStatusModelField( + status_class=MyOrderStatus, ... + ) + + @inventree_transition( + field=status, + source=[MyOrderStatus.PENDING, MyOrderStatus.ON_HOLD], + target=MyOrderStatus.PLACED, + event=MyOrderEvents.PLACED, + refresh_field=False, + ) + def place_order(self): + notify_responsible(...) + + The ``can_`` guard pattern can be preserved using ``can_proceed``:: + + @property + def can_issue(self) -> bool: + return can_proceed(self.place_order) + + Args: + field: The ``InvenTreeCustomStatusModelField`` (or its string name) that holds the state. + source: Allowed source state(s) for the transition. + target: Target state after the transition. + event: Optional event (name) to trigger after the transition. If not provided no event is triggered. + refresh_field: (default True) If True, the field is updated from the database before the transition. + **extra: Additional keyword arguments forwarded to `django_fsm.transition` (e.g. `conditions`, `on_error`, `permission`). + """ + + def decorator(func): + # Apply the django-fsm @transition decorator first. + fsm_func = transition(field=field, source=source, target=target, **extra)(func) + + @transaction.atomic + @wraps(func) + def wrapper(self, *args, **kwargs): + """Ensure that transitions are handled correctly.""" + if refresh_field: + try: + # Update the field from the database to avoid race conditions + current_obj = type(self).objects.select_for_update().get(pk=self.pk) + new_value = getattr(current_obj, field.name) + setattr(self, field.name, new_value) + except type(self).DoesNotExist: # pragma: no cover + raise ValidationError( + f'{self._meta.verbose_name} with pk={self.pk} does not exist in the database' + ) + + # Run plugin transition handlers - if no step is taken the decorated method is called + if result := _run_plugin_transition_handlers( + self, + getattr(self, field.name), + target, + default_action=_noop_default_action, + ): + return result + + # Execute the FSM-wrapped function. This validates the source state, + # runs the method body, and updates the field to the target state. + try: + fsm_func(self, *args, **kwargs) + except TransitionNotAllowed as exc: + # Preserve backward-compatible behaviour: an invalid transition + # (wrong source state, failed condition, or explicit raise inside + # the method body) returns False rather than raising. + if getattr(self, field.name) == target: + target_val = ( + target.label + if isinstance(target, Enum) and hasattr(target, 'label') + else target + ) + raise ValidationError( + f'{self._meta.verbose_name} is already {target_val}' + ) from exc + raise ValidationError( + f'Invalid transition on {self._meta.verbose_name}.{field.name} (source value should be {source}, is {getattr(self, field.name)})' + ) from exc + # Persist all changes (including the updated status field) to the DB. + self.save() + + # trigger event for the transition + if event: + trigger_event(event, id=self.pk) + + return True + + # Propagate the django-fsm metadata so that can_proceed() works correctly + # on the public wrapper method. + if hasattr(fsm_func, '_django_fsm'): + wrapper._django_fsm = fsm_func._django_fsm + return wrapper + + return decorator + + +class TransitionMethod: + """Base class for all plugin-defined transition handler classes. + + A plugin transition handler is called for every state transition on a + ``StateTransitionMixin`` model. Subclasses must implement a ``transition`` + method. """ def __init__(self) -> None: @@ -37,33 +157,36 @@ class TransitionMethod: ) -> bool: """Perform a state transition. - Success: - - The custom transition logic succeeded - - Return True result - - No further transitions are attempted - Ignore: - - The custom transition logic did not apply - - Return False result - - Further transitions are attempted (if available) - - Default action is called if no transition was successful - Failure: - - The custom transition logic failed - - Raise a ValidationError - - No further transitions are attempted - - Default action is not called + When used with ``@inventree_transition``-decorated methods, plugin + handlers are invoked before the decorated method body executes. + The semantics are: + + * **Ignore** - return ``False``. Further handlers are attempted; + the decorated method body executes as normal. + * **Veto** - raise ``ValidationError``. The transition is cancelled; + no further handlers are called; the method body does *not* execute. + * **Handle** (deprecated) - return ``True``. This historically meant + "I handled the transition; skip the default action." Under + ``@inventree_transition``, the decorated method body *always* runs, so + returning ``True`` now only triggers a ``DeprecationWarning``. Plugin + authors should raise ``ValidationError`` to cancel a transition, or + return ``False`` to allow it to proceed. Arguments: current_state: int - Current state of the instance. target_state: int - Target state to transition to. instance: Model - The object instance to transition. - default_action: callable - Default action to be taken if no transition is successful. + default_action: callable - No-op when called from the + ``inventree_transition`` wrapper; present for backward + compatibility. **kwargs: Additional keyword arguments for custom logic. Returns: - result: bool - True if the transition method was successful, False otherwise. + result: bool - ``True`` triggers a deprecation warning (see above). + ``False`` allows the transition to proceed normally. Raises: - ValidationError: Alert the user that the transition failed + ValidationError: Cancels the transition. """ raise NotImplementedError( 'TransitionMethod.transition must be implemented' @@ -71,63 +194,96 @@ class TransitionMethod: class StateTransitionMixin: - """Mixin class to enable state transitions. + """Mixin class to enable plugin-controlled state transitions. - This mixin is used to add state transitions handling to a model. With this you can apply custom logic to state transitions via plugins. - ```python - class MyModel(StateTransitionMixin, models.Model): - def some_dummy_function(self, *args, **kwargs): - pass + Add this mixin to a Django model to gain: - def action(self, *args, **kwargs): - self.handle_transition(0, 1, self, self.some_dummy_function) - ``` + * Plugin hook support for all ``@inventree_transition``-decorated methods + (via the ``inventree_transition`` decorator). + * A legacy ``handle_transition`` method for backward compatibility with + code that calls it directly. + + Example:: + + class MyOrder(StateTransitionMixin, models.Model): + status = InvenTreeCustomStatusModelField( + status_class=MyOrderStatus, ... + ) + + @inventree_transition( + field=status, + source=[MyOrderStatus.PENDING], + target=MyOrderStatus.PLACED, + ) + def place_order(self): + pass """ + @deprecated('Use the @inventree_transition decorator instead', version='1.5.0') def handle_transition( self, current_state, target_state, instance, default_action, **kwargs - ): + ): # pragma: no cover """Handle a state transition for an object. + .. deprecated:: + Use the ``@inventree_transition`` decorator instead. This method + is kept for backward compatibility only and calls the ``default_action`` + directly without invoking the django-fsm machinery or signals. + Args: current_state: Current state of instance target_state: Target state of instance instance: Object instance - default_action: Default action to be taken if none of the transitions returns a boolean true value + default_action: Default action to be taken if none of the + transitions returns a boolean true value """ - from InvenTree.exceptions import log_error - from plugin import PluginMixinEnum, registry - - transition_plugins = registry.with_mixin(PluginMixinEnum.STATE_TRANSITION) - - for plugin in transition_plugins: - try: - handlers = plugin.get_transition_handlers() - except Exception: - log_error('get_transition_handlers', plugin=plugin) - continue - - if type(handlers) is not list: - logger.error( - 'INVE-E9: Plugin %s returned invalid type for transition handlers', - plugin.slug, - ) - continue - - for handler in handlers: - if not isinstance(handler, TransitionMethod): - logger.error( - 'INVE-E9: Invalid transition handler type: %s', handler - ) - continue - - # Call the transition method - result = handler.transition( - current_state, target_state, instance, default_action, **kwargs - ) - - if result: - return result - - # Default action + if result := _run_plugin_transition_handlers( + instance, current_state, target_state, default_action=default_action + ): + return result return default_action(current_state, target_state, instance, **kwargs) + + +def _run_plugin_transition_handlers(instance, source, target, default_action): + """Run plugin transition handlers before a state transition. + + A plugin handler may veto the transition by raising a ``ValidationError``. + """ + if not isinstance(instance, StateTransitionMixin) or not isinstance( + instance, Model + ): + return # pragma: no cover + + from InvenTree.exceptions import log_error + from plugin import PluginMixinEnum, registry + + transition_plugins = registry.with_mixin(PluginMixinEnum.STATE_TRANSITION) + + for plugin in transition_plugins: + try: + handlers = plugin.get_transition_handlers() + except Exception: + log_error('get_transition_handlers', plugin=plugin) + continue + + if type(handlers) is not list: + logger.error( + 'INVE-E9: Plugin %s returned invalid type for transition handlers', + plugin.slug, + ) + continue + + for handler in handlers: + if not isinstance(handler, TransitionMethod): + logger.error('INVE-E9: Invalid transition handler type: %s', handler) + continue + + # Call the transition method. + # ValidationError raised here will propagate and cancel the transition. + if result := handler.transition(source, target, instance, default_action): + return result + + +def _noop_default_action(current_state, target_state, instance, **kwargs): + """No-op default action for compatibility with transition handlers.""" + return None # pragma: no cover diff --git a/src/backend/InvenTree/importer/api.py b/src/backend/InvenTree/importer/api.py index c64f71c654..fd8c6024fd 100644 --- a/src/backend/InvenTree/importer/api.py +++ b/src/backend/InvenTree/importer/api.py @@ -115,6 +115,10 @@ class DataImportSessionAcceptFields(APIView): """Accept the field mapping for a DataImportSession.""" session = get_object_or_404(importer.models.DataImportSession, pk=pk) + # Check session ownership + if not request.user.is_staff and session.user != request.user: + raise PermissionDenied() + # Check that the user has permission to accept the field mapping if model_class := session.model_class: if not check_user_permission(request.user, model_class, 'change'): @@ -137,17 +141,45 @@ class DataImportSessionAcceptRows(DataImporterPermissionMixin, CreateAPI): ctx = super().get_serializer_context() try: - ctx['session'] = importer.models.DataImportSession.objects.get( + session = importer.models.DataImportSession.objects.get( pk=self.kwargs.get('pk', None) ) - except Exception: - pass + except importer.models.DataImportSession.DoesNotExist: + session = None + + if session: + user = self.request.user + if not user.is_staff and session.user != user: + raise PermissionDenied() + ctx['session'] = session ctx['request'] = self.request return ctx -class DataImportColumnMappingList(DataImporterPermissionMixin, ListAPI): +class DataImportSessionChildMixin(DataImporterPermissionMixin): + """Mixin for DataImportRow and DataImportColumnMap views. + + Ensures users can only access objects that belong to an import session they own. + Staff users retain access to all objects. + """ + + def get_queryset(self): + """Return only objects whose session belongs to the requesting user.""" + queryset = super().get_queryset() + + try: + user = self.request.user + except AttributeError: + raise PermissionDenied('User information is not available') + + if user.is_staff: + return queryset + + return queryset.filter(session__user=user) + + +class DataImportColumnMappingList(DataImportSessionChildMixin, ListAPI): """API endpoint for accessing a list of DataImportColumnMap objects.""" queryset = importer.models.DataImportColumnMap.objects.all() @@ -158,14 +190,14 @@ class DataImportColumnMappingList(DataImporterPermissionMixin, ListAPI): filterset_fields = ['session'] -class DataImportColumnMappingDetail(DataImporterPermissionMixin, RetrieveUpdateAPI): +class DataImportColumnMappingDetail(DataImportSessionChildMixin, RetrieveUpdateAPI): """Detail endpoint for a single DataImportColumnMap object.""" queryset = importer.models.DataImportColumnMap.objects.all() serializer_class = importer.serializers.DataImportColumnMapSerializer -class DataImportRowList(DataImporterPermissionMixin, BulkDeleteMixin, ListAPI): +class DataImportRowList(DataImportSessionChildMixin, BulkDeleteMixin, ListAPI): """API endpoint for accessing a list of DataImportRow objects.""" queryset = importer.models.DataImportRow.objects.all() @@ -180,7 +212,7 @@ class DataImportRowList(DataImporterPermissionMixin, BulkDeleteMixin, ListAPI): ordering = 'row_index' -class DataImportRowDetail(DataImporterPermissionMixin, RetrieveUpdateDestroyAPI): +class DataImportRowDetail(DataImportSessionChildMixin, RetrieveUpdateDestroyAPI): """Detail endpoint for a single DataImportRow object.""" queryset = importer.models.DataImportRow.objects.all() diff --git a/src/backend/InvenTree/importer/migrations/0006_dataimportcolumnmap_lookup_field.py b/src/backend/InvenTree/importer/migrations/0006_dataimportcolumnmap_lookup_field.py new file mode 100644 index 0000000000..a6bda2f824 --- /dev/null +++ b/src/backend/InvenTree/importer/migrations/0006_dataimportcolumnmap_lookup_field.py @@ -0,0 +1,24 @@ +# Generated migration + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("importer", "0005_dataimportsession_update_records"), + ] + + operations = [ + migrations.AddField( + model_name="dataimportcolumnmap", + name="lookup_field", + field=models.CharField( + blank=True, + null=True, + max_length=100, + verbose_name="Lookup Field", + help_text="Database field to use for foreign-key lookup. Leave blank for automatic lookup.", + ), + ), + ] diff --git a/src/backend/InvenTree/importer/migrations/0007_dataimportsession_completed_row_count_history_and_more.py b/src/backend/InvenTree/importer/migrations/0007_dataimportsession_completed_row_count_history_and_more.py new file mode 100644 index 0000000000..c70be9e5b3 --- /dev/null +++ b/src/backend/InvenTree/importer/migrations/0007_dataimportsession_completed_row_count_history_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.15 on 2026-06-17 05:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('importer', '0006_dataimportcolumnmap_lookup_field'), + ] + + operations = [ + migrations.AddField( + model_name='dataimportsession', + name='completed_row_count_history', + field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Completed Row Count History'), + ), + migrations.AddField( + model_name='dataimportsession', + name='row_count_history', + field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Row Count History'), + ), + ] diff --git a/src/backend/InvenTree/importer/migrations/0008_alter_dataimportrow_data_alter_dataimportrow_errors_and_more.py b/src/backend/InvenTree/importer/migrations/0008_alter_dataimportrow_data_alter_dataimportrow_errors_and_more.py new file mode 100644 index 0000000000..3688af1d03 --- /dev/null +++ b/src/backend/InvenTree/importer/migrations/0008_alter_dataimportrow_data_alter_dataimportrow_errors_and_more.py @@ -0,0 +1,88 @@ +# Generated by Django 5.2.16 on 2026-08-08 01:36 + +import django.core.serializers.json +import importer.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("importer", "0007_dataimportsession_completed_row_count_history_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="dataimportrow", + name="data", + field=models.JSONField( + blank=True, + encoder=django.core.serializers.json.DjangoJSONEncoder, + null=True, + verbose_name="Data", + ), + ), + migrations.AlterField( + model_name="dataimportrow", + name="errors", + field=models.JSONField( + blank=True, + encoder=django.core.serializers.json.DjangoJSONEncoder, + null=True, + verbose_name="Errors", + ), + ), + migrations.AlterField( + model_name="dataimportrow", + name="row_data", + field=models.JSONField( + blank=True, + encoder=django.core.serializers.json.DjangoJSONEncoder, + null=True, + verbose_name="Original row data", + ), + ), + migrations.AlterField( + model_name="dataimportsession", + name="columns", + field=models.JSONField( + blank=True, + encoder=django.core.serializers.json.DjangoJSONEncoder, + null=True, + verbose_name="Columns", + ), + ), + migrations.AlterField( + model_name="dataimportsession", + name="field_defaults", + field=models.JSONField( + blank=True, + encoder=django.core.serializers.json.DjangoJSONEncoder, + null=True, + validators=[importer.validators.validate_field_defaults], + verbose_name="Field Defaults", + ), + ), + migrations.AlterField( + model_name="dataimportsession", + name="field_filters", + field=models.JSONField( + blank=True, + encoder=django.core.serializers.json.DjangoJSONEncoder, + null=True, + validators=[importer.validators.validate_field_defaults], + verbose_name="Field Filters", + ), + ), + migrations.AlterField( + model_name="dataimportsession", + name="field_overrides", + field=models.JSONField( + blank=True, + encoder=django.core.serializers.json.DjangoJSONEncoder, + null=True, + validators=[importer.validators.validate_field_defaults], + verbose_name="Field Overrides", + ), + ), + ] diff --git a/src/backend/InvenTree/importer/mixins.py b/src/backend/InvenTree/importer/mixins.py index 969f82afa2..9cd5401606 100644 --- a/src/backend/InvenTree/importer/mixins.py +++ b/src/backend/InvenTree/importer/mixins.py @@ -3,6 +3,8 @@ from rest_framework import fields, serializers from taggit.serializers import TagListSerializerField +import InvenTree.serializers + class DataImportSerializerMixin: """Mixin class for adding data import functionality to a DRF serializer.""" @@ -41,6 +43,14 @@ class DataImportSerializerMixin: for field in self.get_import_exclude_fields(**kwargs): self.fields.pop(field, None) + # Duplication options are never used for data import + for field in [ + name + for name, field in self.fields.items() + if isinstance(field, InvenTree.serializers.DuplicateOptionsSerializer) + ]: + self.fields.pop(field, None) + else: # Exclude fields which are only used for data import for field in self.get_import_only_fields(**kwargs): diff --git a/src/backend/InvenTree/importer/models.py b/src/backend/InvenTree/importer/models.py index 8dae1376ab..6c6f1f6f34 100644 --- a/src/backend/InvenTree/importer/models.py +++ b/src/backend/InvenTree/importer/models.py @@ -6,9 +6,11 @@ from datetime import datetime from typing import Optional from django.contrib.auth.models import User +from django.core.exceptions import FieldDoesNotExist from django.core.exceptions import ValidationError as DjangoValidationError +from django.core.serializers.json import DjangoJSONEncoder from django.core.validators import FileExtensionValidator -from django.db import models +from django.db import models, transaction from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -81,7 +83,9 @@ class DataImportSession(models.Model): ], ) - columns = models.JSONField(blank=True, null=True, verbose_name=_('Columns')) + columns = models.JSONField( + blank=True, null=True, verbose_name=_('Columns'), encoder=DjangoJSONEncoder + ) model_type = models.CharField( blank=False, @@ -106,6 +110,7 @@ class DataImportSession(models.Model): null=True, verbose_name=_('Field Defaults'), validators=[importer.validators.validate_field_defaults], + encoder=DjangoJSONEncoder, ) field_overrides = models.JSONField( @@ -113,6 +118,7 @@ class DataImportSession(models.Model): null=True, verbose_name=_('Field Overrides'), validators=[importer.validators.validate_field_defaults], + encoder=DjangoJSONEncoder, ) field_filters = models.JSONField( @@ -120,6 +126,7 @@ class DataImportSession(models.Model): null=True, verbose_name=_('Field Filters'), validators=[importer.validators.validate_field_defaults], + encoder=DjangoJSONEncoder, ) update_records = models.BooleanField( @@ -152,6 +159,36 @@ class DataImportSession(models.Model): return supported_models().get(self.model_type, None) + def get_lookup_fields_for_field(self, field_name: str) -> list: + """Return the valid lookup fields for a given related (FK) field. + + Returns a list of field names that can be used as a lookup key, + consisting of 'pk' plus any fields defined in IMPORT_ID_FIELDS on the related model. + """ + model = self.get_related_model(field_name) + + if not model: + return ['pk'] + + id_fields = ['pk'] + + if custom_fields := getattr(model, 'IMPORT_ID_FIELDS', None): + id_fields += custom_fields + + return id_fields + + @property + def field_lookup_mapping(self) -> dict: + """Return a dict of field -> lookup_field mappings for this import session. + + Only entries where lookup_field is explicitly set are included. + """ + return { + mapping.field: mapping.lookup_field + for mapping in self.column_mappings.all() + if mapping.lookup_field + } + def get_related_model(self, field_name: str) -> Optional[models.Model]: """Return the related model for a given field name. @@ -170,7 +207,7 @@ class DataImportSession(models.Model): related_field = model_class._meta.get_field(field_name) model = related_field.remote_field.model return model - except (AttributeError, models.FieldDoesNotExist): + except (AttributeError, FieldDoesNotExist): return None def extract_columns(self) -> None: @@ -206,7 +243,14 @@ class DataImportSession(models.Model): # Extract a "default" value for the field, if one exists # Skip if one has already been provided by the user - if field not in self.field_defaults and 'default' in field_def: + # Skip entirely when updating existing records - a model-level "creation" + # default (e.g. quantity=1) must not silently overwrite existing data + # for fields the user hasn't chosen to map or default + if ( + not self.update_records + and field not in self.field_defaults + and 'default' in field_def + ): self.field_defaults[field] = field_def['default'] # Generate a list of possible column names for this field @@ -310,7 +354,7 @@ class DataImportSession(models.Model): logger.error('Failed to load data file') return - headers = df.headers + headers = importer.operations.normalize_headers(df.headers) imported_rows = [] @@ -344,15 +388,28 @@ class DataImportSession(models.Model): self.save() def check_complete(self) -> bool: - """Check if the import session is complete.""" + """Check if the import session is complete. + + When all rows have been accepted, the rows and column mappings are + deleted as they are no longer needed. The session itself is retained + as an audit record. + """ if self.completed_row_count < self.row_count: return False - # Update the status of this session if self.status != DataImportStatusCode.COMPLETE.value: self.status = DataImportStatusCode.COMPLETE.value + + # persist historic count values for reporting purposes + self.completed_row_count_history = self.completed_row_count + self.row_count_history = self.row_count + self.save() + # Clear staging data now that all rows have been imported + self.rows.all().delete() + self.column_mappings.all().delete() + return True @property @@ -365,6 +422,14 @@ class DataImportSession(models.Model): """Return the number of completed rows for this session.""" return self.rows.filter(complete=True).count() + # Historic values for reporting purposes + completed_row_count_history = models.PositiveIntegerField( + blank=True, null=True, verbose_name=_('Completed Row Count History') + ) + row_count_history = models.PositiveIntegerField( + blank=True, null=True, verbose_name=_('Row Count History') + ) + def available_fields(self): """Returns information on the available fields. @@ -401,6 +466,11 @@ class DataImportSession(models.Model): if field.get('read_only', False): continue + if field.get('type') == 'related field': + field['lookup_fields'] = self.get_lookup_fields_for_field( + field_name + ) + fields[field_name] = field # Cache the available fields against this instance @@ -415,11 +485,14 @@ class DataImportSession(models.Model): required = {} for field, info in fields.items(): - if info.get('required', False): - required[field] = info - - elif self.update_records and field == self.ID_FIELD_LABEL: - # If we are updating records, the ID field is required + if self.update_records: + # When updating existing records, only the ID field is required - + # all other fields fall back to the existing value on the record + # being updated, so the serializer's usual "required" flag + # (which applies to *creating* a new instance) does not apply here + if field == self.ID_FIELD_LABEL: + required[field] = info + elif info.get('required', False): required[field] = info return required @@ -488,6 +561,22 @@ class DataImportColumnMap(models.Model): if field_def.get('read_only', False): raise DjangoValidationError({'field': _('Selected field is read-only')}) + if self.lookup_field: + if field_def.get('type') != 'related field': + raise DjangoValidationError({ + 'lookup_field': _( + 'Lookup field can only be set for related (foreign-key) fields' + ) + }) + + valid_lookup_fields = self.session.get_lookup_fields_for_field(self.field) + if self.lookup_field not in valid_lookup_fields: + raise DjangoValidationError({ + 'lookup_field': _( + 'Invalid lookup field. Valid options are: {options}' + ).format(options=', '.join(valid_lookup_fields)) + }) + session = models.ForeignKey( DataImportSession, on_delete=models.CASCADE, @@ -499,6 +588,16 @@ class DataImportColumnMap(models.Model): column = models.CharField(blank=True, max_length=100, verbose_name=_('Column')) + lookup_field = models.CharField( + blank=True, + null=True, + max_length=100, + verbose_name=_('Lookup Field'), + help_text=_( + 'Database field to use for foreign-key lookup. Leave blank for automatic lookup.' + ), + ) + @property def available_fields(self): """Return a list of available fields for this import session. @@ -575,12 +674,19 @@ class DataImportRow(models.Model): row_index = models.PositiveIntegerField(default=0, verbose_name=_('Row Index')) row_data = models.JSONField( - blank=True, null=True, verbose_name=_('Original row data') + blank=True, + null=True, + verbose_name=_('Original row data'), + encoder=DjangoJSONEncoder, ) - data = models.JSONField(blank=True, null=True, verbose_name=_('Data')) + data = models.JSONField( + blank=True, null=True, verbose_name=_('Data'), encoder=DjangoJSONEncoder + ) - errors = models.JSONField(blank=True, null=True, verbose_name=_('Errors')) + errors = models.JSONField( + blank=True, null=True, verbose_name=_('Errors'), encoder=DjangoJSONEncoder + ) valid = models.BooleanField(default=False, verbose_name=_('Valid')) @@ -631,9 +737,12 @@ class DataImportRow(models.Model): default_values = self.default_values data = {} + extract_errors = {} self.related_field_map = {} + field_lookup_mapping = self.session.field_lookup_mapping + # We have mapped column (file) to field (serializer) already for field, col in field_mapping.items(): # Data override (force value and skip any further checks) @@ -661,7 +770,17 @@ class DataImportRow(models.Model): elif field_type == 'date': value = self.convert_date_field(value) elif field_type == 'related field': - value = self.lookup_related_field(field, value) + try: + value = self.lookup_related_field( + field, value, lookup_field=field_lookup_mapping.get(field) + ) + except DjangoValidationError as exc: + # exc.message only exists if the error was raised with a single + # message string - lookup_related_field may also raise with a + # dict (message_dict) or list (message), so use exc.messages, + # which normalizes any construction to a flat list of strings. + extract_errors[field] = '; '.join(exc.messages) + continue # Use the default value, if provided if value is None and field in default_values: @@ -703,6 +822,9 @@ class DataImportRow(models.Model): self.data = data + if extract_errors: + self.errors = extract_errors + if commit: self.save() @@ -726,7 +848,9 @@ class DataImportRow(models.Model): # If none of the formats matched, return the original value return value - def lookup_related_field(self, field_name: str, value: str) -> Optional[int]: + def lookup_related_field( + self, field_name: str, value: str, lookup_field: Optional[str] = None + ) -> Optional[int]: """Try to perform lookup against a related field. - This is used to convert a human-readable value (e.g. a supplier name) into a database reference (e.g. supplier ID). @@ -735,6 +859,7 @@ class DataImportRow(models.Model): Arguments: field_name: The name of the field to perform the lookup against value: The value to be looked up + lookup_field: If provided, only query this specific model field (skips auto-lookup) Returns: A primary key value @@ -758,21 +883,35 @@ class DataImportRow(models.Model): 'session': f'No related model found for field: {field_name}' }) - valid_items = set() - base_filters = ( self.session.field_filters.get(field_name, {}) if self.session.field_filters else {} ) - # First priority is the PK (primary key) field + if lookup_field and type(lookup_field) is str: + # A specific lookup field has been chosen by the user — query only that field + try: + queryset = model.objects.filter(**{lookup_field: value}, **base_filters) + except ValueError: + return value + + results = list(queryset[:2]) + + if len(results) == 1: + return results[0].pk + + # Zero or multiple results — return raw value and let serializer report the error + return value + + # Auto-lookup: try pk first, then any model-defined IMPORT_ID_FIELDS id_fields = ['pk'] if custom_id_fields := getattr(model, 'IMPORT_ID_FIELDS', None): id_fields += custom_id_fields - # Iterate through the provided list - if any of the values match, we can perform the lookup + valid_items = set() + for id_field in id_fields: try: queryset = model.objects.filter(**{id_field: value}, **base_filters) @@ -782,15 +921,19 @@ class DataImportRow(models.Model): # Evaluate at most two results to determine if there is exactly one match results = list(queryset[:2]) if len(results) == 1: - # We have a single match against this field valid_items.add(results[0].pk) if len(valid_items) == 1: - # We found a single valid match against the related model - return this value return valid_items.pop() - # We found either zero or multiple values matching against the related model - # Return the original value and let the serializer validation handle any errors against this field + if len(valid_items) > 1: + raise DjangoValidationError( + _( + 'Multiple matches found for value - please ensure the value is unique, or select a specific lookup field' + ) + ) + + # No match found - return the original value and let the serializer validation handle it return value def serializer_data(self): @@ -817,58 +960,42 @@ class DataImportRow(models.Model): return serializer_class( instance=instance, data=self.serializer_data(), + # When updating an existing instance, treat this as a partial + # update - fields not present in the imported data should fall + # back to the existing value on the record, not fail validation + # or be overwritten with a blank/default value + partial=instance is not None, context={'request': request}, ) - def validate(self, commit=False, request=None) -> bool: - """Validate the data in this row against the linked serializer. + def _get_update_instance(self, instance_id, queryset): + """Fetch the target instance for an update, recording any error against this row. Arguments: - commit: If True, the data is saved to the database (if validation passes) - request: The request object (if available) for extracting user information + instance_id: The primary key of the instance to fetch + queryset: The queryset to fetch the instance from (may be locked) Returns: - True if the data is valid, False otherwise - - Raises: - ValidationError: If the linked serializer is not valid + The fetched instance, or None if it could not be found/resolved """ - if self.complete: - # Row has already been completed - return True + try: + return queryset.get(pk=instance_id) + except self.session.model_class.DoesNotExist: + self.errors = { + 'non_field_errors': _('No record found with the provided ID') + + f': {instance_id}' + } + except ValueError: + self.errors = { + 'non_field_errors': _('Invalid ID format provided') + f': {instance_id}' + } + except Exception as e: + self.errors = {'non_field_errors': str(e)} - if self.session.update_records: - # Extract the ID field from the data - instance_id = self.data.get(self.session.ID_FIELD_LABEL, None) - - if not instance_id: - raise DjangoValidationError( - _('ID is required for updating existing records.') - ) - - try: - instance = self.session.model_class.objects.get(pk=instance_id) - except self.session.model_class.DoesNotExist: - self.errors = { - 'non_field_errors': _('No record found with the provided ID') - + f': {instance_id}' - } - return False - except ValueError: - self.errors = { - 'non_field_errors': _('Invalid ID format provided') - + f': {instance_id}' - } - return False - except Exception as e: - self.errors = {'non_field_errors': str(e)} - return False - - serializer = self.construct_serializer(instance=instance, request=request) - - else: - serializer = self.construct_serializer(request=request) + return None + def _process_serializer(self, serializer, commit) -> bool: + """Run is_valid() against the provided serializer, and save it if requested.""" if not serializer: self.errors = { 'non_field_errors': 'No serializer class linked to this import session' @@ -898,3 +1025,69 @@ class DataImportRow(models.Model): self.session.check_complete() return result + + def validate(self, commit=False, request=None) -> bool: + """Validate the data in this row against the linked serializer. + + Arguments: + commit: If True, the data is saved to the database (if validation passes) + request: The request object (if available) for extracting user information + + Returns: + True if the data is valid, False otherwise + + Raises: + ValidationError: If the linked serializer is not valid + """ + if self.complete: + # Row has already been completed + return True + + if self.errors: + # Errors were set during data extraction (e.g. ambiguous FK lookup) + return False + + if self.session.update_records: + # Extract the ID field from the data + instance_id = self.data.get(self.session.ID_FIELD_LABEL, None) + + if not instance_id: + raise DjangoValidationError( + _('ID is required for updating existing records.') + ) + + queryset = self.session.model_class.objects + + if commit: + # Lock the target row for the duration of the transaction. Without + # this, another process could modify the record between this read + # and the serializer.save() call in _process_serializer() - and as + # save() writes the *entire* instance (not just the fields present + # in the imported data), that concurrent change would be silently + # lost (a "lost update" race). The lock is held until the save + # completes below, so a concurrent writer blocks until this commit + # finishes rather than racing against it. + with transaction.atomic(): + instance = self._get_update_instance( + instance_id, queryset.select_for_update() + ) + + if instance is None: + return False + + serializer = self.construct_serializer( + instance=instance, request=request + ) + return self._process_serializer(serializer, commit) + + instance = self._get_update_instance(instance_id, queryset) + + if instance is None: + return False + + serializer = self.construct_serializer(instance=instance, request=request) + + else: + serializer = self.construct_serializer(request=request) + + return self._process_serializer(serializer, commit) diff --git a/src/backend/InvenTree/importer/operations.py b/src/backend/InvenTree/importer/operations.py index 0efca9017c..fec9cc1567 100644 --- a/src/backend/InvenTree/importer/operations.py +++ b/src/backend/InvenTree/importer/operations.py @@ -44,7 +44,15 @@ def load_data_file(data_file, file_format=None): # Excel formats expect binary data if file_format not in ['xls', 'xlsx']: - data = data.decode() + # Attempt to decode the file data as UTF-8 first, falling back to + # cp1252 (common for CSV files exported from Excel on Windows) + try: + data = data.decode('utf-8-sig') + except UnicodeDecodeError: + try: + data = data.decode('cp1252') + except UnicodeDecodeError: + raise ValidationError(_('Could not decode data file as text')) try: data = tablib.Dataset().load(data, headers=True, format=file_format) @@ -72,17 +80,33 @@ def extract_column_names(data_file) -> list: """ data = load_data_file(data_file) - headers = [] + return normalize_headers(data.headers) - for idx, header in enumerate(data.headers): + +def normalize_headers(headers) -> list: + """Normalize a list of raw column headers extracted from a data file. + + Strips whitespace from each header, and generates a default header + for any column that does not have one. Must be used consistently + wherever column headers are extracted, so that column names used for + field mapping match the column names used when extracting row data. + + Args: + headers: List of raw header values (as returned by tablib) + + Returns: + List of normalized column names + """ + result = [] + + for idx, header in enumerate(headers): if header: - header = str(header).strip() - headers.append(header) + result.append(str(header).strip()) else: # If the header is empty, generate a default header - headers.append(f'Column {idx + 1}') + result.append(f'Column {idx + 1}') - return headers + return result def get_field_label(field) -> Optional[str]: diff --git a/src/backend/InvenTree/importer/serializers.py b/src/backend/InvenTree/importer/serializers.py index 2e428b7e9b..566322e310 100644 --- a/src/backend/InvenTree/importer/serializers.py +++ b/src/backend/InvenTree/importer/serializers.py @@ -23,7 +23,15 @@ class DataImportColumnMapSerializer(InvenTreeModelSerializer): """Meta class options for the serializer.""" model = importer.models.DataImportColumnMap - fields = ['pk', 'session', 'column', 'field', 'label', 'description'] + fields = [ + 'pk', + 'session', + 'column', + 'field', + 'label', + 'description', + 'lookup_field', + ] read_only_fields = ['field', 'session'] label = serializers.CharField(read_only=True) @@ -54,6 +62,8 @@ class DataImportSessionSerializer(InvenTreeModelSerializer): 'field_filters', 'row_count', 'completed_row_count', + 'completed_row_count_history', + 'row_count_history', ] read_only_fields = ['pk', 'user', 'status', 'columns'] @@ -88,7 +98,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer): if type(defaults) is not dict: try: defaults = json.loads(str(defaults)) - except: + except json.JSONDecodeError: + raise ValidationError(_('Invalid field defaults')) + + if type(defaults) is not dict: raise ValidationError(_('Invalid field defaults')) return defaults @@ -101,7 +114,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer): if type(overrides) is not dict: try: overrides = json.loads(str(overrides)) - except: + except json.JSONDecodeError: + raise ValidationError(_('Invalid field overrides')) + + if type(overrides) is not dict: raise ValidationError(_('Invalid field overrides')) return overrides @@ -114,7 +130,10 @@ class DataImportSessionSerializer(InvenTreeModelSerializer): if type(filters) is not dict: try: filters = json.loads(str(filters)) - except: + except json.JSONDecodeError: + raise ValidationError(_('Invalid field filters')) + + if type(filters) is not dict: raise ValidationError(_('Invalid field filters')) return filters @@ -161,6 +180,28 @@ class DataImportRowSerializer(InvenTreeModelSerializer): 'complete', ] + def update(self, instance, validated_data): + """Allow manual editing of extracted row data. + + This is used by the importer UI when a user manually corrects a row, + for example by selecting a missing foreign-key target. In that case, + the edited ``data`` payload must become the source of truth for + subsequent validation, rather than being silently ignored in favor of + the original ``row_data`` extracted from the import file. + """ + if 'data' in validated_data: + instance.data = validated_data['data'] + + # Clear stale validation state so the row is re-evaluated against + # the manually edited data on save() + instance.errors = None + + # A manually edited row is not yet committed, even if it had + # previously reached a completed state + instance.complete = False + + return super().update(instance, validated_data) + class DataImportAcceptRowSerializer(serializers.Serializer): """Serializer for accepting rows of data.""" @@ -212,6 +253,8 @@ class DataImportAcceptRowSerializer(serializers.Serializer): row.validate(commit=True, request=request) if session := self.context.get('session', None): + # ensure current state is available + session.refresh_from_db() session.check_complete() return rows diff --git a/src/backend/InvenTree/importer/tests.py b/src/backend/InvenTree/importer/tests.py index 17490b9283..cfc354b581 100644 --- a/src/backend/InvenTree/importer/tests.py +++ b/src/backend/InvenTree/importer/tests.py @@ -1,11 +1,17 @@ """Unit tests for the 'importer' app.""" +import datetime import os +import threading +from unittest import mock +from django.contrib.auth.models import User from django.core.files.base import ContentFile +from django.db import connection +from django.test import TransactionTestCase, skipUnlessDBFeature from django.urls import reverse -from importer.models import DataImportRow, DataImportSession +from importer.models import DataImportColumnMap, DataImportRow, DataImportSession from InvenTree.unit_test import AdminTestCase, InvenTreeAPITestCase, InvenTreeTestCase @@ -58,20 +64,475 @@ class ImporterTest(ImporterMixin, InvenTreeTestCase): self.assertEqual(session.rows.count(), 12) # Check that some data has been imported - for row in session.rows.all(): + rows = list(session.rows.all()) + self.assertEqual(len(rows), 12) + + for row in rows: self.assertIsNotNone(row.data.get('name', None)) self.assertTrue(row.valid) row.validate(commit=True) self.assertTrue(row.complete) - self.assertEqual(session.completed_row_count, 12) + # All rows accepted: rows and mappings are cleared, session is retained + session.refresh_from_db() + self.assertEqual(session.rows.count(), 0) + self.assertEqual(session.column_mappings.count(), 0) # Check that the new companies have been created self.assertEqual(n + 12, Company.objects.count()) + def test_row_data_datetime_serialization(self): + """Test that row data containing native datetime values can be saved. + + Regression test for a Sentry crash: "Object of type datetime is not JSON + serializable when serializing dict item 'COMMENT'". Excel imports (via + tablib/openpyxl) return date-formatted cells as native datetime.datetime + objects rather than strings. These flow unmodified into row_data, which + is then persisted via DataImportRow.objects.bulk_create(). + + DataImportRow.row_data / data / errors (and the related JSONFields on + DataImportSession) previously had no `encoder=DjangoJSONEncoder`, so + Django's JSONField fell back to the plain stdlib json.JSONEncoder, which + cannot serialize datetime objects - raising a TypeError on save/bulk_create. + """ + data_file = self.helper_file('companies.csv') + + session = DataImportSession.objects.create( + data_file=data_file, model_type='company' + ) + + row = DataImportRow( + session=session, + row_index=0, + row_data={'COMMENT': datetime.datetime(2024, 5, 1, 12, 30)}, + ) + + # This must not raise: TypeError: Object of type datetime is not JSON serializable + DataImportRow.objects.bulk_create([row]) + row = DataImportRow.objects.get(session=session, row_index=0) + self.assertEqual(row.row_data['COMMENT'], '2024-05-01T12:30:00') + + def test_import_header_whitespace(self): + """Test that column headers with leading/trailing whitespace are handled correctly. + + Regression test: column mappings are built from *stripped* header names, but + row data was previously extracted using the *raw* (unstripped) headers. If a + header had surrounding whitespace, the mapped column name would never match a + key in the row data, so that field was silently skipped during import. + """ + from company.models import Company + + n = Company.objects.count() + + # Pad each header in the source file with extra whitespace + raw = self.helper_file('companies.csv').read() + lines = raw.splitlines() + headers = [f' {header} ' for header in lines[0].split(',')] + padded_data = '\n'.join([','.join(headers), *lines[1:]]) + + data_file = ContentFile(padded_data, 'companies_whitespace.csv') + + session = DataImportSession.objects.create( + data_file=data_file, model_type='company' + ) + + session.extract_columns() + + # Extracted column names should have whitespace stripped + for col in session.columns: + self.assertEqual(col, col.strip()) + + # Field mappings should be created correctly, against the *stripped* names + for field, col in [ + ('website', 'Website'), + ('is_customer', 'Is customer'), + ('phone', 'Phone number'), + ('description', 'Company description'), + ('active', 'Active'), + ]: + self.assertTrue( + session.column_mappings.filter(field=field, column=col).exists() + ) + + # Run the data import + session.import_data() + self.assertEqual(session.rows.count(), 12) + + rows = list(session.rows.all()) + + # Row data keys must be stripped, to match the mapped column names + for row in rows: + for key in row.row_data: + self.assertEqual(key, key.strip()) + + # Find the 'Arrow' row, and check that mapped fields were actually extracted + arrow_row = next(row for row in rows if row.data.get('name') == 'Arrow') + self.assertEqual(arrow_row.data.get('website'), 'https://www.arrow.com/') + self.assertEqual(arrow_row.data.get('description'), 'Arrow Electronics') + self.assertEqual(arrow_row.data.get('is_customer'), False) + + for row in rows: + self.assertIsNotNone(row.data.get('name', None)) + self.assertTrue(row.valid) + + row.validate(commit=True) + self.assertTrue(row.complete) + + # All rows accepted: rows and mappings are cleared, session is retained + session.refresh_from_db() + self.assertEqual(session.rows.count(), 0) + self.assertEqual(session.column_mappings.count(), 0) + + # Check that the new companies have been created + self.assertEqual(n + 12, Company.objects.count()) + + def test_import_encoding(self): + """Test that non-UTF-8 encoded data files are handled correctly. + + Regression test: CSV files exported from Excel on Windows are commonly + encoded as cp1252 rather than utf-8. Previously, an unhandled + UnicodeDecodeError was raised (surfaced to the user as a server error) + instead of a well-formed ValidationError. + """ + from django.core.exceptions import ValidationError as DjangoValidationError + + raw = self.helper_file('companies.csv').read() + + # Encode the file data as cp1252, including a character not valid in utf-8 + lines = raw.splitlines() + lines[1] = lines[1].replace('Arrow Electronics', 'Arrow Electronics \xb2') + cp1252_data = '\n'.join(lines).encode('cp1252') + + data_file = ContentFile(cp1252_data, 'companies_cp1252.csv') + + session = DataImportSession.objects.create( + data_file=data_file, model_type='company' + ) + + session.extract_columns() + session.import_data() + + arrow_row = next( + row for row in session.rows.all() if row.data.get('name') == 'Arrow' + ) + self.assertEqual(arrow_row.data.get('description'), 'Arrow Electronics ²') + + # A file containing bytes which are not valid in either utf-8 or cp1252 + # should raise a ValidationError, rather than an unhandled exception + invalid_data = ContentFile(b'name,website\r\n\x81\x8d,test\r\n', 'invalid.csv') + + with self.assertRaises(DjangoValidationError): + DataImportSession.objects.create( + data_file=invalid_data, model_type='company' + ).extract_columns() + def test_field_defaults(self): - """Test default field values.""" + """Test default field values. + + Regression test for bug #30 (dev/todo/bugs.md): validate_field_defaults + must reject any parsed JSON value that isn't actually a dict, not just + values which fail to parse as JSON at all. + """ + from django.core.exceptions import ValidationError as DjangoValidationError + + def data_file(): + # full_clean() reads the file eagerly, so each session needs its own + # freshly-opened (binary) copy + content = self.helper_file('companies.csv').read() + return ContentFile(content.encode(), 'companies.csv') + + # A dict value is accepted as-is + session = DataImportSession( + data_file=data_file(), model_type='company', field_defaults={'name': 'Test'} + ) + session.full_clean() + + # A JSON-encoded dict string is also accepted (de-stringified) + session = DataImportSession( + data_file=data_file(), + model_type='company', + field_defaults='{"name": "Test"}', + ) + session.full_clean() + + # A JSON-encoded list is valid JSON, but not a dict - must be rejected + session = DataImportSession( + data_file=data_file(), model_type='company', field_defaults='[1, 2, 3]' + ) + with self.assertRaises(DjangoValidationError): + session.full_clean() + + # Garbage which does not even parse as JSON must also be rejected + session = DataImportSession( + data_file=data_file(), model_type='company', field_defaults='not valid json' + ) + with self.assertRaises(DjangoValidationError): + session.full_clean() + + def test_update_existing_records(self): + """Test updating existing records via import, providing only the ID field. + + Regression test for GH #12499: when updating existing records, only the + primary key should be required. Fields which are not mapped to a column + (and have no explicit override/default) must: + - not be flagged as "required" and block the mapping wizard + - not be auto-populated with a model-level "creation" default + - not overwrite the existing value on the target record + """ + from part.models import Part, PartCategory + from stock.models import StockItem + + category = PartCategory.objects.create( + name='Update Test Category', description='Test category' + ) + part = Part.objects.create( + category=category, name='Update Test Part', description='Test part' + ) + + item = StockItem.objects.create(part=part, quantity=42, batch='Original batch') + + csv_content = f'ID,batch\n{item.pk},Updated batch\n' + data_file = ContentFile(csv_content, 'stock_update.csv') + + session = DataImportSession.objects.create( + data_file=data_file, model_type='stockitem', update_records=True + ) + + # Only the 'id' field should be required - 'quantity' and 'part' already + # exist on the target record, and must not be forced + required = session.required_fields() + self.assertIn('id', required) + self.assertNotIn('quantity', required) + self.assertNotIn('part', required) + + # No model-level "creation" default should have been auto-populated for + # 'quantity' - doing so would silently overwrite the existing value + self.assertNotIn('quantity', session.field_defaults or {}) + + # Mapping is valid, even though 'quantity' and 'part' are unmapped + session.accept_mapping() + + session.refresh_from_db() + self.assertEqual(session.rows.count(), 1) + + row = session.rows.first() + self.assertTrue(row.valid) + + # Unmapped fields must not appear in the extracted row data at all + self.assertNotIn('quantity', row.data) + self.assertNotIn('part', row.data) + + self.assertTrue(row.validate(commit=True)) + self.assertTrue(row.complete) + + # Existing values for unmapped fields must be preserved + item.refresh_from_db() + self.assertEqual(item.quantity, 42) + self.assertEqual(item.part, part) + self.assertEqual(item.batch, 'Updated batch') + + def test_lookup_field_ambiguous_match(self): + """Test the behavior of lookup_related_field for ambiguous and pinned matches.""" + from django.core.exceptions import ValidationError as DjangoValidationError + + from part.models import Part, PartCategory + + category = PartCategory.objects.create( + name='Test Category', description='Test category' + ) + + # Two parts which collide under different IMPORT_ID_FIELDS ('IPN' and 'name') + part_a = Part.objects.create( + category=category, name='Widget', description='desc', IPN='AMBIG-001' + ) + Part.objects.create( + category=category, name='AMBIG-001', description='desc', IPN='WIDGET-002' + ) + + data_file = self.helper_file('companies.csv') + session = DataImportSession.objects.create( + data_file=data_file, model_type='stockitem' + ) + + row = DataImportRow(session=session) + row.related_field_map = {} + + # Auto-lookup (no pinned lookup field) raises, as the value matches two different parts + with self.assertRaises(DjangoValidationError): + row.lookup_related_field('part', 'AMBIG-001') + + # Pinning the lookup field to 'IPN' resolves the match unambiguously + result = row.lookup_related_field('part', 'AMBIG-001', lookup_field='IPN') + self.assertEqual(result, part_a.pk) + + # Pinning the lookup field to 'name' resolves to the *other* part + result = row.lookup_related_field('part', 'AMBIG-001', lookup_field='name') + self.assertNotEqual(result, part_a.pk) + + def test_extract_data_related_field_validation_error(self): + """Test that extract_data() handles a dict-constructed ValidationError. + + Regression test: django.core.exceptions.ValidationError only exposes a + `.message` attribute when it was raised with a single message string. + lookup_related_field can also raise with a dict (e.g. "no related model + found for field") or a list, in which case `.message` does not exist and + accessing it raises: AttributeError: 'ValidationError' object has no + attribute 'message'. extract_data() must use `.messages` instead, which + normalizes any construction to a flat list of strings. + """ + from django.core.exceptions import ValidationError as DjangoValidationError + + data_file = self.helper_file('companies.csv') + session = DataImportSession.objects.create( + data_file=data_file, model_type='stockitem' + ) + + row = DataImportRow(session=session, row_data={'Website': 'foo'}) + + field_mapping = {'part': 'Website'} + available_fields = {'part': {'type': 'related field'}} + + with mock.patch.object( + DataImportRow, + 'lookup_related_field', + side_effect=DjangoValidationError({ + 'session': 'No related model found for field: part' + }), + ): + # Must not raise: AttributeError: 'ValidationError' object has no attribute 'message' + row.extract_data( + field_mapping=field_mapping, + available_fields=available_fields, + commit=False, + ) + + self.assertEqual(row.errors, {'part': 'No related model found for field: part'}) + + def test_lookup_field_validation(self): + """Test that DataImportColumnMap.clean() validates the lookup_field value.""" + from django.core.exceptions import ValidationError as DjangoValidationError + + data_file = self.helper_file('companies.csv') + session = DataImportSession.objects.create( + data_file=data_file, model_type='stockitem' + ) + + part_mapping = session.column_mappings.get(field='part') + quantity_mapping = session.column_mappings.get(field='quantity') + + # Valid lookup field for a related (FK) field + part_mapping.lookup_field = 'IPN' + part_mapping.save() + part_mapping.refresh_from_db() + self.assertEqual(part_mapping.lookup_field, 'IPN') + + # Invalid lookup field (not a valid IMPORT_ID_FIELDS option) + part_mapping.lookup_field = 'not_a_real_field' + with self.assertRaises(DjangoValidationError): + part_mapping.save() + + # lookup_field cannot be set against a non-related field + quantity_mapping.lookup_field = 'IPN' + with self.assertRaises(DjangoValidationError): + quantity_mapping.save() + + +@skipUnlessDBFeature('has_select_for_update') +class DataImportRowConcurrencyTest(ImporterMixin, TransactionTestCase): + """Genuine cross-transaction regression test for row locking during a data-import update. + + Uses two real threads (each with its own database connection) to reproduce the + lost-update race: two concurrent import rows updating *different* fields on the + same StockItem could both read the pre-update instance before either had + committed its save() - and since save() writes the *entire* instance, whichever + thread committed second would silently discard the first thread's change. + + DataImportRow.validate() now locks the target row (select_for_update, inside + transaction.atomic()) for the duration of the read-modify-write cycle, so the + second thread's read is forced to wait until the first thread's transaction + commits - and therefore sees (and preserves) the first thread's change. + """ + + def setUp(self): + """Create a single StockItem to update concurrently.""" + super().setUp() + + from part.models import Part, PartCategory + from stock.models import StockItem + + category = PartCategory.objects.create( + name='Concurrency Category', description='Test category' + ) + self.part = Part.objects.create( + category=category, name='Concurrency Part', description='Test part' + ) + self.item = StockItem.objects.create(part=self.part, quantity=10) + + def helper_session(self) -> DataImportSession: + """Construct a minimal DataImportSession configured for stock item updates.""" + return DataImportSession.objects.create( + data_file=self.helper_file('companies.csv'), + model_type='stockitem', + update_records=True, + ) + + def test_concurrent_update_does_not_lose_writes(self): + """Two concurrent updates to different fields must not clobber one another.""" + start_barrier = threading.Barrier(2, timeout=5) + errors = [] + + # Wrap DataImportRow._get_update_instance() so both threads reach the + # (real, database-level) row lock at the same time - one wins the lock + # and proceeds through to commit, the other blocks until the winner's + # transaction completes. + original_get_update_instance = DataImportRow._get_update_instance + + def synced_get_update_instance(row, instance_id, queryset): + start_barrier.wait(timeout=5) + return original_get_update_instance(row, instance_id, queryset) + + def update(field, value): + try: + row = DataImportRow( + session=self.helper_session(), + # 'part' is a required field on StockItemSerializer, so it must + # be included even though this row is only actually changing + # 'field' - the fix under test is *locking*, not partial-update + # support, so we work within the serializer's existing rules + data={'id': self.item.pk, 'part': self.part.pk, field: value}, + ) + if not row.validate(commit=True): + errors.append(row.errors) + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + with mock.patch.object( + DataImportRow, '_get_update_instance', synced_get_update_instance + ): + # Note: 'batch' is deliberately avoided here - it has a model-level + # default (generate_batch_code), and DRF applies a field's default to + # *any* non-partial update where the field is omitted, regardless of + # the existing instance value. That's a separate, already-tracked + # issue (GH #12499) and would confound this test, which is only + # about proving the row lock closes the read/write race. + thread_a = threading.Thread(target=update, args=('notes', 'notes-a')) + thread_b = threading.Thread( + target=update, args=('packaging', 'packaging-b') + ) + + thread_a.start() + thread_b.start() + thread_a.join(timeout=10) + thread_b.join(timeout=10) + + self.assertEqual(errors, []) + + self.item.refresh_from_db() + self.assertEqual(self.item.notes, 'notes-a') + self.assertEqual(self.item.packaging, 'packaging-b') class ImportAPITest(ImporterMixin, InvenTreeAPITestCase): @@ -174,6 +635,58 @@ class ImportAPITest(ImporterMixin, InvenTreeAPITestCase): # Check that there are new database records self.assertEqual(PartCategory.objects.count(), N + 4) + def test_column_mapping_lookup_field(self): + """Test that the 'lookup_field' option can be specified via the column-mapping API.""" + f = self.helper_file('companies.csv') + + session = DataImportSession.objects.create( + data_file=f, model_type='stockitem', user=self.user + ) + + self.assignRole('stock.change') + + # available_fields should expose the valid lookup field options for the 'part' FK field + session_detail = self.get( + reverse('api-import-session-detail', kwargs={'pk': session.pk}) + ).data + part_field_info = session_detail['available_fields']['part'] + self.assertIn('lookup_fields', part_field_info) + self.assertIn('IPN', part_field_info['lookup_fields']) + self.assertIn('name', part_field_info['lookup_fields']) + self.assertIn('pk', part_field_info['lookup_fields']) + + part_mapping = session.column_mappings.get(field='part') + quantity_mapping = session.column_mappings.get(field='quantity') + + mapping_url = reverse( + 'api-importer-mapping-detail', kwargs={'pk': part_mapping.pk} + ) + + # Initially, no lookup field is set (defaults to 'auto') + data = self.get(mapping_url).data + self.assertIn(data['lookup_field'], [None, '']) + + # Set a valid lookup field + data = self.patch(mapping_url, {'lookup_field': 'IPN'}, expected_code=200).data + self.assertEqual(data['lookup_field'], 'IPN') + + # Confirm it persists + data = self.get(mapping_url).data + self.assertEqual(data['lookup_field'], 'IPN') + + # An invalid lookup field is rejected + self.patch(mapping_url, {'lookup_field': 'not_a_real_field'}, expected_code=400) + + # Clear the lookup field (revert to 'auto') + data = self.patch(mapping_url, {'lookup_field': None}, expected_code=200).data + self.assertIn(data['lookup_field'], [None, '']) + + # lookup_field cannot be set against a non-related field + quantity_url = reverse( + 'api-importer-mapping-detail', kwargs={'pk': quantity_mapping.pk} + ) + self.patch(quantity_url, {'lookup_field': 'IPN'}, expected_code=400) + def test_session_list(self): """Test API endpoint which details the list of import sessions.""" url = reverse('api-importer-session-list') @@ -204,6 +717,191 @@ class ImportAPITest(ImporterMixin, InvenTreeAPITestCase): for session in response.data: self.assertEqual(session['user'], self.user.pk) + def test_accept_fields_ownership(self): + """Test that accept_fields rejects requests for sessions owned by another user.""" + other_user = User.objects.create_user( + username='other_accept', password='password' + ) + + f = self.helper_file('companies.csv') + session = DataImportSession.objects.create( + data_file=f, model_type='company', user=other_user + ) + + url = reverse('api-import-session-accept-fields', kwargs={'pk': session.pk}) + + # Non-owner, non-staff should be denied + self.user.is_staff = False + self.user.save() + self.post(url, expected_code=403) + + # Staff should be allowed (subject to model permission) + # Company is part of the purchase_order ruleset + self.user.is_staff = True + self.user.save() + self.assignRole('purchase_order.change') + self.post(url, expected_code=200) + + def test_accept_rows_ownership(self): + """Test that accept_rows rejects requests for sessions owned by another user.""" + other_user = User.objects.create_user( + username='other_accept_rows', password='password' + ) + + f = self.helper_file('companies.csv') + session = DataImportSession.objects.create( + data_file=f, model_type='company', user=other_user + ) + session.extract_columns() + + url = reverse('api-import-session-accept-rows', kwargs={'pk': session.pk}) + + self.user.is_staff = False + self.user.save() + self.post(url, {'rows': []}, expected_code=403) + + # Staff can reach the endpoint (rows list is empty so validation rejects with 400, not 403) + self.user.is_staff = True + self.user.save() + self.post(url, {'rows': []}, expected_code=400) + + def test_session_cleanup_on_complete(self): + """Test that a completed import session deletes itself and all associated data.""" + url = reverse('api-importer-session-list') + data_file = self.helper_file('part_categories.csv') + + data = self.post( + url, + {'model_type': 'partcategory', 'data_file': data_file}, + format='multipart', + ).data + + session_id = data['pk'] + session_pk = session_id + + self.assignRole('part_category.add') + self.post( + reverse('api-import-session-accept-fields', kwargs={'pk': session_id}), + expected_code=200, + ) + + rows = self.get( + reverse('api-importer-row-list'), data={'session': session_id} + ).data + row_ids = [r['pk'] for r in rows] + self.assertGreater(len(row_ids), 0) + + # Confirm rows and mappings exist before acceptance + self.assertTrue(DataImportRow.objects.filter(session_id=session_pk).exists()) + self.assertTrue( + DataImportColumnMap.objects.filter(session_id=session_pk).exists() + ) + + # Accept all rows — this should trigger cleanup of rows and mappings + self.post( + reverse('api-import-session-accept-rows', kwargs={'pk': session_id}), + {'rows': row_ids}, + ) + + # Rows and column mappings must be cleared + self.assertFalse(DataImportRow.objects.filter(session_id=session_pk).exists()) + self.assertFalse( + DataImportColumnMap.objects.filter(session_id=session_pk).exists() + ) + + # Session itself is retained as an audit record with COMPLETE status + from importer.models import DataImportSession + from importer.status_codes import DataImportStatusCode + + session_obj = DataImportSession.objects.get(pk=session_pk) + self.assertEqual(session_obj.status, DataImportStatusCode.COMPLETE.value) + + detail = self.get( + reverse('api-import-session-detail', kwargs={'pk': session_id}), + expected_code=200, + ).data + self.assertEqual(detail['row_count'], 0) + self.assertEqual(detail['completed_row_count'], 0) + + def test_row_and_mapping_ownership(self): + """Test that DataImportRow and DataImportColumnMap endpoints filter by session ownership.""" + f = self.helper_file('companies.csv') + + other_user = User.objects.create_user( + username='other_importer', password='password' + ) + + # Session owned by self.user + session_mine = DataImportSession.objects.create( + data_file=f, model_type='company', user=self.user + ) + session_mine.extract_columns() + + # Session owned by another user + f2 = self.helper_file('companies.csv') + session_other = DataImportSession.objects.create( + data_file=f2, model_type='company', user=other_user + ) + session_other.extract_columns() + + row_list_url = reverse('api-importer-row-list') + mapping_list_url = reverse('api-importer-mapping-list') + + # Non-staff: should only see rows/mappings from own session + self.user.is_staff = False + self.user.save() + + rows = self.get(row_list_url).data + for row in rows: + self.assertEqual(row['session'], session_mine.pk) + + mappings = self.get(mapping_list_url).data + for mapping in mappings: + self.assertEqual(mapping['session'], session_mine.pk) + + # Detail endpoint: own session's row/mapping should be accessible + own_row = DataImportRow.objects.filter(session=session_mine).first() + other_row = DataImportRow.objects.filter(session=session_other).first() + + if own_row: + self.get( + reverse('api-importer-row-detail', kwargs={'pk': own_row.pk}), + expected_code=200, + ) + if other_row: + self.get( + reverse('api-importer-row-detail', kwargs={'pk': other_row.pk}), + expected_code=404, + ) + + own_mapping = DataImportColumnMap.objects.filter(session=session_mine).first() + other_mapping = DataImportColumnMap.objects.filter( + session=session_other + ).first() + + if own_mapping: + self.get( + reverse('api-importer-mapping-detail', kwargs={'pk': own_mapping.pk}), + expected_code=200, + ) + if other_mapping: + self.get( + reverse('api-importer-mapping-detail', kwargs={'pk': other_mapping.pk}), + expected_code=404, + ) + + # Staff user: should see rows/mappings from all sessions + self.user.is_staff = True + self.user.save() + + all_row_pks = set(DataImportRow.objects.values_list('pk', flat=True)) + response_rows = self.get(row_list_url).data + self.assertEqual({r['pk'] for r in response_rows}, all_row_pks) + + all_mapping_pks = set(DataImportColumnMap.objects.values_list('pk', flat=True)) + response_mappings = self.get(mapping_list_url).data + self.assertEqual({m['pk'] for m in response_mappings}, all_mapping_pks) + class AdminTest(ImporterMixin, AdminTestCase): """Tests for the admin interface integration.""" diff --git a/src/backend/InvenTree/importer/validators.py b/src/backend/InvenTree/importer/validators.py index 4c72f43615..5f81ff6dd5 100644 --- a/src/backend/InvenTree/importer/validators.py +++ b/src/backend/InvenTree/importer/validators.py @@ -6,7 +6,7 @@ from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ # Define maximum limits for imported file data -IMPORTER_MAX_FILE_SIZE = 32 * 1024 * 1042 +IMPORTER_MAX_FILE_SIZE = 32 * 1024 * 1024 IMPORTER_MAX_ROWS = 5000 IMPORTER_MAX_COLS = 1000 @@ -46,8 +46,11 @@ def validate_field_defaults(value): return if type(value) is not dict: - # OK if we can parse it as JSON + # OK if we can parse it as JSON - but the result must be a dict try: value = json.loads(value) - except json.JSONDecodeError: + except (TypeError, json.JSONDecodeError): + raise ValidationError(_('Value must be a valid dictionary object')) + + if type(value) is not dict: raise ValidationError(_('Value must be a valid dictionary object')) diff --git a/src/backend/InvenTree/locale/ar/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/ar/LC_MESSAGES/django.po index 3072988a23..6cfbf5fd2d 100644 --- a/src/backend/InvenTree/locale/ar/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/ar/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Arabic\n" "Language: ar_SA\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "نقطة نهاية API غير موجودة" -#: InvenTree/api.py:438 -msgid "List of items must be provided for bulk operation" -msgstr "" - #: InvenTree/api.py:445 +msgid "List of items must be provided for bulk operation" +msgstr "يجب أن يكون قائمة لـ عناصر مقدم لـ bulk operation" + +#: InvenTree/api.py:452 msgid "Items must be provided as a list" -msgstr "" +msgstr "يجب أن يكون عناصر مقدم بصفته قائمة" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" -msgstr "" +msgstr "غير صالح عناصر قائمة مقدم" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" -msgstr "" +msgstr "الكل تصفية يجب فقط يكون مستخدم مع صحيح" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" -msgstr "" +msgstr "لا عناصر مطابقة ال مقدم criteria" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" -msgstr "" +msgstr "لا بيانات مقدم" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." -msgstr "" +msgstr "يجب أن يكون هذا حقل فريد." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "العنصر لم يعد يتطابق مع المعايير المقدمة" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "المستخدم ليس لديه الصلاحية لعرض هذا النموذج" @@ -65,309 +69,358 @@ msgstr "تأكيد البريد الإلكتروني" msgid "You must type the same email each time." msgstr "يجب عليك كتابة نفس البريد الإلكتروني كل مرة." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "عنوان البريد الإلكتروني الرئيسي المقدم غير صالح." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "لم تتم الموافقة على نطاق البريد الإلكتروني المقدم." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "الوحدة المقدمة غير صالحة ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "لم يتم تقديم قيمة" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "تعذّر تحويل {original} إلى {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "الكمية المقدمة غير صحيحة" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "يمكن العثور على تفاصيل الخطأ في لوحة التحكم" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "أدخل التاريخ" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" -msgstr "" +msgstr "غير صالح عشري قيمة" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "ملاحظات" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "القيمة '{name}' لا تظهر في تنسيق النمط" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "القيمة المقدمة لا تتطابق مع النمط المطلوب: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" -msgstr "" +msgstr "لا يمكن ترقيم تسلسلي المزيد من 1000 عناصر عند once" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "سلسلة الرقم التسلسلي فارغة" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "تكرار التسلسل" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" -msgstr "" +msgstr "غير صالح مجموعة: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "نطاق المجموعة {group} يتجاوز الكَمّيَّة المسموح بها ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "لم يتم العثور على أرقام متسلسلة" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" -msgstr "" +msgstr "عدد فريد الأرقام التسلسلية ({n}) يجب مطابقة كمية ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "إزالة علامات HTML من هذه القيمة" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" -msgstr "" +msgstr "بيانات يحتوي prohibited markdown محتوى" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" -msgstr "" +msgstr "غير صالح URL: لا hostname" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" -msgstr "" +msgstr "غير صالح URL: hostname يمكن غير يكون resolved" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" -msgstr "" +msgstr "URL points إلى خاص أو reserved IP عنوان" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" -msgstr "" +msgstr "أيضًا many redirects" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "خطأ فى الاتصال" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" -msgstr "" +msgstr "خادم responded مع غير صالح حالة رمز" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" -msgstr "" +msgstr "Exception حدث" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" -msgstr "" +msgstr "خادم responded مع غير صالح Content-Length قيمة" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" -msgstr "" +msgstr "صورة حجم هو أيضًا large" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" -msgstr "" +msgstr "صورة تنزيل exceeded أقصى حجم" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" -msgstr "" +msgstr "بعيد خادم مرتجع فارغ استجابة" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" -msgstr "" +msgstr "مورد URL هو غير صالح صورة ملف" #: InvenTree/magic_login.py:31 msgid "Log in to the app" -msgstr "" +msgstr "سجل في إلى ال تطبيق" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "البريد الإلكتروني" -#: InvenTree/middleware.py:192 -msgid "You must enable two-factor authentication before doing anything else." -msgstr "" +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "CSRF verification فشل. Ensure INVENTREE_SITE_URL و INVENTREE_TRUSTED_ORIGINS هي مهيأ correctly." -#: InvenTree/models.py:114 +#: InvenTree/middleware.py:218 +msgid "You must enable two-factor authentication before doing anything else." +msgstr "أنت يجب تفعيل two-factor مصادقة قبل doing anything else." + +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "خطأ في تشغيل التحقق من صحة الإضافات" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "البيانات الوصفية يجب أن تكون كائن القالب بايثون" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" -msgstr "" +msgstr "إضافة Metadata" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" -msgstr "" +msgstr "JSON metadata حقل، لـ استخدام حسب خارجي إضافات" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" -msgstr "" - -#: InvenTree/models.py:392 -msgid "Unknown format key specified" -msgstr "" - -#: InvenTree/models.py:398 -msgid "Missing required format key" -msgstr "" - -#: InvenTree/models.py:409 -msgid "Reference field cannot be empty" -msgstr "" +msgstr "Improperly formatted نمط" #: InvenTree/models.py:417 +msgid "Unknown format key specified" +msgstr "غير معروف تنسيق مفتاح محدد" + +#: InvenTree/models.py:423 +msgid "Missing required format key" +msgstr "مفقود مطلوب تنسيق مفتاح" + +#: InvenTree/models.py:434 +msgid "Reference field cannot be empty" +msgstr "مرجع حقل لا يمكن يكون فارغ" + +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" -msgstr "" +msgstr "مرجع رقم هو أيضًا large" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" -msgstr "" +msgstr "غير صالح choice" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" -msgstr "" +msgstr "الاسم" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" -msgstr "" +msgstr "الوصف" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" -msgstr "" +msgstr "وصف (اختياري)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" -msgstr "" +msgstr "مسار" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" -msgstr "" +msgstr "نسخ names لا يمكن موجود under ال نفس الأصل" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" -msgstr "" +msgstr "Markdown ملاحظات (اختياري)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" -msgstr "" +msgstr "باركود بيانات" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" -msgstr "" +msgstr "Third party باركود بيانات" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" -msgstr "" +msgstr "باركود Hash" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" -msgstr "" +msgstr "فريد hash لـ باركود بيانات" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" -msgstr "" +msgstr "موجود باركود تم العثور" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" -msgstr "" +msgstr "خادم خطأ" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." -msgstr "" +msgstr "خطأ لديه تم مسجل حسب ال خادم." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" -msgstr "" +msgstr "الصورة" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" -msgstr "" +msgstr "يجب يكون صالح رقم" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" -msgstr "" +msgstr "العملة" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" -msgstr "" +msgstr "تحديد عملة من متاح خيارات" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." -msgstr "" +msgstr "هذا حقل قد غير يكون null." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" -msgstr "" +msgstr "غير صالح قيمة" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" -msgstr "" +msgstr "غير صالح محتوى نوع تنسيق" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" -msgstr "" +msgstr "محتوى نوع غير تم العثور" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" -msgstr "" +msgstr "محتوى نوع يقوم غير مطابقة مطلوب mixin class" + +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "نسخ معلمات" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "نسخ معلمات من ال أصلي عنصر" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "نسخ سطور" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "نسخ البنود من ال أصلي طلب" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "نسخ إضافي سطور" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "نسخ إضافي البنود من ال أصلي طلب" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "Duplication خيارات" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "تحديد خيارات لـ duplicating هذا عنصر" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "أصلي" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "تحديد نسخة إلى نسخ" #: InvenTree/setting/locales.py:20 msgid "Arabic" @@ -521,46 +574,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" -msgstr "" +msgstr "تحديث متاح" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" -msgstr "" +msgstr "تحديث لـ InvenTree هو متاح" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" -msgstr "" +msgstr "غير صالح physical وحدة" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" -msgstr "" +msgstr "غير صالح عملة رمز" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" -msgstr "" +msgstr "حالة الطلب" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" -msgstr "" +msgstr "الأصل إنتاج" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" -msgstr "" +msgstr "تضمين متغيرات" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,443 +624,452 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 #: templates/email/part_event_notification.html:15 #: templates/email/stale_stock_notification.html:17 msgid "Part" -msgstr "" +msgstr "الصنف" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" -msgstr "" +msgstr "الفئة" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" -msgstr "" +msgstr "Ancestor إنتاج" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" -msgstr "" +msgstr "مسند إلى me" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" -msgstr "" +msgstr "مسند إلى" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" -msgstr "" +msgstr "تم الإنشاء قبل" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" -msgstr "" +msgstr "تم الإنشاء بعد" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" -msgstr "" +msgstr "تاريخ لديه بدء" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" -msgstr "" +msgstr "بدء تاريخ قبل" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" -msgstr "" +msgstr "بدء تاريخ بعد" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" -msgstr "" +msgstr "تاريخ لديه هدف" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" -msgstr "" +msgstr "التاريخ المستهدف قبل" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" -msgstr "" +msgstr "التاريخ المستهدف بعد" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" -msgstr "" +msgstr "مكتمل قبل" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" -msgstr "" +msgstr "مكتمل بعد" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" -msgstr "" +msgstr "تاريخ Min" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" -msgstr "" +msgstr "تاريخ Max" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" -msgstr "" +msgstr "استبعاد Tree" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" -msgstr "" +msgstr "يجب أن يكون إنتاج ملغى قبل هو يمكن يكون تم الحذف" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" -msgstr "" +msgstr "قابل للاستهلاك" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" -msgstr "" +msgstr "اختياري" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" -msgstr "" +msgstr "تجميع" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" -msgstr "" +msgstr "متتبع" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" -msgstr "" +msgstr "قابل للاختبار" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" -msgstr "" +msgstr "طلب متبقي" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" -msgstr "" +msgstr "مخصص" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" -msgstr "" +msgstr "مستهلك" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" -msgstr "" +msgstr "متاح" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" -msgstr "" +msgstr "قيد الطلب" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" -msgstr "" +msgstr "إنتاج غير تم العثور" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" -msgstr "" +msgstr "أمر إنتاج" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" -msgstr "" +msgstr "الموقع" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" -msgstr "" +msgstr "مخرج" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." -msgstr "" +msgstr "تصفية حسب مخرج عنصر المخزون ID. استخدام 'null' إلى find غير مثبت إنتاج عناصر." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" -msgstr "" +msgstr "أوامر الإنتاج" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" -msgstr "" +msgstr "تجميع BOM لديه غير تم تم التحقق" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" -msgstr "" +msgstr "أمر الإنتاج لا يمكن يكون تم الإنشاء لـ غير نشط صنف" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" -msgstr "" +msgstr "أمر الإنتاج لا يمكن يكون تم الإنشاء لـ غير مقفل صنف" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" -msgstr "" +msgstr "أوامر الإنتاج يمكن فقط يكون externally fulfilled لـ قابل للشراء أصناف" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" -msgstr "" +msgstr "يجب أن يكون مسؤول مستخدم أو مجموعة محدد" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" -msgstr "" +msgstr "أمر الإنتاج صنف لا يمكن يكون تم التغيير" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" -msgstr "" +msgstr "يجب أن يكون تاريخ هدف تاريخ بعد بدء" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" -msgstr "" +msgstr "أمر الإنتاج مرجع" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" -msgstr "" +msgstr "المرجع" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" -msgstr "" +msgstr "Brief وصف لـ ال إنتاج (اختياري)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" -msgstr "" +msgstr "أمر الإنتاج إلى الذي هذا إنتاج هو مخصص" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" -msgstr "" +msgstr "تحديد صنف إلى إنتاج" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" -msgstr "" +msgstr "طلب البيع مرجع" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" -msgstr "" +msgstr "طلب البيع إلى الذي هذا إنتاج هو مخصص" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" -msgstr "" +msgstr "المصدر موقع" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" -msgstr "" +msgstr "تحديد موقع إلى take مخزون من لـ هذا إنتاج (ترك فارغ إلى take من أي موقع المخزون)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" -msgstr "" +msgstr "خارجي إنتاج" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" -msgstr "" +msgstr "هذا أمر الإنتاج هو fulfilled externally" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" -msgstr "" +msgstr "الوجهة موقع" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" -msgstr "" +msgstr "تحديد موقع حيث ال مكتمل عناصر سوف يكون مخزن" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" -msgstr "" +msgstr "كمية إنتاج" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" -msgstr "" +msgstr "عدد عناصر المخزون إلى إنتاج" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" -msgstr "" +msgstr "مكتمل عناصر" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" -msgstr "" +msgstr "عدد عناصر المخزون الذي لديه تم مكتمل" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" -msgstr "" +msgstr "حالة إنتاج" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" -msgstr "" +msgstr "إنتاج حالة رمز" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" -msgstr "" +msgstr "رمز الدفعة" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" -msgstr "" +msgstr "رمز الدفعة لـ هذا مخرجات الإنتاج" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" -msgstr "" +msgstr "تاريخ الإنشاء" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" -msgstr "" - -#: build/models.py:371 -msgid "Scheduled start date for this build order" -msgstr "" - -#: build/models.py:377 -msgid "Target completion date" -msgstr "" +msgstr "تاريخ إنتاج بدء" #: build/models.py:379 +msgid "Scheduled start date for this build order" +msgstr "مجدول بدء تاريخ لـ هذا أمر الإنتاج" + +#: build/models.py:385 +msgid "Target completion date" +msgstr "تاريخ هدف إكمال" + +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." -msgstr "" +msgstr "التاريخ المستهدف لـ إنتاج إكمال. إنتاج سوف يكون متأخر بعد هذا تاريخ." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" -msgstr "" +msgstr "تاريخ الإكمال" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" -msgstr "" +msgstr "مكتمل حسب" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" -msgstr "" +msgstr "مصروف حسب" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" -msgstr "" +msgstr "مستخدم من مصروف هذا أمر الإنتاج" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" -msgstr "" +msgstr "مسؤول" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" -msgstr "" +msgstr "مستخدم أو مجموعة مسؤول لـ هذا أمر الإنتاج" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" -msgstr "" +msgstr "خارجي رابط" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" -msgstr "" +msgstr "رابط إلى خارجي URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" -msgstr "" +msgstr "إنتاج Priority" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" -msgstr "" +msgstr "Priority لـ هذا أمر الإنتاج" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" -msgstr "" +msgstr "مشروع رمز" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" -msgstr "" +msgstr "مشروع رمز لـ هذا أمر الإنتاج" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" -msgstr "" +msgstr "لا يمكن مكتمل أمر الإنتاج مع فتح فرعي builds" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" -msgstr "" +msgstr "لا يمكن مكتمل أمر الإنتاج مع غير مكتمل مخرجات" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" -msgstr "" +msgstr "يجب أن يكون الأرقام التسلسلية مقدم لـ قابل للتتبع أصناف" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" -msgstr "" +msgstr "لا مخرجات الإنتاج محدد" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" -msgstr "" +msgstr "مخرجات الإنتاج هو بالفعل مكتمل" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" +msgstr "مخرجات الإنتاج يقوم غير مطابقة أمر الإنتاج" + +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" -msgstr "" +msgstr "يجب أن يكون الكمية أكبر من صفر" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" -msgstr "" +msgstr "كمية كمية لا يمكن يكون أكبر من ال مخرج" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" -msgstr "" +msgstr "مخرجات الإنتاج لديه غير نجح الكل مطلوب اختبارات" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "مخصص عناصر المخزون هي ما زال في الإنتاج" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" +msgstr "لا يمكن partially مكتمل مخرجات الإنتاج مع مخصص عناصر" + +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" msgstr "" -#: build/models.py:1750 +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "متاح كمية ({q}) exceeded" + +#: build/models.py:2167 msgid "Build Order Line Item" -msgstr "" +msgstr "أمر الإنتاج بند" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" -msgstr "" +msgstr "إنتاج كائن" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,1514 +1081,1603 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" -msgstr "" +msgstr "الكمية" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" -msgstr "" +msgstr "مطلوب كمية لـ أمر الإنتاج" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" -msgstr "" +msgstr "كمية مستهلك مخزون" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" -msgstr "" +msgstr "إنتاج عنصر يجب تحديد مخرجات الإنتاج، بصفته master صنف هو معلّم بصفته قابل للتتبع" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" -msgstr "" +msgstr "محدد عنصر المخزون يقوم غير مطابقة BOM سطر" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" -msgstr "" +msgstr "يجب أن يكون كمية مخصص أكبر من صفر" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" -msgstr "" +msgstr "يجب أن يكون الكمية 1 لـ مسلسل مخزون" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" -msgstr "" +msgstr "مخصص كمية ({q}) يجب غير تجاوز متاح مخزون كمية ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" -msgstr "" +msgstr "عنصر المخزون هو over-allocated" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" -msgstr "" +msgstr "عنصر مخزون" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" -msgstr "" +msgstr "المصدر عنصر المخزون" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" -msgstr "" +msgstr "مخزون كمية إلى تخصيص إلى إنتاج" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" -msgstr "" +msgstr "تثبيت إلى" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" -msgstr "" +msgstr "الوجهة عنصر المخزون" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" -msgstr "" +msgstr "إنتاج مستوى" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" -msgstr "" +msgstr "صنف اسم" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" -msgstr "" +msgstr "مخرجات الإنتاج" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" -msgstr "" +msgstr "مخرجات الإنتاج يقوم غير مطابقة ال الأصل إنتاج" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" -msgstr "" +msgstr "مخرج صنف يقوم غير مطابقة BuildOrder صنف" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" -msgstr "" +msgstr "هذا مخرجات الإنتاج لديه بالفعل تم مكتمل" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" -msgstr "" +msgstr "هذا مخرجات الإنتاج هو غير بالكامل مخصص" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" -msgstr "" +msgstr "إدخال كمية لـ مخرجات الإنتاج" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" -msgstr "" +msgstr "عدد صحيح كمية مطلوب لـ قابل للتتبع أصناف" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" -msgstr "" +msgstr "عدد صحيح كمية مطلوب، بصفته ال قائمة المواد يحتوي قابل للتتبع أصناف" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" -msgstr "" +msgstr "الأرقام التسلسلية" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" -msgstr "" +msgstr "إدخال الأرقام التسلسلية لـ إنتاج مخرجات" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" -msgstr "" +msgstr "موقع المخزون لـ مخرجات الإنتاج" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" -msgstr "" +msgstr "تلقائي تخصيص الأرقام التسلسلية" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" -msgstr "" +msgstr "تلقائيًا تخصيص مطلوب عناصر مع مطابق الأرقام التسلسلية" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" -msgstr "" +msgstr "ال التالي الأرقام التسلسلية بالفعل موجود أو هي غير صالح" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" -msgstr "" +msgstr "يجب أن يكون قائمة لـ إنتاج مخرجات مقدم" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" -msgstr "" +msgstr "موقع المخزون لـ scrapped مخرجات" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" -msgstr "" +msgstr "Discard تخصيصات" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" -msgstr "" +msgstr "Discard أي مخزون تخصيصات لـ scrapped مخرجات" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" -msgstr "" +msgstr "Reason لـ scrapping مخرجات الإنتاج(s)" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" -msgstr "" +msgstr "موقع لـ مكتمل إنتاج مخرجات" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "هيكلي مواقع لا يمكن يكون مسند عناصر المخزون" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" -msgstr "" +msgstr "قبول غير مكتمل تخصيص" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" -msgstr "" +msgstr "مكتمل مخرجات إذا مخزون لديه غير تم بالكامل مخصص" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" -msgstr "" +msgstr "استهلاك مخصص مخزون" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" -msgstr "" +msgstr "استهلاك أي مخزون الذي لديه بالفعل تم مخصص إلى هذا إنتاج" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" -msgstr "" +msgstr "إزالة غير مكتمل مخرجات" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" -msgstr "" +msgstr "حذف أي إنتاج مخرجات الذي لديه غير تم مكتمل" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" -msgstr "" +msgstr "غير permitted" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" -msgstr "" +msgstr "قبول بصفته مستهلك حسب هذا أمر الإنتاج" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" -msgstr "" +msgstr "Deallocate قبل completing هذا أمر الإنتاج" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" -msgstr "" +msgstr "Overallocated مخزون" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" -msgstr "" +msgstr "How تنفيذ أنت ترغب إلى handle إضافي عناصر المخزون مسند إلى ال أمر الإنتاج" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" -msgstr "" +msgstr "Some عناصر المخزون لديه تم overallocated" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" -msgstr "" +msgstr "قبول غير مخصص" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" -msgstr "" +msgstr "قبول ذلك عناصر المخزون لديه غير تم بالكامل مخصص إلى هذا أمر الإنتاج" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" -msgstr "" +msgstr "مطلوب مخزون لديه غير تم بالكامل مخصص" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" -msgstr "" +msgstr "قبول غير مكتمل" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" -msgstr "" +msgstr "قبول ذلك ال مطلوب رقم لـ إنتاج مخرجات لديه غير تم مكتمل" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" -msgstr "" +msgstr "مطلوب إنتاج كمية لديه غير تم مكتمل" + +#: build/serializers.py:779 +msgid "Build order has open child build orders" +msgstr "أمر الإنتاج لديه فتح فرعي أوامر الإنتاج" + +#: build/serializers.py:782 +msgid "Build order must be in production state" +msgstr "يجب أن يكون أمر الإنتاج في الإنتاج حالة" + +#: build/serializers.py:785 +msgid "Build order has incomplete outputs" +msgstr "أمر الإنتاج لديه غير مكتمل مخرجات" #: build/serializers.py:824 -msgid "Build order has open child build orders" -msgstr "" - -#: build/serializers.py:827 -msgid "Build order must be in production state" -msgstr "" - -#: build/serializers.py:830 -msgid "Build order has incomplete outputs" -msgstr "" - -#: build/serializers.py:869 msgid "Build Line" -msgstr "" +msgstr "إنتاج سطر" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" -msgstr "" +msgstr "مخرجات الإنتاج" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" -msgstr "" +msgstr "مخرجات الإنتاج يجب نقطة إلى ال نفس إنتاج" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" -msgstr "" +msgstr "إنتاج بند" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" -msgstr "" +msgstr "bom_item.صنف يجب نقطة إلى ال نفس صنف بصفته ال أمر الإنتاج" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" -msgstr "" +msgstr "يجب أن يكون عنصر في مخزون" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" -msgstr "" +msgstr "يجب أن يكون مخرجات الإنتاج محدد لـ تخصيص لـ متتبع أصناف" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" -msgstr "" +msgstr "مخرجات الإنتاج لا يمكن يكون محدد لـ تخصيص لـ untracked أصناف" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" -msgstr "" +msgstr "يجب أن يكون تخصيص عناصر مقدم" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" -msgstr "" +msgstr "موقع المخزون حيث أصناف هي إلى يكون sourced (ترك فارغ إلى take من أي موقع)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" -msgstr "" +msgstr "استبعاد موقع" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" -msgstr "" +msgstr "استبعاد عناصر المخزون من هذا محدد موقع" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" -msgstr "" +msgstr "Interchangeable مخزون" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" -msgstr "" +msgstr "عناصر المخزون في متعدد مواقع يمكن يكون مستخدم interchangeably" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" -msgstr "" +msgstr "بديل مخزون" + +#: build/serializers.py:1085 +msgid "Allow allocation of substitute parts" +msgstr "السماح تخصيص لـ بديل أصناف" + +#: build/serializers.py:1090 +msgid "Optional Items" +msgstr "اختياري عناصر" + +#: build/serializers.py:1091 +msgid "Allocate optional BOM items to build order" +msgstr "تخصيص اختياري BOM عناصر إلى أمر الإنتاج" + +#: build/serializers.py:1097 +msgid "All Items" +msgstr "الكل عناصر" + +#: build/serializers.py:1098 +msgid "Untracked Items" +msgstr "Untracked عناصر" + +#: build/serializers.py:1099 +msgid "Tracked Items" +msgstr "متتبع عناصر" + +#: build/serializers.py:1101 +msgid "Item Type" +msgstr "عنصر نوع" + +#: build/serializers.py:1102 +msgid "Select item type to auto-allocate" +msgstr "تحديد عنصر نوع إلى auto-allocate" + +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "مخزون Priority" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "Preferred طلب في الذي مطابق عناصر المخزون هي مستهلك" #: build/serializers.py:1117 -msgid "Allow allocation of substitute parts" -msgstr "" +msgid "Build Lines" +msgstr "إنتاج سطور" -#: build/serializers.py:1122 -msgid "Optional Items" -msgstr "" +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "حد تخصيص إلى هذه إنتاج سطور (ترك فارغ إلى تخصيص الكل سطور)" -#: build/serializers.py:1123 -msgid "Allocate optional BOM items to build order" -msgstr "" - -#: build/serializers.py:1129 -msgid "All Items" -msgstr "" - -#: build/serializers.py:1130 -msgid "Untracked Items" -msgstr "" - -#: build/serializers.py:1131 -msgid "Tracked Items" -msgstr "" - -#: build/serializers.py:1133 -msgid "Item Type" -msgstr "" - -#: build/serializers.py:1134 -msgid "Select item type to auto-allocate" -msgstr "" - -#: build/serializers.py:1188 +#: build/serializers.py:1174 msgid "BOM Reference" -msgstr "" +msgstr "BOM مرجع" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" -msgstr "" +msgstr "BOM صنف ID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" -msgstr "" +msgstr "BOM صنف اسم" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" -msgstr "" +msgstr "تثبيت إلى" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" -msgstr "" +msgstr "إنتاج" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" -msgstr "" +msgstr "صنف المورد" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" -msgstr "" +msgstr "كمية مخصص" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" -msgstr "" +msgstr "إنتاج مرجع" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" -msgstr "" +msgstr "فئة الأصناف اسم" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" -msgstr "" +msgstr "قابل للتتبع" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" -msgstr "" +msgstr "موروث" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" -msgstr "" +msgstr "السماح متغيرات" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" -msgstr "" +msgstr "عنصر قائمة المواد" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" -msgstr "" +msgstr "قيد الإنتاج" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" -msgstr "" +msgstr "مجدول إلى إنتاج" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" -msgstr "" +msgstr "خارجي مخزون" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" -msgstr "" +msgstr "متاح مخزون" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" -msgstr "" +msgstr "متاح بديل مخزون" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" -msgstr "" +msgstr "متاح متغير مخزون" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" -msgstr "" +msgstr "كمية مستهلك كمية يتجاوز مخصص" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" -msgstr "" +msgstr "اختياري ملاحظات لـ ال مخزون consumption" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" -msgstr "" +msgstr "إنتاج عنصر يجب نقطة إلى ال صحيح أمر الإنتاج" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" -msgstr "" +msgstr "نسخ إنتاج عنصر تخصيص" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" -msgstr "" +msgstr "إنتاج سطر يجب نقطة إلى ال صحيح أمر الإنتاج" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" -msgstr "" +msgstr "نسخ إنتاج سطر تخصيص" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" -msgstr "" +msgstr "يجب أن يكون عند أقل واحد عنصر أو سطر مقدم" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" -msgstr "" +msgstr "قيد الانتظار" #: build/status_codes.py:12 msgid "Production" -msgstr "" +msgstr "الإنتاج" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" -msgstr "" +msgstr "على تعليق" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" -msgstr "" +msgstr "ملغى" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" -msgstr "" +msgstr "مكتمل" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "أمر الإنتاج {build} لديه تم مكتمل" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "أمر الإنتاج لديه تم مكتمل" + +#: build/tasks.py:487 msgid "Stock required for build order" -msgstr "" +msgstr "مخزون مطلوب لـ أمر الإنتاج" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" -msgstr "" +msgstr "أمر الإنتاج {build} يتطلب additional مخزون" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" -msgstr "" +msgstr "متأخر أمر الإنتاج" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" -msgstr "" +msgstr "أمر الإنتاج {bo} هو الآن متأخر" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "لديه Thumbnail" + +#: common/api.py:773 msgid "Is Link" -msgstr "" +msgstr "هو رابط" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" -msgstr "" +msgstr "هو ملف" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" -msgstr "" +msgstr "مستخدم يقوم غير لديه صلاحية إلى حذف هذه مرفقات" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "مستخدم يقوم غير لديه صلاحية إلى تعديل هذا مرفق" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" -msgstr "" +msgstr "مستخدم يقوم غير لديه صلاحية إلى حذف هذا مرفق" + +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "اختيار قائمة هو مقفل" #: common/currency.py:135 msgid "Invalid currency code" -msgstr "" +msgstr "غير صالح عملة رمز" #: common/currency.py:137 msgid "Duplicate currency code" -msgstr "" +msgstr "نسخ عملة رمز" #: common/currency.py:142 msgid "No valid currency codes provided" -msgstr "" +msgstr "لا صالح عملة رموز مقدم" #: common/currency.py:159 msgid "No plugin" -msgstr "" +msgstr "لا إضافة" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "وسوم" + +#: common/filters.py:390 msgid "Project Code Label" -msgstr "" +msgstr "مشروع رمز ملصق" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" -msgstr "" +msgstr "تم التحديث" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" -msgstr "" +msgstr "طابع زمني لـ آخر تحديث" #: common/models.py:146 msgid "Update By" -msgstr "" +msgstr "تحديث حسب" #: common/models.py:147 msgid "User who last updated this object" -msgstr "" +msgstr "مستخدم من آخر تم التحديث هذا كائن" #: common/models.py:174 msgid "Unique project code" -msgstr "" +msgstr "فريد مشروع رمز" #: common/models.py:181 msgid "Project description" -msgstr "" +msgstr "مشروع وصف" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" -msgstr "" +msgstr "نشط" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "هو هذا مشروع رمز نشط؟" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "مستخدم أو مجموعة مسؤول لـ هذا مشروع" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "إعدادات مفتاح" + +#: common/models.py:799 +msgid "Settings value" +msgstr "إعدادات قيمة" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Chosen قيمة هو غير صالح خيار" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "يجب أن يكون القيمة boolean قيمة" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "يجب أن يكون القيمة عدد صحيح قيمة" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "يجب أن يكون القيمة صالح رقم" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "قيمة يقوم غير نجاح validation checks" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "يجب أن يكون مفتاح نص فريد" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "المستخدم" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "كمية سعر فاصل" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "السعر" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "كمية سعر الوحدة عند محدد" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "نقطة نهاية" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "نقطة نهاية عند الذي هذا webhook هو مستلم" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "اسم لـ هذا webhook" + +#: common/models.py:1460 msgid "Is this webhook active" -msgstr "" +msgstr "هو هذا webhook نشط" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" -msgstr "" +msgstr "رمز وصول" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" -msgstr "" +msgstr "رمز وصول لـ access" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" -msgstr "" +msgstr "Shared secret لـ HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" -msgstr "" +msgstr "رسالة ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" -msgstr "" +msgstr "فريد معرف لـ هذا رسالة" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" -msgstr "" +msgstr "مضيف" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" -msgstr "" +msgstr "مضيف من الذي هذا رسالة كان مستلم" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" -msgstr "" +msgstr "الترويسة" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" -msgstr "" +msgstr "Header لـ هذا رسالة" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" -msgstr "" +msgstr "Body لـ هذا رسالة" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" -msgstr "" +msgstr "نقطة نهاية على الذي هذا رسالة كان مستلم" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" -msgstr "" +msgstr "Worked على" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" +msgstr "كان ال work على هذا رسالة finished؟" + +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" msgstr "" -#: common/models.py:1751 +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" -msgstr "" +msgstr "عنوان" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" -msgstr "" +msgstr "رابط" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" -msgstr "" +msgstr "قراءة" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" -msgstr "" +msgstr "كان هذا أخبار عنصر قراءة؟" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" -msgstr "" +msgstr "صورة ملف" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" -msgstr "" +msgstr "هدف نموذج نوع لـ هذا صورة" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" -msgstr "" +msgstr "هدف نموذج ID لـ هذا صورة" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" -msgstr "" +msgstr "مخصص وحدة" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" -msgstr "" +msgstr "يجب أن يكون وحدة symbol فريد" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" -msgstr "" +msgstr "يجب أن يكون وحدة اسم صالح معرف" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" -msgstr "" +msgstr "وحدة اسم" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" -msgstr "" +msgstr "اختياري وحدة symbol" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" -msgstr "" +msgstr "وحدة definition" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" -msgstr "" +msgstr "المرفق" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" -msgstr "" - -#: common/models.py:1980 -msgid "Missing external link" -msgstr "" - -#: common/models.py:2019 -msgid "No file attached to rename" -msgstr "" +msgstr "مفقود ملف" #: common/models.py:2022 +msgid "Missing external link" +msgstr "مفقود خارجي رابط" + +#: common/models.py:2070 +msgid "No file attached to rename" +msgstr "لا ملف attached إلى rename" + +#: common/models.py:2073 msgid "Filename cannot be empty" -msgstr "" +msgstr "اسم الملف لا يمكن يكون فارغ" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" -msgstr "" +msgstr "غير صالح اسم الملف" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" -msgstr "" +msgstr "لا يمكن تغيير ملف extension" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" -msgstr "" +msgstr "ملف مع هذا اسم بالفعل موجود" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" -msgstr "" +msgstr "فشل في حفظ renamed ملف" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" -msgstr "" +msgstr "نموذج نوع" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" -msgstr "" +msgstr "هدف نموذج نوع لـ صورة" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" +msgstr "تحديد ملف إلى إرفاق" + +#: common/models.py:2138 +msgid "Thumbnail" msgstr "" -#: common/models.py:2096 +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "Thumbnail صورة لـ هذا مرفق" + +#: common/models.py:2155 msgid "Comment" msgstr "" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" -msgstr "" +msgstr "مرفق comment" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" -msgstr "" +msgstr "تاريخ رفع" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" -msgstr "" - -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" +msgstr "تاريخ ال ملف كان تم الرفع" #: common/models.py:2178 -msgid "Custom States" -msgstr "" +msgid "Is image" +msgstr "هو صورة" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "صحيح إذا هذا مرفق هو صالح صورة ملف" #: common/models.py:2183 +msgid "File size" +msgstr "ملف حجم" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "ملف حجم في bytes" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "غير صالح نموذج نوع محدد لـ مرفق" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "مخصص حالة" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "مخصص States" + +#: common/models.py:2309 msgid "Reference Status Set" -msgstr "" +msgstr "مرجع حالة تعيين" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" -msgstr "" +msgstr "حالة تعيين ذلك هو extended مع هذا مخصص حالة" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" -msgstr "" +msgstr "منطقي مفتاح" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" -msgstr "" +msgstr "حالة منطقي مفتاح ذلك هو equal إلى هذا مخصص حالة في business logic" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" -msgstr "" - -#: common/models.py:2196 -msgid "Numerical value that will be saved in the models database" -msgstr "" - -#: common/models.py:2202 -msgid "Name of the state" -msgstr "" - -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 -msgid "Label" -msgstr "" - -#: common/models.py:2212 -msgid "Label that will be displayed in the frontend" -msgstr "" - -#: common/models.py:2219 generic/states/serializers.py:24 -msgid "Color" -msgstr "" - -#: common/models.py:2220 -msgid "Color that will be displayed in the frontend" -msgstr "" - -#: common/models.py:2228 -msgid "Model" -msgstr "" - -#: common/models.py:2229 -msgid "Model this state is associated with" -msgstr "" - -#: common/models.py:2244 -msgid "Model must be selected" -msgstr "" - -#: common/models.py:2247 -msgid "Key must be selected" -msgstr "" - -#: common/models.py:2250 -msgid "Logical key must be selected" -msgstr "" - -#: common/models.py:2254 -msgid "Key must be different from logical key" -msgstr "" - -#: common/models.py:2261 -msgid "Valid reference status class must be provided" -msgstr "" - -#: common/models.py:2267 -msgid "Key must be different from the logical keys of the reference status" -msgstr "" - -#: common/models.py:2274 -msgid "Logical key must be in the logical keys of the reference status" -msgstr "" - -#: common/models.py:2281 -msgid "Name must be different from the names of the reference status" -msgstr "" - -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 -msgid "Selection List" -msgstr "" +msgstr "القيمة" #: common/models.py:2322 -msgid "Selection Lists" -msgstr "" +msgid "Numerical value that will be saved in the models database" +msgstr "Numerical قيمة ذلك سوف يكون saved في ال نماذج قاعدة بيانات" -#: common/models.py:2327 -msgid "Name of the selection list" -msgstr "" +#: common/models.py:2328 +msgid "Name of the state" +msgstr "اسم لـ ال حالة" -#: common/models.py:2334 -msgid "Description of the selection list" -msgstr "" +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 +msgid "Label" +msgstr "ملصق" -#: common/models.py:2340 part/models.py:1297 -msgid "Locked" -msgstr "" +#: common/models.py:2338 +msgid "Label that will be displayed in the frontend" +msgstr "ملصق ذلك سوف يكون معروض في ال frontend" -#: common/models.py:2341 -msgid "Is this selection list locked?" -msgstr "" +#: common/models.py:2345 generic/states/serializers.py:24 +msgid "Color" +msgstr "لون" -#: common/models.py:2347 -msgid "Can this selection list be used?" -msgstr "" +#: common/models.py:2346 +msgid "Color that will be displayed in the frontend" +msgstr "لون ذلك سوف يكون معروض في ال frontend" + +#: common/models.py:2354 +msgid "Model" +msgstr "نموذج" #: common/models.py:2355 +msgid "Model this state is associated with" +msgstr "نموذج هذا حالة هو مرتبط مع" + +#: common/models.py:2370 +msgid "Model must be selected" +msgstr "يجب أن يكون نموذج محدد" + +#: common/models.py:2373 +msgid "Key must be selected" +msgstr "يجب أن يكون مفتاح محدد" + +#: common/models.py:2376 +msgid "Logical key must be selected" +msgstr "يجب أن يكون منطقي مفتاح محدد" + +#: common/models.py:2380 +msgid "Key must be different from logical key" +msgstr "يجب أن يكون مفتاح مختلف من منطقي مفتاح" + +#: common/models.py:2387 +msgid "Valid reference status class must be provided" +msgstr "يجب أن يكون صالح مرجع حالة class مقدم" + +#: common/models.py:2393 +msgid "Key must be different from the logical keys of the reference status" +msgstr "يجب أن يكون مفتاح حالة مختلف من ال منطقي keys لـ ال مرجع" + +#: common/models.py:2400 +msgid "Logical key must be in the logical keys of the reference status" +msgstr "يجب أن يكون منطقي مفتاح حالة في ال منطقي keys لـ ال مرجع" + +#: common/models.py:2407 +msgid "Name must be different from the names of the reference status" +msgstr "يجب أن يكون الاسم حالة مختلف من ال names لـ ال مرجع" + +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 +msgid "Selection List" +msgstr "اختيار قائمة" + +#: common/models.py:2448 +msgid "Selection Lists" +msgstr "اختيار Lists" + +#: common/models.py:2453 +msgid "Name of the selection list" +msgstr "اسم لـ ال اختيار قائمة" + +#: common/models.py:2460 +msgid "Description of the selection list" +msgstr "وصف لـ ال اختيار قائمة" + +#: common/models.py:2466 part/models.py:1315 +msgid "Locked" +msgstr "مقفل" + +#: common/models.py:2467 +msgid "Is this selection list locked?" +msgstr "هو هذا اختيار قائمة مقفل؟" + +#: common/models.py:2473 +msgid "Can this selection list be used?" +msgstr "يمكن هذا اختيار قائمة يكون مستخدم؟" + +#: common/models.py:2481 msgid "Source Plugin" -msgstr "" - -#: common/models.py:2356 -msgid "Plugin which provides the selection list" -msgstr "" - -#: common/models.py:2361 -msgid "Source String" -msgstr "" - -#: common/models.py:2362 -msgid "Optional string identifying the source used for this list" -msgstr "" - -#: common/models.py:2371 -msgid "Default Entry" -msgstr "" - -#: common/models.py:2372 -msgid "Default entry for this selection list" -msgstr "" - -#: common/models.py:2377 common/models.py:3274 -msgid "Created" -msgstr "" - -#: common/models.py:2378 -msgid "Date and time that the selection list was created" -msgstr "" - -#: common/models.py:2383 -msgid "Last Updated" -msgstr "" - -#: common/models.py:2384 -msgid "Date and time that the selection list was last updated" -msgstr "" - -#: common/models.py:2446 -msgid "Selection List Entry" -msgstr "" - -#: common/models.py:2447 -msgid "Selection List Entries" -msgstr "" - -#: common/models.py:2457 -msgid "Selection list to which this entry belongs" -msgstr "" - -#: common/models.py:2463 -msgid "Value of the selection list entry" -msgstr "" - -#: common/models.py:2469 -msgid "Label for the selection list entry" -msgstr "" - -#: common/models.py:2475 -msgid "Description of the selection list entry" -msgstr "" +msgstr "المصدر إضافة" #: common/models.py:2482 +msgid "Plugin which provides the selection list" +msgstr "إضافة الذي يوفر ال اختيار قائمة" + +#: common/models.py:2487 +msgid "Source String" +msgstr "المصدر نص" + +#: common/models.py:2488 +msgid "Optional string identifying the source used for this list" +msgstr "اختياري نص identifying ال المصدر مستخدم لـ هذا قائمة" + +#: common/models.py:2497 +msgid "Default Entry" +msgstr "افتراضي سجل" + +#: common/models.py:2498 +msgid "Default entry for this selection list" +msgstr "افتراضي سجل لـ هذا اختيار قائمة" + +#: common/models.py:2503 common/models.py:3470 +msgid "Created" +msgstr "تم الإنشاء" + +#: common/models.py:2504 +msgid "Date and time that the selection list was created" +msgstr "تاريخ و وقت ذلك ال اختيار قائمة كان تم الإنشاء" + +#: common/models.py:2509 +msgid "Last Updated" +msgstr "آخر تم التحديث" + +#: common/models.py:2510 +msgid "Date and time that the selection list was last updated" +msgstr "تاريخ و وقت ذلك ال اختيار قائمة كان آخر تم التحديث" + +#: common/models.py:2572 +msgid "Selection List Entry" +msgstr "اختيار قائمة سجل" + +#: common/models.py:2573 +msgid "Selection List Entries" +msgstr "اختيار قائمة سجلات" + +#: common/models.py:2583 +msgid "Selection list to which this entry belongs" +msgstr "اختيار قائمة إلى الذي هذا سجل belongs" + +#: common/models.py:2589 +msgid "Value of the selection list entry" +msgstr "قيمة لـ ال اختيار قائمة سجل" + +#: common/models.py:2595 +msgid "Label for the selection list entry" +msgstr "ملصق لـ ال اختيار قائمة سجل" + +#: common/models.py:2601 +msgid "Description of the selection list entry" +msgstr "وصف لـ ال اختيار قائمة سجل" + +#: common/models.py:2608 msgid "Is this selection list entry active?" -msgstr "" +msgstr "هو هذا اختيار قائمة سجل نشط؟" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" -msgstr "" +msgstr "معلمة قالب" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" +msgstr "معلمة قوالب" + +#: common/models.py:2664 +msgid "No uniqueness required" msgstr "" -#: common/models.py:2554 +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" -msgstr "" +msgstr "مربع اختيار معلمات لا يمكن لديه وحدات" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" -msgstr "" +msgstr "مربع اختيار معلمات لا يمكن لديه خيارات" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" -msgstr "" +msgstr "يجب أن يكون خيارات فريد" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" -msgstr "" - -#: common/models.py:2618 -msgid "Target model type for this parameter template" -msgstr "" - -#: common/models.py:2624 -msgid "Parameter Name" -msgstr "" - -#: common/models.py:2630 part/models.py:1250 -msgid "Units" -msgstr "" - -#: common/models.py:2631 -msgid "Physical units for this parameter" -msgstr "" - -#: common/models.py:2639 -msgid "Parameter description" -msgstr "" - -#: common/models.py:2645 -msgid "Checkbox" -msgstr "" - -#: common/models.py:2646 -msgid "Is this parameter a checkbox?" -msgstr "" - -#: common/models.py:2651 part/models.py:3773 -msgid "Choices" -msgstr "" - -#: common/models.py:2652 -msgid "Valid choices for this parameter (comma-separated)" -msgstr "" - -#: common/models.py:2663 -msgid "Selection list for this parameter" -msgstr "" - -#: common/models.py:2668 part/models.py:3748 report/models.py:292 -msgid "Enabled" -msgstr "" - -#: common/models.py:2669 -msgid "Is this parameter template enabled?" -msgstr "" - -#: common/models.py:2710 -msgid "Parameter" -msgstr "" - -#: common/models.py:2711 -msgid "Parameters" -msgstr "" +msgstr "يجب أن يكون معلمة قالب اسم فريد" #: common/models.py:2757 +msgid "Target model type for this parameter template" +msgstr "هدف نموذج نوع لـ هذا معلمة قالب" + +#: common/models.py:2763 +msgid "Parameter Name" +msgstr "معلمة اسم" + +#: common/models.py:2769 part/models.py:1268 +msgid "Units" +msgstr "الوحدات" + +#: common/models.py:2770 +msgid "Physical units for this parameter" +msgstr "Physical وحدات لـ هذا معلمة" + +#: common/models.py:2778 +msgid "Parameter description" +msgstr "معلمة وصف" + +#: common/models.py:2784 +msgid "Checkbox" +msgstr "مربع اختيار" + +#: common/models.py:2785 +msgid "Is this parameter a checkbox?" +msgstr "هو هذا معلمة مربع اختيار؟" + +#: common/models.py:2790 part/models.py:3663 +msgid "Choices" +msgstr "خيارات" + +#: common/models.py:2791 +msgid "Valid choices for this parameter (comma-separated)" +msgstr "صالح خيارات لـ هذا معلمة (comma-separated)" + +#: common/models.py:2802 +msgid "Selection list for this parameter" +msgstr "اختيار قائمة لـ هذا معلمة" + +#: common/models.py:2807 part/models.py:3638 report/models.py:297 +msgid "Enabled" +msgstr "مفعّل" + +#: common/models.py:2808 +msgid "Is this parameter template enabled?" +msgstr "هو هذا معلمة قالب مفعّل؟" + +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 +msgid "Parameter" +msgstr "معلمة" + +#: common/models.py:2859 +msgid "Parameters" +msgstr "معلمات" + +#: common/models.py:2905 msgid "Invalid choice for parameter value" +msgstr "غير صالح choice لـ معلمة قيمة" + +#: common/models.py:3009 +msgid "Parameter value must be unique" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" -msgstr "" +msgstr "غير صالح نموذج نوع محدد لـ معلمة" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" -msgstr "" +msgstr "نموذج ID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" -msgstr "" +msgstr "ID لـ ال هدف نموذج لـ هذا معلمة" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" -msgstr "" +msgstr "قالب" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" -msgstr "" +msgstr "معلمة قالب" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" -msgstr "" +msgstr "بيانات" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" -msgstr "" +msgstr "معلمة قيمة" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" -msgstr "" +msgstr "ملاحظة" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" -msgstr "" +msgstr "اختياري ملاحظة حقل" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" -msgstr "" +msgstr "مسح الباركود" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" -msgstr "" +msgstr "باركود بيانات" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" -msgstr "" +msgstr "مستخدم من تم المسح ال باركود" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" -msgstr "" +msgstr "طابع زمني" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" -msgstr "" +msgstr "تاريخ و وقت لـ ال مسح الباركود" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" -msgstr "" +msgstr "URL نقطة نهاية الذي processed ال باركود" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" -msgstr "" +msgstr "سياق" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" -msgstr "" +msgstr "سياق بيانات لـ ال مسح الباركود" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" -msgstr "" +msgstr "استجابة" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" -msgstr "" +msgstr "استجابة بيانات من ال مسح الباركود" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" -msgstr "" +msgstr "نتيجة" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" -msgstr "" +msgstr "كان ال مسح الباركود ناجح؟" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" -msgstr "" +msgstr "خطأ حدث" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." -msgstr "" +msgstr "INVE-E8: بريد إلكتروني سجل الحذف هو protected. تعيين INVENTREE_PROTECT_EMAIL_LOG إلى خطأ إلى السماح الحذف." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" -msgstr "" +msgstr "بريد إلكتروني رسالة" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" -msgstr "" +msgstr "بريد إلكتروني Messages" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" -msgstr "" +msgstr "تم الإرسال" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" -msgstr "" +msgstr "فشل" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" -msgstr "" +msgstr "لا Reply" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" -msgstr "" +msgstr "تتبع تسليم" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" -msgstr "" +msgstr "تتبع قراءة" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" -msgstr "" +msgstr "تتبع انقر" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" -msgstr "" +msgstr "معرف لـ هذا رسالة (might يكون مورد حسب خارجي نظام)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" -msgstr "" +msgstr "سلسلة ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" -msgstr "" +msgstr "معرف لـ هذا رسالة سلسلة (might يكون مورد حسب خارجي نظام)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" -msgstr "" +msgstr "سلسلة" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" -msgstr "" +msgstr "مرتبط سلسلة لـ هذا رسالة" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" -msgstr "" +msgstr "بريد إلكتروني سلسلة" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" -msgstr "" +msgstr "بريد إلكتروني Threads" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" -msgstr "" +msgstr "مفتاح" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" -msgstr "" +msgstr "فريد مفتاح لـ هذا سلسلة (مستخدم إلى identify ال سلسلة)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" -msgstr "" +msgstr "فريد معرف لـ هذا سلسلة" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" -msgstr "" +msgstr "بدأ داخلي" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" -msgstr "" +msgstr "كان هذا سلسلة بدأ internally؟" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" -msgstr "" +msgstr "تاريخ و وقت ذلك ال سلسلة كان تم الإنشاء" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" -msgstr "" +msgstr "تاريخ و وقت ذلك ال سلسلة كان آخر تم التحديث" #: common/notifications.py:57 #, python-brace-format msgid "New {verbose_name}" -msgstr "" +msgstr "{verbose_name} جديد" #: common/notifications.py:59 msgid "A new order has been created and assigned to you" -msgstr "" +msgstr "جديد طلب لديه تم تم الإنشاء و مسند إلى أنت" #: common/notifications.py:65 #, python-brace-format msgid "{verbose_name} canceled" -msgstr "" +msgstr "{verbose_name} ملغى" #: common/notifications.py:67 msgid "A order that is assigned to you was canceled" -msgstr "" +msgstr "طلب ذلك هو مسند إلى أنت كان ملغى" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" -msgstr "" +msgstr "عناصر مستلم" #: common/notifications.py:75 msgid "Items have been received against a purchase order" -msgstr "" +msgstr "عناصر لديه تم مستلم مقابل طلب الشراء" #: common/notifications.py:82 msgid "Items have been received against a return order" -msgstr "" +msgstr "عناصر لديه تم مستلم مقابل طلب الإرجاع" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" -msgstr "" +msgstr "يشير إذا changing هذا إعداد يتطلب confirmation" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." -msgstr "" - -#: common/serializers.py:172 -msgid "Indicates if the setting is overridden by an environment variable" -msgstr "" +msgstr "هذا إعداد يتطلب confirmation قبل changing. يرجى تأكيد ال تغيير." #: common/serializers.py:174 +msgid "Indicates if the setting is overridden by an environment variable" +msgstr "يشير إذا ال إعداد هو overridden حسب environment variable" + +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" -msgstr "" +msgstr "تجاوز" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" -msgstr "" +msgstr "هو قيد التشغيل" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" -msgstr "" +msgstr "قيد الانتظار مهام" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" -msgstr "" +msgstr "مجدول مهام" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" -msgstr "" +msgstr "فشل مهام" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" -msgstr "" +msgstr "مهمة ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" -msgstr "" +msgstr "فريد مهمة ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" -msgstr "" +msgstr "Lock وقت" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" -msgstr "" +msgstr "مهمة اسم" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" -msgstr "" +msgstr "دالة" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" -msgstr "" +msgstr "دالة اسم" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" -msgstr "" +msgstr "وسائط" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" -msgstr "" +msgstr "مهمة وسائط" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" -msgstr "" +msgstr "Keyword وسائط" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" -msgstr "" +msgstr "مهمة keyword وسائط" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" -msgstr "" +msgstr "اسم الملف" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" -msgstr "" +msgstr "نموذج نوع" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" -msgstr "" +msgstr "مستخدم يقوم غير لديه صلاحية إلى إنشاء أو تعديل مرفقات لـ هذا نموذج" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" -msgstr "" - -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" +msgstr "مستخدم يقوم غير لديه صلاحية إلى إنشاء أو تعديل معلمات لـ هذا نموذج" #: common/setting/system.py:97 msgid "No group" -msgstr "" +msgstr "لا مجموعة" #: common/setting/system.py:170 msgid "Site URL is locked by configuration" -msgstr "" +msgstr "موقع URL هو مقفل حسب تهيئة" #: common/setting/system.py:187 msgid "Restart required" -msgstr "" +msgstr "إعادة تشغيل مطلوب" #: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" -msgstr "" +msgstr "إعداد لديه تم تم التغيير الذي يتطلب خادم إعادة تشغيل" #: common/setting/system.py:194 msgid "Pending migrations" -msgstr "" +msgstr "قيد الانتظار ترحيلات" #: common/setting/system.py:195 msgid "Number of pending database migrations" -msgstr "" +msgstr "عدد قيد الانتظار قاعدة بيانات ترحيلات" #: common/setting/system.py:200 msgid "Active warning codes" -msgstr "" +msgstr "نشط تحذير رموز" #: common/setting/system.py:201 msgid "A dict of active warning codes" -msgstr "" +msgstr "dict لـ نشط تحذير رموز" #: common/setting/system.py:207 msgid "Instance ID" -msgstr "" +msgstr "نسخة ID" #: common/setting/system.py:208 msgid "Unique identifier for this InvenTree instance" -msgstr "" +msgstr "فريد معرف لـ هذا InvenTree نسخة" #: common/setting/system.py:213 msgid "Announce ID" @@ -2532,23 +2685,23 @@ msgstr "" #: common/setting/system.py:215 msgid "Announce the instance ID of the server in the server status info (unauthenticated)" -msgstr "" +msgstr "Announce ال نسخة ID لـ ال خادم في ال خادم حالة info (unauthenticated)" #: common/setting/system.py:221 msgid "Server Instance Name" -msgstr "" +msgstr "خادم نسخة اسم" #: common/setting/system.py:223 msgid "String descriptor for the server instance" -msgstr "" +msgstr "نص descriptor لـ ال خادم نسخة" #: common/setting/system.py:227 msgid "Use instance name" -msgstr "" +msgstr "استخدام نسخة اسم" #: common/setting/system.py:228 msgid "Use the instance name in the title-bar" -msgstr "" +msgstr "استخدام ال نسخة اسم في ال title-bar" #: common/setting/system.py:233 msgid "Restrict showing `about`" @@ -2556,47 +2709,47 @@ msgstr "" #: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" -msgstr "" +msgstr "عرض ال `about` modal فقط إلى superusers" #: common/setting/system.py:239 msgid "Show superuser banner" -msgstr "" +msgstr "عرض مستخدم فائق banner" #: common/setting/system.py:240 msgid "Show a warning banner in the UI when logged in as superuser" -msgstr "" +msgstr "عرض تحذير banner في ال UI عند مسجل في بصفته مستخدم فائق" #: common/setting/system.py:245 msgid "Show admin banner" -msgstr "" +msgstr "عرض مسؤول banner" #: common/setting/system.py:246 msgid "Show a warning banner in the UI when logged in as admin" -msgstr "" +msgstr "عرض تحذير banner في ال UI عند مسجل في بصفته مسؤول" #: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" -msgstr "" +msgstr "شركة اسم" #: common/setting/system.py:252 msgid "Internal company name" -msgstr "" +msgstr "داخلي شركة اسم" #: common/setting/system.py:256 msgid "Base URL" -msgstr "" +msgstr "أساس URL" #: common/setting/system.py:257 msgid "Base URL for server instance" -msgstr "" +msgstr "أساس URL لـ خادم نسخة" #: common/setting/system.py:263 msgid "Default Currency" -msgstr "" +msgstr "افتراضي عملة" #: common/setting/system.py:264 msgid "Select base currency for pricing calculations" -msgstr "" +msgstr "تحديد أساس عملة لـ التسعير حسابات" #: common/setting/system.py:270 msgid "Supported Currencies" @@ -2604,1504 +2757,1615 @@ msgstr "" #: common/setting/system.py:271 msgid "List of supported currency codes" -msgstr "" +msgstr "قائمة لـ supported عملة رموز" #: common/setting/system.py:277 msgid "Currency Update Interval" -msgstr "" +msgstr "عملة تحديث فاصل" #: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" -msgstr "" +msgstr "How often إلى تحديث صرف rates (تعيين إلى صفر إلى تعطيل)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" -msgstr "" +msgstr "أيام" #: common/setting/system.py:284 msgid "Currency Update Plugin" -msgstr "" +msgstr "عملة تحديث إضافة" #: common/setting/system.py:285 msgid "Currency update plugin to use" -msgstr "" +msgstr "عملة تحديث إضافة إلى استخدام" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "رفع حجم حد" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "أقصى allowable رفع حجم لـ صور و ملفات" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" #: common/setting/system.py:291 msgid "Require schema specification when validating URLs" -msgstr "" +msgstr "طلب schema specification عند validating URLs" #: common/setting/system.py:296 msgid "Update Check Interval" -msgstr "" +msgstr "تحديث فحص فاصل" #: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" -msgstr "" +msgstr "How often إلى فحص لـ updates (تعيين إلى صفر إلى تعطيل)" #: common/setting/system.py:303 msgid "Automatic Backup" -msgstr "" +msgstr "تلقائي Backup" #: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" -msgstr "" +msgstr "تفعيل تلقائي backup لـ قاعدة بيانات و media ملفات" #: common/setting/system.py:309 msgid "Auto Backup Interval" -msgstr "" +msgstr "تلقائي Backup فاصل" #: common/setting/system.py:310 msgid "Specify number of days between automated backup events" -msgstr "" +msgstr "تحديد رقم لـ أيام بين automated backup events" #: common/setting/system.py:316 msgid "Task Deletion Interval" -msgstr "" +msgstr "مهمة الحذف فاصل" #: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" -msgstr "" +msgstr "خلفية مهمة نتائج سوف يكون تم الحذف بعد محدد رقم لـ أيام" #: common/setting/system.py:325 msgid "Error Log Deletion Interval" -msgstr "" +msgstr "خطأ في سجل الحذف فاصل" #: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" -msgstr "" +msgstr "خطأ في logs سوف يكون تم الحذف بعد محدد رقم لـ أيام" #: common/setting/system.py:332 msgid "Notification Deletion Interval" -msgstr "" +msgstr "إشعار الحذف فاصل" #: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" -msgstr "" +msgstr "مستخدم إشعارات سوف يكون تم الحذف بعد محدد رقم لـ أيام" #: common/setting/system.py:341 msgid "Email Deletion Interval" -msgstr "" +msgstr "بريد إلكتروني الحذف فاصل" #: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" -msgstr "" +msgstr "بريد إلكتروني messages سوف يكون تم الحذف بعد محدد رقم لـ أيام" #: common/setting/system.py:350 msgid "Protect Email Log" -msgstr "" +msgstr "Protect بريد إلكتروني سجل" #: common/setting/system.py:351 msgid "Prevent deletion of email log entries" -msgstr "" +msgstr "منع الحذف لـ بريد إلكتروني سجل سجلات" #: common/setting/system.py:356 msgid "Barcode Support" -msgstr "" +msgstr "باركود الدعم" #: common/setting/system.py:357 msgid "Enable barcode scanner support in the web interface" -msgstr "" +msgstr "تفعيل باركود ماسح الدعم في ال ويب واجهة" #: common/setting/system.py:362 msgid "Store Barcode Results" -msgstr "" +msgstr "تخزين باركود نتائج" #: common/setting/system.py:363 msgid "Store barcode scan results in the database" -msgstr "" +msgstr "تخزين مسح الباركود نتائج في ال قاعدة بيانات" #: common/setting/system.py:368 msgid "Barcode Scans Maximum Count" -msgstr "" +msgstr "باركود Scans أقصى عد" #: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" -msgstr "" +msgstr "أقصى رقم لـ مسح الباركود نتائج إلى تخزين" #: common/setting/system.py:374 msgid "Barcode Input Delay" -msgstr "" +msgstr "باركود إدخال Delay" #: common/setting/system.py:375 msgid "Barcode input processing delay time" -msgstr "" +msgstr "باركود إدخال processing delay وقت" #: common/setting/system.py:381 msgid "Barcode Webcam Support" -msgstr "" +msgstr "باركود Webcam الدعم" #: common/setting/system.py:382 msgid "Allow barcode scanning via webcam in browser" -msgstr "" +msgstr "السماح باركود المسح عبر webcam في متصفح" #: common/setting/system.py:387 msgid "Barcode Show Data" -msgstr "" +msgstr "باركود عرض بيانات" #: common/setting/system.py:388 msgid "Display barcode data in browser as text" -msgstr "" +msgstr "عرض باركود بيانات في متصفح بصفته نص" #: common/setting/system.py:393 msgid "Barcode Generation Plugin" -msgstr "" +msgstr "باركود Generation إضافة" #: common/setting/system.py:394 msgid "Plugin to use for internal barcode data generation" -msgstr "" - -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" +msgstr "إضافة إلى استخدام لـ داخلي باركود بيانات generation" #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" -msgstr "" +msgid "Part Locking" +msgstr "صنف Locking" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" -msgstr "" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "تفعيل locking لـ أصناف إلى منع modification" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" -msgstr "" +msgid "Part Revisions" +msgstr "صنف مراجعات" -#: common/setting/system.py:417 -msgid "IPN Regex" -msgstr "" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" +msgstr "تفعيل مراجعة حقل لـ صنف" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "تجميع مراجعة فقط" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "فقط السماح مراجعات لـ تجميع أصناف" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "السماح الحذف من تجميع" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "السماح الحذف لـ أصناف الذي هي مستخدم في تجميع" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "IPN تعبير نمطي" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" -msgstr "" - -#: common/setting/system.py:421 -msgid "Allow Duplicate IPN" -msgstr "" - -#: common/setting/system.py:422 -msgid "Allow multiple parts to share the same IPN" -msgstr "" - -#: common/setting/system.py:427 -msgid "Allow Editing IPN" -msgstr "" - -#: common/setting/system.py:428 -msgid "Allow changing the IPN value while editing a part" -msgstr "" - -#: common/setting/system.py:433 -msgid "Copy Part BOM Data" -msgstr "" +msgstr "Regular expression نمط لـ مطابق صنف IPN" #: common/setting/system.py:434 -msgid "Copy BOM data by default when duplicating a part" -msgstr "" +msgid "Allow Duplicate IPN" +msgstr "السماح نسخ IPN" -#: common/setting/system.py:439 -msgid "Copy Part Parameter Data" -msgstr "" +#: common/setting/system.py:435 +msgid "Allow multiple parts to share the same IPN" +msgstr "السماح متعدد أصناف إلى share ال نفس IPN" #: common/setting/system.py:440 -msgid "Copy parameter data by default when duplicating a part" -msgstr "" +msgid "Allow Editing IPN" +msgstr "السماح تحرير IPN" -#: common/setting/system.py:445 -msgid "Copy Part Test Data" -msgstr "" +#: common/setting/system.py:441 +msgid "Allow changing the IPN value while editing a part" +msgstr "السماح changing ال IPN قيمة أثناء تحرير صنف" #: common/setting/system.py:446 -msgid "Copy test data by default when duplicating a part" -msgstr "" +msgid "Copy Part BOM Data" +msgstr "نسخ صنف BOM بيانات" -#: common/setting/system.py:451 -msgid "Copy Category Parameter Templates" -msgstr "" +#: common/setting/system.py:447 +msgid "Copy BOM data by default when duplicating a part" +msgstr "نسخ BOM بيانات حسب افتراضي عند duplicating صنف" #: common/setting/system.py:452 -msgid "Copy category parameter templates when creating a part" -msgstr "" +msgid "Copy Part Parameter Data" +msgstr "نسخ معلمة الصنف بيانات" + +#: common/setting/system.py:453 +msgid "Copy parameter data by default when duplicating a part" +msgstr "نسخ معلمة بيانات حسب افتراضي عند duplicating صنف" #: common/setting/system.py:458 -msgid "Parts are templates by default" -msgstr "" +msgid "Copy Part Test Data" +msgstr "نسخ صنف اختبار بيانات" + +#: common/setting/system.py:459 +msgid "Copy test data by default when duplicating a part" +msgstr "نسخ اختبار بيانات حسب افتراضي عند duplicating صنف" #: common/setting/system.py:464 +msgid "Copy Category Parameter Templates" +msgstr "نسخ فئة معلمة قوالب" + +#: common/setting/system.py:465 +msgid "Copy category parameter templates when creating a part" +msgstr "نسخ فئة معلمة قوالب عند creating صنف" + +#: common/setting/system.py:471 +msgid "Parts are templates by default" +msgstr "أصناف هي قوالب حسب افتراضي" + +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" -msgstr "" +msgstr "أصناف يمكن يكون مجمّع من أخرى مكونات حسب افتراضي" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" -msgstr "" +msgstr "مكوّن" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" -msgstr "" +msgstr "أصناف يمكن يكون مستخدم بصفته sub-components حسب افتراضي" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" -msgstr "" +msgstr "قابل للشراء" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" -msgstr "" +msgstr "أصناف هي قابل للشراء حسب افتراضي" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" -msgstr "" +msgstr "قابل للبيع" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" -msgstr "" +msgstr "أصناف هي قابل للبيع حسب افتراضي" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" -msgstr "" +msgstr "أصناف هي قابل للتتبع حسب افتراضي" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" -msgstr "" +msgstr "افتراضي" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" -msgstr "" +msgstr "أصناف هي افتراضي حسب افتراضي" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" -msgstr "" - -#: common/setting/system.py:500 -msgid "Display related parts for a part" -msgstr "" - -#: common/setting/system.py:505 -msgid "Initial Stock Data" -msgstr "" - -#: common/setting/system.py:506 -msgid "Allow creation of initial stock when adding a new part" -msgstr "" - -#: common/setting/system.py:511 -msgid "Initial Supplier Data" -msgstr "" +msgstr "عرض مرتبط أصناف" #: common/setting/system.py:513 -msgid "Allow creation of initial supplier data when adding a new part" -msgstr "" +msgid "Display related parts for a part" +msgstr "عرض مرتبط أصناف لـ صنف" + +#: common/setting/system.py:518 +msgid "Initial Stock Data" +msgstr "أولي مخزون بيانات" #: common/setting/system.py:519 -msgid "Part Name Display Format" -msgstr "" +msgid "Allow creation of initial stock when adding a new part" +msgstr "السماح إنشاء لـ أولي مخزون عند إضافة جديد صنف" -#: common/setting/system.py:520 -msgid "Format to display the part name" -msgstr "" +#: common/setting/system.py:524 +msgid "Initial Supplier Data" +msgstr "أولي مورد بيانات" #: common/setting/system.py:526 -msgid "Part Category Default Icon" -msgstr "" - -#: common/setting/system.py:527 -msgid "Part category default icon (empty means no icon)" -msgstr "" +msgid "Allow creation of initial supplier data when adding a new part" +msgstr "السماح إنشاء لـ أولي مورد بيانات عند إضافة جديد صنف" #: common/setting/system.py:532 -msgid "Minimum Pricing Decimal Places" -msgstr "" +msgid "Part Name Display Format" +msgstr "صنف اسم عرض تنسيق" -#: common/setting/system.py:534 -msgid "Minimum number of decimal places to display when rendering pricing data" -msgstr "" +#: common/setting/system.py:533 +msgid "Format to display the part name" +msgstr "تنسيق إلى عرض ال صنف اسم" + +#: common/setting/system.py:539 +msgid "Part Category Default Icon" +msgstr "فئة الأصناف افتراضي أيقونة" + +#: common/setting/system.py:540 +msgid "Part category default icon (empty means no icon)" +msgstr "فئة الأصناف افتراضي أيقونة (فارغ means لا أيقونة)" #: common/setting/system.py:545 -msgid "Maximum Pricing Decimal Places" -msgstr "" +msgid "Minimum Pricing Decimal Places" +msgstr "أدنى التسعير عشري أماكن" #: common/setting/system.py:547 -msgid "Maximum number of decimal places to display when rendering pricing data" -msgstr "" +msgid "Minimum number of decimal places to display when rendering pricing data" +msgstr "أدنى رقم لـ عشري أماكن إلى عرض عند عرض التسعير بيانات" #: common/setting/system.py:558 -msgid "Use Supplier Pricing" -msgstr "" +msgid "Maximum Pricing Decimal Places" +msgstr "أقصى التسعير عشري أماكن" #: common/setting/system.py:560 +msgid "Maximum number of decimal places to display when rendering pricing data" +msgstr "أقصى رقم لـ عشري أماكن إلى عرض عند عرض التسعير بيانات" + +#: common/setting/system.py:571 +msgid "Use Supplier Pricing" +msgstr "استخدام مورد التسعير" + +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" -msgstr "" +msgstr "تضمين مورد سعر فواصل في إجمالي التسعير حسابات" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" -msgstr "" +msgstr "شراء سجل تجاوز" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" -msgstr "" +msgstr "تاريخي طلب الشراء التسعير overrides مورد سعر فواصل" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" -msgstr "" +msgstr "استخدام عنصر المخزون التسعير" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" -msgstr "" +msgstr "استخدام التسعير من يدويًا entered مخزون بيانات لـ التسعير حسابات" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" -msgstr "" - -#: common/setting/system.py:584 -msgid "Exclude stock items older than this number of days from pricing calculations" -msgstr "" - -#: common/setting/system.py:591 -msgid "Use Variant Pricing" -msgstr "" - -#: common/setting/system.py:592 -msgid "Include variant pricing in overall pricing calculations" -msgstr "" +msgstr "عنصر المخزون التسعير Age" #: common/setting/system.py:597 -msgid "Active Variants Only" -msgstr "" +msgid "Exclude stock items older than this number of days from pricing calculations" +msgstr "استبعاد عناصر المخزون older من هذا رقم لـ أيام من التسعير حسابات" -#: common/setting/system.py:599 -msgid "Only use active variant parts for calculating variant pricing" -msgstr "" +#: common/setting/system.py:604 +msgid "Use Variant Pricing" +msgstr "استخدام متغير التسعير" #: common/setting/system.py:605 +msgid "Include variant pricing in overall pricing calculations" +msgstr "تضمين متغير التسعير في إجمالي التسعير حسابات" + +#: common/setting/system.py:610 +msgid "Active Variants Only" +msgstr "نشط متغيرات فقط" + +#: common/setting/system.py:612 +msgid "Only use active variant parts for calculating variant pricing" +msgstr "فقط استخدام نشط متغير أصناف لـ calculating متغير التسعير" + +#: common/setting/system.py:618 msgid "Auto Update Pricing" -msgstr "" - -#: common/setting/system.py:607 -msgid "Automatically update part pricing when internal data changes" -msgstr "" - -#: common/setting/system.py:613 -msgid "Pricing Rebuild Interval" -msgstr "" - -#: common/setting/system.py:614 -msgid "Number of days before part pricing is automatically updated" -msgstr "" +msgstr "تلقائي تحديث التسعير" #: common/setting/system.py:620 -msgid "Internal Prices" -msgstr "" - -#: common/setting/system.py:621 -msgid "Enable internal prices for parts" -msgstr "" +msgid "Automatically update part pricing when internal data changes" +msgstr "تلقائيًا تحديث صنف التسعير عند داخلي بيانات تغييرات" #: common/setting/system.py:626 -msgid "Internal Price Override" -msgstr "" +msgid "Pricing Rebuild Interval" +msgstr "التسعير Rebuild فاصل" -#: common/setting/system.py:628 -msgid "If available, internal prices override price range calculations" -msgstr "" +#: common/setting/system.py:627 +msgid "Number of days before part pricing is automatically updated" +msgstr "عدد أيام قبل صنف التسعير هو تلقائيًا تم التحديث" + +#: common/setting/system.py:633 +msgid "Internal Prices" +msgstr "داخلي أسعار" #: common/setting/system.py:634 +msgid "Enable internal prices for parts" +msgstr "تفعيل داخلي أسعار لـ أصناف" + +#: common/setting/system.py:639 +msgid "Internal Price Override" +msgstr "داخلي سعر تجاوز" + +#: common/setting/system.py:641 +msgid "If available, internal prices override price range calculations" +msgstr "إذا متاح، داخلي أسعار تجاوز سعر range حسابات" + +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" -msgstr "" +msgstr "كمية السماح BOM صفر" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" -msgstr "" +msgstr "كمية قبول صفر كمية لـ BOM عنصر لـ صنف. Enables باستخدام إعداد كمية إلى define كمية مطلوب per إنتاج، independent لـ إنتاج" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" -msgstr "" - -#: common/setting/system.py:643 -msgid "Enable label printing from the web interface" -msgstr "" - -#: common/setting/system.py:648 -msgid "Label Image DPI" -msgstr "" - -#: common/setting/system.py:650 -msgid "DPI resolution when generating image files to supply to label printing plugins" -msgstr "" +msgstr "تفعيل ملصق الطباعة" #: common/setting/system.py:656 -msgid "Enable Reports" -msgstr "" +msgid "Enable label printing from the web interface" +msgstr "تفعيل ملصق الطباعة من ال ويب واجهة" -#: common/setting/system.py:657 -msgid "Enable generation of reports" -msgstr "" - -#: common/setting/system.py:662 -msgid "Debug Mode" -msgstr "" +#: common/setting/system.py:661 +msgid "Label Image DPI" +msgstr "ملصق صورة DPI" #: common/setting/system.py:663 -msgid "Generate reports in debug mode (HTML output)" -msgstr "" - -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" +msgid "DPI resolution when generating image files to supply to label printing plugins" +msgstr "DPI resolution عند جارٍ الإنشاء صورة ملفات إلى supply إلى ملصق الطباعة إضافات" #: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" +msgid "Enable Reports" +msgstr "تفعيل تقارير" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" +#: common/setting/system.py:670 +msgid "Enable generation of reports" +msgstr "تفعيل generation لـ تقارير" #: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" +msgid "Debug Mode" +msgstr "تصحيح الأخطاء وضع" -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" -msgstr "" +#: common/setting/system.py:676 +msgid "Generate reports in debug mode (HTML output)" +msgstr "إنشاء تقارير في تصحيح الأخطاء وضع (HTML مخرج)" + +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "تقرير URL جارٍ الجلب" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" -msgstr "" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "السماح جارٍ الجلب لـ بعيد URLs عند جارٍ الإنشاء تقارير" + +#: common/setting/system.py:687 +msgid "Log Report Errors" +msgstr "سجل تقرير أخطاء" #: common/setting/system.py:688 -msgid "Globally Unique Serials" -msgstr "" +msgid "Log errors which occur when generating reports" +msgstr "سجل أخطاء الذي occur عند جارٍ الإنشاء تقارير" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" -msgstr "" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" +msgstr "صفحة حجم" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" -msgstr "" +msgid "Default page size for PDF reports" +msgstr "افتراضي صفحة حجم لـ PDF تقارير" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" -msgstr "" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" +msgstr "Enforce معلمة وحدات" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" -msgstr "" +msgid "If units are provided, parameter values must match the specified units" +msgstr "إذا وحدات هي مقدم، معلمة قيم يجب مطابقة ال محدد وحدات" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" -msgstr "" +msgid "Globally Unique Serials" +msgstr "Globally فريد Serials" -#: common/setting/system.py:712 -msgid "Batch Code Template" -msgstr "" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" +msgstr "يجب أن يكون الأرقام التسلسلية لـ عناصر المخزون globally فريد" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" -msgstr "" +msgid "Delete Depleted Stock" +msgstr "حذف نافد مخزون" -#: common/setting/system.py:717 -msgid "Stock Expiry" -msgstr "" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" +msgstr "Determines افتراضي behavior عند عنصر المخزون هو نافد" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" -msgstr "" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" +msgstr "السماح تعديل الرقم التسلسلي" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" -msgstr "" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" +msgstr "السماح تحرير لـ الرقم التسلسلي لـ عناصر المخزون" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" -msgstr "" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" +msgstr "حذف مسلسل مخزون" -#: common/setting/system.py:729 -msgid "Stock Stale Time" -msgstr "" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" +msgstr "السماح الحذف لـ عناصر المخزون الذي لديه الرقم التسلسلي" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" -msgstr "" +msgid "Batch Code Template" +msgstr "رمز الدفعة قالب" -#: common/setting/system.py:738 -msgid "Build Expired Stock" -msgstr "" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" +msgstr "قالب لـ جارٍ الإنشاء افتراضي دفعة رموز لـ عناصر المخزون" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" -msgstr "" +#: common/setting/system.py:736 +msgid "Stock Expiry" +msgstr "مخزون انتهاء" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" -msgstr "" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" +msgstr "تفعيل مخزون انتهاء الوظيفة" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" -msgstr "" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "Sell منتهي مخزون" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "السماح بيع لـ منتهي مخزون" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" +msgstr "مخزون قديم وقت" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" -msgstr "" +msgid "Number of days stock items are considered stale before expiring" +msgstr "عدد أيام عناصر المخزون هي considered قديم قبل expiring" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" -msgstr "" +msgid "Build Expired Stock" +msgstr "إنتاج منتهي مخزون" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" -msgstr "" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "السماح building مع منتهي مخزون" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" +msgstr "مخزون Ownership Control" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" -msgstr "" +msgid "Enable ownership control over stock locations and items" +msgstr "تفعيل ownership control over مواقع المخزون و عناصر" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" +msgstr "موقع المخزون افتراضي أيقونة" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "موقع المخزون افتراضي أيقونة (فارغ means لا أيقونة)" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "عرض مثبت عناصر المخزون" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "عرض مثبت عناصر المخزون في مخزون tables" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "فحص BOM عند installing عناصر" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "مثبت عناصر المخزون يجب موجود في ال BOM لـ ال الأصل صنف" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" -msgstr "" - -#: common/setting/system.py:772 -msgid "Allow stock items which are not in stock to be transferred between stock locations" -msgstr "" - -#: common/setting/system.py:778 -msgid "Build Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:779 -msgid "Required pattern for generating Build Order reference field" -msgstr "" - -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 -msgid "Require Responsible Owner" -msgstr "" - -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 -msgid "A responsible owner must be assigned to each order" -msgstr "" - -#: common/setting/system.py:790 -msgid "Require Active Part" -msgstr "" +msgstr "السماح خارج لـ مخزون تحويل" #: common/setting/system.py:791 -msgid "Prevent build order creation for inactive parts" -msgstr "" - -#: common/setting/system.py:796 -msgid "Require Locked Part" -msgstr "" +msgid "Allow stock items which are not in stock to be transferred between stock locations" +msgstr "السماح عناصر المخزون الذي هي غير في مخزون إلى يكون منقول بين مواقع المخزون" #: common/setting/system.py:797 -msgid "Prevent build order creation for unlocked parts" -msgstr "" +msgid "Merge stock with existing stock on transfer by default" +msgstr "دمج مخزون مع موجود مخزون على تحويل حسب افتراضي" -#: common/setting/system.py:802 -msgid "Require Valid BOM" -msgstr "" +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "افتراضي حالة لـ دمج مخزون على تحويل behaviour. (يمكن يكون تم التغيير per تحويل إذا desired)" -#: common/setting/system.py:803 -msgid "Prevent build order creation unless BOM has been validated" -msgstr "" +#: common/setting/system.py:805 +msgid "Build Order Reference Pattern" +msgstr "أمر الإنتاج مرجع نمط" -#: common/setting/system.py:808 -msgid "Require Closed Child Orders" -msgstr "" +#: common/setting/system.py:806 +msgid "Required pattern for generating Build Order reference field" +msgstr "مطلوب نمط لـ جارٍ الإنشاء أمر الإنتاج مرجع حقل" -#: common/setting/system.py:810 -msgid "Prevent build order completion until all child orders are closed" -msgstr "" +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 +msgid "Require Responsible Owner" +msgstr "طلب مسؤول مالك" -#: common/setting/system.py:816 -msgid "External Build Orders" -msgstr "" +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 +msgid "A responsible owner must be assigned to each order" +msgstr "يجب أن يكون مسؤول مالك مسند إلى كل طلب" #: common/setting/system.py:817 -msgid "Enable external build order functionality" -msgstr "" +msgid "Require Active Part" +msgstr "طلب نشط صنف" -#: common/setting/system.py:822 -msgid "Require External Build Orders" -msgstr "" +#: common/setting/system.py:818 +msgid "Prevent build order creation for inactive parts" +msgstr "منع أمر الإنتاج إنشاء لـ غير نشط أصناف" + +#: common/setting/system.py:823 +msgid "Require Locked Part" +msgstr "طلب مقفل صنف" #: common/setting/system.py:824 -msgid "Require an external build order when ordering assembled parts from an external supplier" -msgstr "" +msgid "Prevent build order creation for unlocked parts" +msgstr "منع أمر الإنتاج إنشاء لـ غير مقفل أصناف" + +#: common/setting/system.py:829 +msgid "Require Valid BOM" +msgstr "طلب صالح BOM" #: common/setting/system.py:830 -msgid "Block Until Tests Pass" -msgstr "" +msgid "Prevent build order creation unless BOM has been validated" +msgstr "منع أمر الإنتاج إنشاء unless BOM لديه تم تم التحقق" -#: common/setting/system.py:832 -msgid "Prevent build outputs from being completed until all required tests pass" -msgstr "" +#: common/setting/system.py:835 +msgid "Require Closed Child Orders" +msgstr "طلب Closed فرعي طلبات" -#: common/setting/system.py:838 -msgid "Enable Return Orders" -msgstr "" +#: common/setting/system.py:837 +msgid "Prevent build order completion until all child orders are closed" +msgstr "منع أمر الإنتاج إكمال حتى الكل فرعي طلبات هي closed" -#: common/setting/system.py:839 -msgid "Enable return order functionality in the user interface" -msgstr "" +#: common/setting/system.py:843 +msgid "External Build Orders" +msgstr "خارجي أوامر الإنتاج" #: common/setting/system.py:844 -msgid "Return Order Reference Pattern" -msgstr "" +msgid "Enable external build order functionality" +msgstr "تفعيل خارجي أمر الإنتاج الوظيفة" -#: common/setting/system.py:846 -msgid "Required pattern for generating Return Order reference field" -msgstr "" +#: common/setting/system.py:849 +msgid "Require External Build Orders" +msgstr "طلب خارجي أوامر الإنتاج" -#: common/setting/system.py:858 -msgid "Edit Completed Return Orders" -msgstr "" +#: common/setting/system.py:851 +msgid "Require an external build order when ordering assembled parts from an external supplier" +msgstr "طلب خارجي أمر الإنتاج عند ordering مجمّع أصناف من خارجي مورد" -#: common/setting/system.py:860 -msgid "Allow editing of return orders after they have been completed" -msgstr "" +#: common/setting/system.py:857 +msgid "Block Until Tests Pass" +msgstr "Block حتى اختبارات نجاح" + +#: common/setting/system.py:859 +msgid "Prevent build outputs from being completed until all required tests pass" +msgstr "منع إنتاج مخرجات من being مكتمل حتى الكل مطلوب اختبارات نجاح" + +#: common/setting/system.py:865 +msgid "Enable Return Orders" +msgstr "تفعيل طلبات الإرجاع" #: common/setting/system.py:866 +msgid "Enable return order functionality in the user interface" +msgstr "تفعيل طلب الإرجاع الوظيفة في ال مستخدم واجهة" + +#: common/setting/system.py:871 +msgid "Return Order Reference Pattern" +msgstr "طلب الإرجاع مرجع نمط" + +#: common/setting/system.py:873 +msgid "Required pattern for generating Return Order reference field" +msgstr "مطلوب نمط لـ جارٍ الإنشاء طلب الإرجاع مرجع حقل" + +#: common/setting/system.py:885 +msgid "Edit Completed Return Orders" +msgstr "تعديل مكتمل طلبات الإرجاع" + +#: common/setting/system.py:887 +msgid "Allow editing of return orders after they have been completed" +msgstr "السماح تحرير لـ طلبات الإرجاع بعد they لديه تم مكتمل" + +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:867 -msgid "Required pattern for generating Sales Order reference field" -msgstr "" - -#: common/setting/system.py:878 -msgid "Sales Order Default Shipment" -msgstr "" - -#: common/setting/system.py:879 -msgid "Enable creation of default shipment with sales orders" -msgstr "" - -#: common/setting/system.py:884 -msgid "Edit Completed Sales Orders" -msgstr "" - -#: common/setting/system.py:886 -msgid "Allow editing of sales orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:892 -msgid "Shipment Requires Checking" -msgstr "" +msgstr "طلب البيع مرجع نمط" #: common/setting/system.py:894 +msgid "Required pattern for generating Sales Order reference field" +msgstr "مطلوب نمط لـ جارٍ الإنشاء طلب البيع مرجع حقل" + +#: common/setting/system.py:905 +msgid "Sales Order Default Shipment" +msgstr "طلب البيع افتراضي شحنة" + +#: common/setting/system.py:906 +msgid "Enable creation of default shipment with sales orders" +msgstr "تفعيل إنشاء لـ افتراضي شحنة مع طلبات البيع" + +#: common/setting/system.py:911 +msgid "Edit Completed Sales Orders" +msgstr "تعديل مكتمل طلبات البيع" + +#: common/setting/system.py:913 +msgid "Allow editing of sales orders after they have been shipped or completed" +msgstr "السماح تحرير لـ طلبات البيع بعد they لديه تم مشحون أو مكتمل" + +#: common/setting/system.py:919 +msgid "Shipment Requires Checking" +msgstr "شحنة يتطلب Checking" + +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" -msgstr "" +msgstr "منع إكمال لـ شحنات حتى عناصر لديه تم محدد" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" -msgstr "" +msgstr "تعيين مشحون طلبات بصفته مكتمل" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" +msgstr "حالة طلبات البيع معلّم بصفته مشحون سوف تلقائيًا يكون مكتمل، bypassing ال \"shipped\"" + +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "تفعيل طلبات التحويل" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "تفعيل طلب التحويل الوظيفة في ال مستخدم واجهة" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "طلب التحويل مرجع نمط" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "مطلوب نمط لـ جارٍ الإنشاء طلب التحويل مرجع حقل" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" -msgstr "" - -#: common/setting/system.py:910 -msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" -msgstr "" - -#: common/setting/system.py:916 -msgid "Purchase Order Reference Pattern" -msgstr "" - -#: common/setting/system.py:918 -msgid "Required pattern for generating Purchase Order reference field" -msgstr "" - -#: common/setting/system.py:930 -msgid "Edit Completed Purchase Orders" -msgstr "" - -#: common/setting/system.py:932 -msgid "Allow editing of purchase orders after they have been shipped or completed" -msgstr "" - -#: common/setting/system.py:938 -msgid "Convert Currency" -msgstr "" - -#: common/setting/system.py:939 -msgid "Convert item value to base currency when receiving stock" -msgstr "" - -#: common/setting/system.py:944 -msgid "Auto Complete Purchase Orders" -msgstr "" - -#: common/setting/system.py:946 -msgid "Automatically mark purchase orders as complete when all line items are received" -msgstr "" - -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" +msgstr "Block غير مكتمل عنصر اختبارات" #: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" +msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" +msgstr "منع تخصيص لـ عناصر المخزون إلى طلبات البيع إذا مطلوب عنصر اختبارات هي غير مكتمل" #: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" +msgid "Purchase Order Reference Pattern" +msgstr "طلب الشراء مرجع نمط" #: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" +msgid "Required pattern for generating Purchase Order reference field" +msgstr "مطلوب نمط لـ جارٍ الإنشاء طلب الشراء مرجع حقل" -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" +#: common/setting/system.py:985 +msgid "Edit Completed Purchase Orders" +msgstr "تعديل مكتمل طلبات الشراء" #: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" +msgid "Allow editing of purchase orders after they have been shipped or completed" +msgstr "السماح تحرير لـ طلبات الشراء بعد they لديه تم مشحون أو مكتمل" #: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" +msgid "Convert Currency" +msgstr "تحويل عملة" -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" +#: common/setting/system.py:994 +msgid "Convert item value to base currency when receiving stock" +msgstr "تحويل عنصر قيمة إلى أساس عملة عند receiving مخزون" + +#: common/setting/system.py:999 +msgid "Auto Complete Purchase Orders" +msgstr "تلقائي مكتمل طلبات الشراء" #: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" +msgid "Automatically mark purchase orders as complete when all line items are received" +msgstr "تلقائيًا تعيين طلبات الشراء بصفته مكتمل عند الكل البنود هي مستلم" -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" -msgstr "" +msgid "Enable password forgot" +msgstr "تفعيل كلمة المرور forgot" -#: common/setting/system.py:1021 -msgid "Mail twice" -msgstr "" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "تفعيل كلمة المرور forgot دالة على ال تسجيل الدخول pages" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" -msgstr "" +msgid "Enable registration" +msgstr "تفعيل تسجيل" -#: common/setting/system.py:1027 -msgid "Password twice" -msgstr "" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "تفعيل self-registration لـ مستخدمون على ال تسجيل الدخول pages" #: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "تفعيل SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "تفعيل SSO على ال تسجيل الدخول pages" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "تفعيل SSO تسجيل" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "تفعيل self-registration عبر SSO لـ مستخدمون على ال تسجيل الدخول pages" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "تفعيل SSO مجموعة مزامنة" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "تفعيل synchronizing InvenTree مجموعات مع مجموعات مقدم حسب ال IdP" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "SSO مجموعة مفتاح" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "ال اسم لـ ال مجموعات claim attribute مقدم حسب ال IdP" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "SSO مجموعة map" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "mapping من SSO مجموعات إلى محلي InvenTree مجموعات. إذا ال محلي مجموعة يقوم غير موجود، هو سوف يكون تم الإنشاء." + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "إزالة مجموعات outside لـ SSO" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "Whether مجموعات مسند إلى ال مستخدم ينبغي يكون تمت الإزالة إذا they هي غير backend حسب ال IdP. Disabling هذا إعداد might cause security issues" + +#: common/setting/system.py:1072 +msgid "Email required" +msgstr "بريد إلكتروني مطلوب" + +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" +msgstr "طلب مستخدم إلى supply بريد على signup" + +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "Auto-fill SSO مستخدمون" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" +msgstr "تلقائيًا fill خارج user-details من SSO account-data" + +#: common/setting/system.py:1084 +msgid "Mail twice" +msgstr "بريد twice" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" +msgstr "على signup ask مستخدمون twice لـ الخاص بهم بريد" + +#: common/setting/system.py:1090 +msgid "Password twice" +msgstr "كلمة المرور twice" + +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" -msgstr "" +msgstr "على signup ask مستخدمون twice لـ الخاص بهم كلمة المرور" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" -msgstr "" +msgstr "مسموح domains" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" -msgstr "" +msgstr "Restrict signup إلى certain domains (comma-separated، starting مع @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" -msgstr "" +msgstr "مجموعة على signup" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." -msgstr "" +msgstr "مجموعة إلى الذي جديد مستخدمون هي مسند على تسجيل. إذا SSO مجموعة مزامنة هو مفعّل، هذا مجموعة هو فقط تعيين إذا لا مجموعة يمكن يكون مسند من ال IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." -msgstr "" - -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." -msgstr "" - -#: common/setting/system.py:1060 -msgid "Check plugins on startup" -msgstr "" - -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" -msgstr "" - -#: common/setting/system.py:1069 -msgid "Check for plugin updates" -msgstr "" - -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" -msgstr "" - -#: common/setting/system.py:1076 -msgid "Enable URL integration" -msgstr "" - -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" -msgstr "" - -#: common/setting/system.py:1083 -msgid "Enable navigation integration" -msgstr "" - -#: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" -msgstr "" - -#: common/setting/system.py:1090 -msgid "Enable app integration" -msgstr "" - -#: common/setting/system.py:1091 -msgid "Enable plugins to add apps" -msgstr "" - -#: common/setting/system.py:1097 -msgid "Enable schedule integration" -msgstr "" - -#: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" -msgstr "" - -#: common/setting/system.py:1104 -msgid "Enable event integration" -msgstr "" - -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" -msgstr "" - -#: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" -msgstr "" +msgstr "مستخدمون يجب استخدام multifactor security." #: common/setting/system.py:1118 -msgid "Enable mail integration" -msgstr "" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +msgstr "Enabling هذا إعداد سوف طلب الكل مستخدمون إلى تعيين أعلى multifactor مصادقة. الكل sessions سوف يكون disconnected immediately." -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" -msgstr "" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" +msgstr "فحص إضافات على startup" #: common/setting/system.py:1125 -msgid "Enable project codes" -msgstr "" +msgid "Check that all plugins are installed on startup - enable in container environments" +msgstr "فحص ذلك الكل إضافات هي مثبت على startup - تفعيل في container environments" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" -msgstr "" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" +msgstr "فحص لـ إضافة updates" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" -msgstr "" +msgid "Enable periodic checks for updates to installed plugins" +msgstr "تفعيل periodic checks لـ updates إلى مثبت إضافات" #: common/setting/system.py:1139 -msgid "Exclude External Locations" -msgstr "" +msgid "Enable URL integration" +msgstr "تفعيل URL تكامل" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "تفعيل إضافات إلى إضافة URL routes" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" +msgstr "تفعيل تنقل تكامل" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" -msgstr "" +msgid "Enable plugins to integrate into navigation" +msgstr "تفعيل إضافات إلى integrate إلى تنقل" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" -msgstr "" +#: common/setting/system.py:1153 +msgid "Enable app integration" +msgstr "تفعيل تطبيق تكامل" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" -msgstr "" +msgid "Enable plugins to add apps" +msgstr "تفعيل إضافات إلى إضافة apps" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" +msgstr "تفعيل schedule تكامل" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" -msgstr "" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" +msgstr "تفعيل إضافات إلى run مجدول مهام" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" +#: common/setting/system.py:1167 +msgid "Enable event integration" +msgstr "تفعيل event تكامل" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" -msgstr "" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" +msgstr "تفعيل إضافات إلى respond إلى داخلي events" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +#: common/setting/system.py:1174 +msgid "Enable interface integration" +msgstr "تفعيل واجهة تكامل" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" -msgstr "" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" +msgstr "تفعيل إضافات إلى integrate إلى ال مستخدم واجهة" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "" +msgid "Enable mail integration" +msgstr "تفعيل بريد تكامل" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" +msgstr "تفعيل إضافات إلى عملية صادر/وارد mails" #: common/setting/system.py:1188 -msgid "Display Users full names" -msgstr "" +msgid "Enable project codes" +msgstr "تفعيل مشروع رموز" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" -msgstr "" +msgid "Enable project codes for tracking projects" +msgstr "تفعيل مشروع رموز لـ تتبع مشاريع" #: common/setting/system.py:1194 -msgid "Display User Profiles" -msgstr "" +msgid "Enable Stocktake" +msgstr "تفعيل جرد المخزون" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" -msgstr "" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" +msgstr "تفعيل الوظيفة لـ recording تاريخي مخزون levels و قيمة" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" -msgstr "" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" +msgstr "استبعاد خارجي مواقع" #: common/setting/system.py:1204 +msgid "Exclude stock items in external locations from stocktake calculations" +msgstr "استبعاد عناصر المخزون في خارجي مواقع من جرد المخزون حسابات" + +#: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "تلقائي جرد المخزون Period" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "عدد أيام بين تلقائي جرد المخزون recording" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "حذف Old جرد المخزون سجلات" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "حذف جرد المخزون سجلات older من ال محدد رقم لـ أيام" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "جرد المخزون الحذف فاصل" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "جرد المخزون سجلات سوف يكون تم الحذف بعد محدد رقم لـ أيام" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "حذف Old مخزون تتبع سجلات" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "حذف مخزون تتبع سجلات older من ال محدد رقم لـ أيام" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "مخزون تتبع الحذف فاصل" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "مخزون تتبع سجلات سوف يكون تم الحذف بعد محدد رقم لـ أيام" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "عرض مستخدمون كامل names" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "عرض مستخدمون كامل names بدلًا من لـ usernames" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "عرض مستخدم ملفات شخصية" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "عرض مستخدمون ملفات شخصية على الخاص بهم ملف شخصي صفحة" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "Week Starts على" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "Starting day لـ ال week، لـ عرض في تقويم views" + +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "تقويم Horizon" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "عدد months إلى ال future إلى عرض في تقويم views" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" -msgstr "" +msgstr "تفعيل اختبار Station بيانات" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" -msgstr "" +msgstr "تفعيل اختبار station بيانات collection لـ اختبار نتائج" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" -msgstr "" +msgstr "تفعيل آلة Ping" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" -msgstr "" +msgstr "تفعيل حالة periodic ping مهمة لـ مسجل آلات إلى فحص الخاص بهم" #: common/setting/user.py:23 msgid "Inline label display" -msgstr "" +msgstr "Inline ملصق عرض" #: common/setting/user.py:25 msgid "Display PDF labels in the browser, instead of downloading as a file" -msgstr "" +msgstr "عرض PDF ملصقات في ال متصفح، بدلًا من لـ downloading بصفته ملف" #: common/setting/user.py:31 msgid "Default label printer" -msgstr "" +msgstr "افتراضي ملصق طابعة" #: common/setting/user.py:32 msgid "Configure which label printer should be selected by default" -msgstr "" +msgstr "Configure الذي ملصق طابعة ينبغي يكون محدد حسب افتراضي" #: common/setting/user.py:37 msgid "Inline report display" -msgstr "" +msgstr "Inline تقرير عرض" #: common/setting/user.py:39 msgid "Display PDF reports in the browser, instead of downloading as a file" -msgstr "" +msgstr "عرض PDF تقارير في ال متصفح، بدلًا من لـ downloading بصفته ملف" #: common/setting/user.py:45 msgid "Barcode Scanner in Form Fields" -msgstr "" +msgstr "باركود ماسح في Form حقول" #: common/setting/user.py:46 msgid "Allow barcode scanner input in form fields" -msgstr "" +msgstr "السماح باركود ماسح إدخال في form حقول" #: common/setting/user.py:51 msgid "Search Parts" -msgstr "" +msgstr "بحث أصناف" #: common/setting/user.py:52 msgid "Display parts in search preview window" -msgstr "" +msgstr "عرض أصناف في بحث معاينة نافذة" #: common/setting/user.py:57 msgid "Search Supplier Parts" -msgstr "" +msgstr "بحث أصناف المورد" #: common/setting/user.py:58 msgid "Display supplier parts in search preview window" -msgstr "" +msgstr "عرض أصناف المورد في بحث معاينة نافذة" #: common/setting/user.py:63 msgid "Search Manufacturer Parts" -msgstr "" +msgstr "بحث أصناف الشركة المصنعة" #: common/setting/user.py:64 msgid "Display manufacturer parts in search preview window" -msgstr "" +msgstr "عرض أصناف الشركة المصنعة في بحث معاينة نافذة" #: common/setting/user.py:69 msgid "Hide Inactive Parts" -msgstr "" +msgstr "إخفاء غير نشط أصناف" #: common/setting/user.py:70 msgid "Excluded inactive parts from search preview window" -msgstr "" +msgstr "Excluded غير نشط أصناف من بحث معاينة نافذة" #: common/setting/user.py:75 msgid "Search Categories" -msgstr "" +msgstr "بحث فئات" #: common/setting/user.py:76 msgid "Display part categories in search preview window" -msgstr "" +msgstr "عرض فئات الأصناف في بحث معاينة نافذة" #: common/setting/user.py:81 msgid "Search Stock" -msgstr "" +msgstr "بحث مخزون" #: common/setting/user.py:82 msgid "Display stock items in search preview window" -msgstr "" +msgstr "عرض عناصر المخزون في بحث معاينة نافذة" #: common/setting/user.py:87 msgid "Hide Unavailable Stock Items" -msgstr "" +msgstr "إخفاء غير متاح عناصر المخزون" #: common/setting/user.py:89 msgid "Exclude stock items which are not available from the search preview window" -msgstr "" +msgstr "استبعاد عناصر المخزون الذي هي غير متاح من ال بحث معاينة نافذة" #: common/setting/user.py:95 msgid "Search Locations" -msgstr "" +msgstr "بحث مواقع" #: common/setting/user.py:96 msgid "Display stock locations in search preview window" -msgstr "" +msgstr "عرض مواقع المخزون في بحث معاينة نافذة" #: common/setting/user.py:101 msgid "Search Companies" -msgstr "" +msgstr "بحث شركات" #: common/setting/user.py:102 msgid "Display companies in search preview window" -msgstr "" +msgstr "عرض شركات في بحث معاينة نافذة" #: common/setting/user.py:107 msgid "Search Build Orders" -msgstr "" +msgstr "بحث أوامر الإنتاج" #: common/setting/user.py:108 msgid "Display build orders in search preview window" -msgstr "" +msgstr "عرض أوامر الإنتاج في بحث معاينة نافذة" #: common/setting/user.py:113 msgid "Search Purchase Orders" -msgstr "" +msgstr "بحث طلبات الشراء" #: common/setting/user.py:114 msgid "Display purchase orders in search preview window" -msgstr "" +msgstr "عرض طلبات الشراء في بحث معاينة نافذة" #: common/setting/user.py:119 msgid "Exclude Inactive Purchase Orders" -msgstr "" +msgstr "استبعاد غير نشط طلبات الشراء" #: common/setting/user.py:120 msgid "Exclude inactive purchase orders from search preview window" -msgstr "" +msgstr "استبعاد غير نشط طلبات الشراء من بحث معاينة نافذة" #: common/setting/user.py:125 msgid "Search Sales Orders" -msgstr "" +msgstr "بحث طلبات البيع" #: common/setting/user.py:126 msgid "Display sales orders in search preview window" -msgstr "" +msgstr "عرض طلبات البيع في بحث معاينة نافذة" #: common/setting/user.py:131 msgid "Exclude Inactive Sales Orders" -msgstr "" +msgstr "استبعاد غير نشط طلبات البيع" #: common/setting/user.py:132 msgid "Exclude inactive sales orders from search preview window" -msgstr "" +msgstr "استبعاد غير نشط طلبات البيع من بحث معاينة نافذة" #: common/setting/user.py:137 msgid "Search Sales Order Shipments" -msgstr "" +msgstr "بحث طلب البيع شحنات" #: common/setting/user.py:138 msgid "Display sales order shipments in search preview window" -msgstr "" +msgstr "عرض طلب البيع شحنات في بحث معاينة نافذة" #: common/setting/user.py:143 msgid "Search Return Orders" -msgstr "" +msgstr "بحث طلبات الإرجاع" #: common/setting/user.py:144 msgid "Display return orders in search preview window" -msgstr "" +msgstr "عرض طلبات الإرجاع في بحث معاينة نافذة" #: common/setting/user.py:149 msgid "Exclude Inactive Return Orders" -msgstr "" +msgstr "استبعاد غير نشط طلبات الإرجاع" #: common/setting/user.py:150 msgid "Exclude inactive return orders from search preview window" -msgstr "" +msgstr "استبعاد غير نشط طلبات الإرجاع من بحث معاينة نافذة" #: common/setting/user.py:155 msgid "Search Preview Results" -msgstr "" +msgstr "بحث معاينة نتائج" #: common/setting/user.py:157 msgid "Number of results to show in each section of the search preview window" -msgstr "" +msgstr "عدد نتائج إلى عرض في كل section لـ ال بحث معاينة نافذة" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" -msgstr "" +msgstr "تعبير نمطي بحث" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" -msgstr "" - -#: common/setting/user.py:169 -msgid "Whole Word Search" -msgstr "" - -#: common/setting/user.py:170 -msgid "Search queries return results for whole word matches" -msgstr "" - -#: common/setting/user.py:175 -msgid "Search Notes" -msgstr "" +msgstr "تفعيل regular expressions في بحث queries" #: common/setting/user.py:177 -msgid "Search queries return results for matches from the item's notes" -msgstr "" +msgid "Whole Word Search" +msgstr "Whole Word بحث" + +#: common/setting/user.py:178 +msgid "Search queries return results for whole word matches" +msgstr "بحث queries إرجاع نتائج لـ whole word matches" #: common/setting/user.py:183 +msgid "Search Notes" +msgstr "بحث ملاحظات" + +#: common/setting/user.py:185 +msgid "Search queries return results for matches from the item's notes" +msgstr "بحث queries إرجاع نتائج لـ matches من ال item's ملاحظات" + +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" -msgstr "" +msgstr "Escape مفتاح Closes Forms" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" -msgstr "" +msgstr "استخدام ال escape مفتاح إلى إغلاق modal forms" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" -msgstr "" +msgstr "ال navbar position هو fixed إلى ال أعلى لـ ال شاشة" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" -msgstr "" +msgstr "Fixed جدول Headers" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" -msgstr "" +msgstr "جدول headers هي fixed إلى ال أعلى لـ ال جدول" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" -msgstr "" +msgstr "عرض Spotlight" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" -msgstr "" +msgstr "تفعيل spotlight تنقل الوظيفة" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" -msgstr "" +msgstr "تنقل Icons" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" -msgstr "" +msgstr "عرض icons في ال تنقل bar" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" -msgstr "" +msgstr "تاريخ تنسيق" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" +msgstr "Preferred تنسيق لـ displaying تواريخ" + +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" -msgstr "" - -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." -msgstr "" +msgid "Show Stock History" +msgstr "عرض مخزون سجل" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" +msgstr "عرض مخزون سجل معلومات في ال صنف تفصيل صفحة" #: common/setting/user.py:247 -msgid "Show full part categories in tables" -msgstr "" +msgid "Show Last Breadcrumb" +msgstr "عرض آخر Breadcrumb" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." -msgstr "" +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" +msgstr "عرض ال حالي صفحة في breadcrumbs" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" -msgstr "" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "عرض إضافي نموذج معلومات" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" -msgstr "" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "عرض إضافي معلومات في نموذج اختيار dropdowns" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" +msgstr "عرض كامل موقع المخزون في tables" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" -msgstr "" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "معطّل: ال كامل موقع مسار هو معروض بصفته hover tooltip. مفعّل: ال كامل موقع مسار هو معروض بصفته plain نص." #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "عرض كامل فئات الأصناف في tables" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "معطّل: ال كامل فئة مسار هو معروض بصفته hover tooltip. مفعّل: ال كامل فئة مسار هو معروض بصفته plain نص." + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "عرض Subassemblies في BOM جدول" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "تفعيل عرض لـ subassemblies في ال BOM جدول" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "استلام خطأ تقارير" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "استلام إشعارات لـ نظام أخطاء" + +#: common/setting/user.py:287 msgid "Last used printing machines" -msgstr "" +msgstr "آخر مستخدم الطباعة آلات" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" -msgstr "" +msgstr "حفظ ال آخر مستخدم الطباعة آلات لـ مستخدم" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" -msgstr "" +msgstr "عرض عناصر عند Final مستوى" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" -msgstr "" +msgstr "تلقائيًا افتراضي إلى showing عناصر/أصناف بدلًا من لـ sub-levels لـ مواقع أو فئات مع لا children" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" -msgstr "" +msgstr "الكل نماذج" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" -msgstr "" +msgstr "لا مرفق نموذج نوع مقدم" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" -msgstr "" +msgstr "غير صالح مرفق نموذج نوع" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "ملف حجم يتجاوز أقصى رفع حد لـ {max_size} MB" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "غير صالح ملف اسم" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" -msgstr "" +msgstr "أدنى أماكن لا يمكن يكون أكبر من أقصى أماكن" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" -msgstr "" +msgstr "أقصى أماكن لا يمكن يكون أقل من أدنى أماكن" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." -msgstr "" +msgstr "فارغ domain هو غير مسموح." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" -msgstr "" +msgstr "غير صالح domain اسم: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" -msgstr "" +msgstr "يجب أن يكون القيمة uppercase" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" -msgstr "" +msgstr "يجب أن يكون القيمة صالح variable معرف" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" -msgstr "" +msgstr "صنف هو نشط" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" -msgstr "" +msgstr "شركة مصنعة هو نشط" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" -msgstr "" - -#: company/api.py:254 -msgid "Primary Supplier Part" -msgstr "" - -#: company/api.py:258 -msgid "Internal Part is Active" -msgstr "" +msgstr "صنف المورد هو نشط" #: company/api.py:263 +msgid "Primary Supplier Part" +msgstr "أساسي صنف المورد" + +#: company/api.py:267 +msgid "Internal Part is Active" +msgstr "داخلي صنف هو نشط" + +#: company/api.py:272 msgid "Supplier is Active" -msgstr "" +msgstr "مورد هو نشط" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" -msgstr "" +msgstr "الشركة المصنعة" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" -msgstr "" +msgstr "الشركة" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" -msgstr "" +msgstr "لديه مخزون" #: company/models.py:125 msgid "Companies" -msgstr "" +msgstr "الشركات" #: company/models.py:153 msgid "Company description" -msgstr "" +msgstr "شركة وصف" #: company/models.py:154 msgid "Description of the company" -msgstr "" +msgstr "وصف لـ ال شركة" #: company/models.py:160 msgid "Website" @@ -4109,64 +4373,64 @@ msgstr "" #: company/models.py:161 msgid "Company website URL" -msgstr "" +msgstr "شركة website URL" #: company/models.py:167 msgid "Phone number" -msgstr "" +msgstr "هاتف رقم" #: company/models.py:169 msgid "Contact phone number" -msgstr "" +msgstr "جهة اتصال هاتف رقم" #: company/models.py:176 msgid "Contact email address" -msgstr "" +msgstr "جهة اتصال بريد إلكتروني عنوان" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" -msgstr "" +msgstr "جهة الاتصال" #: company/models.py:183 msgid "Point of contact" -msgstr "" +msgstr "نقطة لـ جهة اتصال" #: company/models.py:189 msgid "Link to external company information" -msgstr "" +msgstr "رابط إلى خارجي شركة معلومات" #: company/models.py:194 msgid "Is this company active?" -msgstr "" +msgstr "هو هذا شركة نشط؟" #: company/models.py:199 msgid "Is customer" -msgstr "" +msgstr "هو عميل" #: company/models.py:200 msgid "Do you sell items to this company?" -msgstr "" +msgstr "تنفيذ أنت sell عناصر إلى هذا شركة؟" #: company/models.py:205 msgid "Is supplier" -msgstr "" +msgstr "هو مورد" #: company/models.py:206 msgid "Do you purchase items from this company?" -msgstr "" +msgstr "تنفيذ أنت شراء عناصر من هذا شركة؟" #: company/models.py:211 msgid "Is manufacturer" -msgstr "" +msgstr "هو شركة مصنعة" #: company/models.py:212 msgid "Does this company manufacture parts?" -msgstr "" +msgstr "يقوم هذا شركة manufacture أصناف؟" #: company/models.py:220 msgid "Default currency used for this company" -msgstr "" +msgstr "افتراضي عملة مستخدم لـ هذا شركة" #: company/models.py:227 msgid "Tax ID" @@ -4174,291 +4438,291 @@ msgstr "" #: company/models.py:228 msgid "Company Tax ID" -msgstr "" +msgstr "شركة Tax ID" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" -msgstr "" +msgstr "العنوان" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" -msgstr "" +msgstr "تحديد شركة" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" -msgstr "" +msgstr "عنوان عنوان" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" -msgstr "" +msgstr "عنوان describing ال عنوان سجل" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" -msgstr "" +msgstr "أساسي عنوان" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" -msgstr "" +msgstr "تعيين بصفته أساسي عنوان" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" -msgstr "" +msgstr "سطر 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" -msgstr "" +msgstr "عنوان سطر 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" -msgstr "" +msgstr "سطر 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" -msgstr "" +msgstr "عنوان سطر 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" -msgstr "" +msgstr "Postal رمز" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" -msgstr "" +msgstr "Postal رمز city/region" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" -msgstr "" +msgstr "حالة/Province" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" -msgstr "" +msgstr "حالة أو province" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" -msgstr "" +msgstr "عنوان country" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" -msgstr "" +msgstr "Courier شحن ملاحظات" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" -msgstr "" +msgstr "ملاحظات لـ شحن courier" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" -msgstr "" +msgstr "داخلي شحن ملاحظات" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" -msgstr "" +msgstr "شحن ملاحظات لـ داخلي استخدام" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" -msgstr "" +msgstr "رابط إلى عنوان معلومات (خارجي)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" -msgstr "" +msgstr "صنف الشركة المصنعة" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" -msgstr "" +msgstr "أساس صنف" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" -msgstr "" +msgstr "تحديد صنف" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" -msgstr "" +msgstr "تحديد شركة مصنعة" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" -msgstr "" +msgstr "صنف الشركة المصنعة رقم" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" -msgstr "" +msgstr "URL لـ خارجي صنف الشركة المصنعة رابط" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" -msgstr "" +msgstr "صنف الشركة المصنعة وصف" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" -msgstr "" +msgstr "يجب أن يكون حزمة وحدات compatible مع ال أساس صنف وحدات" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" -msgstr "" +msgstr "يجب أن يكون حزمة وحدات أكبر من صفر" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" -msgstr "" +msgstr "مرتبط صنف الشركة المصنعة يجب مرجع ال نفس أساس صنف" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" -msgstr "" +msgstr "المورد" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" -msgstr "" +msgstr "تحديد مورد" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" -msgstr "" +msgstr "مورد مخزون keeping وحدة" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" -msgstr "" - -#: company/models.py:792 -msgid "Primary" -msgstr "" +msgstr "هو هذا صنف المورد نشط؟" #: company/models.py:793 +msgid "Primary" +msgstr "أساسي" + +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgstr "هو هذا ال أساسي صنف المورد لـ ال مرتبط صنف؟" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" -msgstr "" +msgstr "تحديد صنف الشركة المصنعة" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" -msgstr "" +msgstr "URL لـ خارجي صنف المورد رابط" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" -msgstr "" +msgstr "صنف المورد وصف" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" -msgstr "" +msgstr "أساس تكلفة" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" -msgstr "" +msgstr "أدنى charge (e.g. stocking fee)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" -msgstr "" +msgstr "تعبئة" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" -msgstr "" +msgstr "صنف تعبئة" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" -msgstr "" +msgstr "كمية حزمة" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." -msgstr "" +msgstr "إجمالي كمية مورد في مفرد حزمة. ترك فارغ لـ مفرد عناصر." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" -msgstr "" +msgstr "متعدد" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" -msgstr "" +msgstr "طلب متعدد" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" -msgstr "" - -#: company/models.py:889 -msgid "Availability Updated" -msgstr "" +msgstr "كمية متاح من مورد" #: company/models.py:890 +msgid "Availability Updated" +msgstr "Availability تم التحديث" + +#: company/models.py:891 msgid "Date of last update of availability data" -msgstr "" +msgstr "تاريخ لـ آخر تحديث لـ availability بيانات" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" -msgstr "" +msgstr "مورد سعر فاصل" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" -msgstr "" +msgstr "افتراضي عملة مستخدم لـ هذا مورد" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" -msgstr "" +msgstr "شركة اسم" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" -msgstr "" - -#: company/serializers.py:408 -msgid "Price Breaks" -msgstr "" +msgstr "متوفر في المخزون" #: company/serializers.py:461 +msgid "Price Breaks" +msgstr "سعر فواصل" + +#: company/serializers.py:514 msgid "Pretty Name" -msgstr "" +msgstr "Pretty اسم" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" -msgstr "" +msgstr "خطأ في حدث during بيانات تصدير" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" -msgstr "" +msgstr "بيانات تصدير إضافة مرتجع incorrect بيانات تنسيق" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" -msgstr "" +msgstr "تصدير تنسيق" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" -msgstr "" +msgstr "تحديد تصدير ملف تنسيق" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" -msgstr "" +msgstr "تصدير إضافة" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" -msgstr "" +msgstr "تحديد تصدير إضافة" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" -msgstr "" +msgstr "Additional حالة معلومات لـ هذا عنصر" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" -msgstr "" +msgstr "مخصص حالة مفتاح" #: generic/states/serializers.py:26 msgid "Custom" -msgstr "" +msgstr "مخصص" #: generic/states/serializers.py:37 msgid "Class" @@ -4466,7 +4730,7 @@ msgstr "" #: generic/states/serializers.py:40 msgid "Values" -msgstr "" +msgstr "قيم" #: generic/states/tests.py:22 order/status_codes.py:13 msgid "Placed" @@ -4474,171 +4738,204 @@ msgstr "" #: generic/states/validators.py:21 msgid "Invalid status code" -msgstr "" +msgstr "غير صالح حالة رمز" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" -msgstr "" +msgstr "بيانات ملف" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" -msgstr "" +msgstr "بيانات ملف إلى استيراد" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" -msgstr "" +msgstr "أعمدة" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" -msgstr "" +msgstr "هدف نموذج نوع لـ هذا استيراد جلسة" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" -msgstr "" +msgstr "حالة استيراد" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" -msgstr "" +msgstr "حقل Defaults" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" -msgstr "" - -#: importer/models.py:121 -msgid "Field Filters" -msgstr "" +msgstr "حقل Overrides" #: importer/models.py:127 +msgid "Field Filters" +msgstr "حقل مرشحات" + +#: importer/models.py:134 msgid "Update Existing Records" -msgstr "" +msgstr "تحديث موجود سجلات" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" -msgstr "" +msgstr "إذا مفعّل، موجود سجلات سوف يكون تم التحديث مع جديد بيانات" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" -msgstr "" +msgstr "Some مطلوب حقول لديه غير تم mapped" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "مكتمل صف عد سجل" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "صف عد سجل" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" -msgstr "" +msgstr "موجود قاعدة بيانات معرف لـ ال سجل" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" -msgstr "" +msgstr "عمود هو بالفعل mapped إلى قاعدة بيانات حقل" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" -msgstr "" +msgstr "حقل هو بالفعل mapped إلى بيانات عمود" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" -msgstr "" +msgstr "يجب أن يكون عمود mapping مرتبط إلى صالح استيراد جلسة" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" -msgstr "" +msgstr "عمود يقوم غير موجود في ال بيانات ملف" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" -msgstr "" +msgstr "حقل يقوم غير موجود في ال هدف نموذج" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" -msgstr "" +msgstr "محدد حقل هو read-only" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "بحث حقل يمكن فقط يكون تعيين لـ مرتبط (foreign-key) حقول" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "غير صالح بحث حقل. صالح خيارات هي: {options}" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" -msgstr "" +msgstr "استيراد جلسة" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" -msgstr "" +msgstr "حقل" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" -msgstr "" +msgstr "عمود" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "بحث حقل" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "قاعدة بيانات حقل إلى استخدام لـ foreign-key بحث. ترك فارغ لـ تلقائي بحث." + +#: importer/models.py:674 msgid "Row Index" -msgstr "" +msgstr "صف Index" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" -msgstr "" +msgstr "أصلي صف بيانات" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" -msgstr "" +msgstr "أخطاء" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" -msgstr "" +msgstr "صالح" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "" +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "متعدد matches تم العثور لـ قيمة - يرجى ensure ال قيمة هو فريد، أو تحديد specific بحث حقل" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" -msgstr "" +msgstr "لا سجل تم العثور مع ال مقدم ID" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" -msgstr "" +msgstr "غير صالح ID تنسيق مقدم" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "ID هو مطلوب لـ جارٍ التحديث موجود سجلات." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" -msgstr "" +msgstr "Unsupported بيانات ملف تنسيق" #: importer/operations.py:43 msgid "Failed to open data file" +msgstr "فشل في فتح بيانات ملف" + +#: importer/operations.py:55 +msgid "Could not decode data file as text" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:62 msgid "Invalid data file dimensions" -msgstr "" +msgstr "غير صالح بيانات ملف dimensions" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" -msgstr "" +msgstr "غير صالح حقل defaults" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" -msgstr "" +msgstr "غير صالح حقل overrides" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" -msgstr "" +msgstr "غير صالح حقل مرشحات" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" -msgstr "" +msgstr "صفوف" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" -msgstr "" +msgstr "قائمة لـ صف IDs إلى قبول" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" -msgstr "" +msgstr "لا صفوف مقدم" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" -msgstr "" +msgstr "صف يقوم غير belong إلى هذا جلسة" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" -msgstr "" +msgstr "صف يحتوي غير صالح بيانات" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" -msgstr "" +msgstr "صف لديه بالفعل تم مكتمل" #: importer/status_codes.py:13 msgid "Initializing" @@ -4646,167 +4943,167 @@ msgstr "" #: importer/status_codes.py:18 msgid "Mapping Columns" -msgstr "" +msgstr "Mapping أعمدة" #: importer/status_codes.py:21 msgid "Importing Data" -msgstr "" +msgstr "Importing بيانات" #: importer/status_codes.py:24 msgid "Processing Data" -msgstr "" +msgstr "Processing بيانات" #: importer/validators.py:21 msgid "Data file exceeds maximum size limit" -msgstr "" +msgstr "بيانات ملف يتجاوز أقصى حجم حد" #: importer/validators.py:26 msgid "Data file contains no headers" -msgstr "" +msgstr "بيانات ملف يحتوي لا headers" #: importer/validators.py:29 msgid "Data file contains too many columns" -msgstr "" +msgstr "بيانات ملف يحتوي أيضًا many أعمدة" #: importer/validators.py:32 msgid "Data file contains too many rows" -msgstr "" +msgstr "بيانات ملف يحتوي أيضًا many صفوف" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" -msgstr "" +msgstr "يجب أن يكون القيمة صالح dictionary كائن" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" -msgstr "" +msgstr "عدد copies إلى طباعة لـ كل ملصق" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" -msgstr "" +msgstr "غير معروف" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" -msgstr "" +msgstr "الطباعة" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" -msgstr "" +msgstr "تحذير" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" -msgstr "" +msgstr "لا media" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" -msgstr "" +msgstr "خطأ" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" -msgstr "" +msgstr "ملصق طابعة" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." -msgstr "" +msgstr "Directly طباعة ملصقات لـ various عناصر." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" -msgstr "" +msgstr "طابعة موقع" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" -msgstr "" +msgstr "Scope ال طابعة إلى specific موقع" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" -msgstr "" +msgstr "اسم لـ آلة" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" -msgstr "" +msgstr "آلة نوع" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" -msgstr "" +msgstr "نوع لـ آلة" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" -msgstr "" +msgstr "برنامج تشغيل" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" -msgstr "" +msgstr "برنامج تشغيل مستخدم لـ ال آلة" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" -msgstr "" +msgstr "آلات يمكن يكون معطّل" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" -msgstr "" +msgstr "برنامج تشغيل متاح" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" -msgstr "" +msgstr "لا أخطاء" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" -msgstr "" +msgstr "حالة آلة" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" -msgstr "" +msgstr "آلة" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" -msgstr "" +msgstr "آلة Config" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" -msgstr "" +msgstr "Config نوع" #: machine/serializers.py:24 msgid "Key of the property" -msgstr "" +msgstr "مفتاح لـ ال property" #: machine/serializers.py:27 msgid "Value of the property" -msgstr "" +msgstr "قيمة لـ ال property" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" -msgstr "" +msgstr "مجموعة" #: machine/serializers.py:30 msgid "Grouping of the property" -msgstr "" +msgstr "Grouping لـ ال property" #: machine/serializers.py:33 msgid "Type" -msgstr "" +msgstr "نوع" #: machine/serializers.py:35 msgid "Type of the property" -msgstr "" +msgstr "نوع لـ ال property" #: machine/serializers.py:40 msgid "Max Progress" @@ -4814,901 +5111,1011 @@ msgstr "" #: machine/serializers.py:41 msgid "Maximum value for progress type, required if type=progress" -msgstr "" +msgstr "أقصى قيمة لـ progress نوع، مطلوب إذا type=progress" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" -msgstr "" +msgstr "طلب مرجع" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" -msgstr "" +msgstr "متبقي" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" -msgstr "" +msgstr "لديه مشروع رمز" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" -msgstr "" +msgstr "تم الإنشاء حسب" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" -msgstr "" +msgstr "تم الإنشاء قبل" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" -msgstr "" +msgstr "تم الإنشاء بعد" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" -msgstr "" +msgstr "تاريخ لديه بدء" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" -msgstr "" +msgstr "بدء تاريخ قبل" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" -msgstr "" +msgstr "بدء تاريخ بعد" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" -msgstr "" +msgstr "تاريخ لديه هدف" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" -msgstr "" +msgstr "التاريخ المستهدف قبل" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" -msgstr "" +msgstr "التاريخ المستهدف بعد" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" -msgstr "" +msgstr "تم التحديث قبل" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" -msgstr "" +msgstr "تم التحديث بعد" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" -msgstr "" +msgstr "لديه التسعير" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" -msgstr "" +msgstr "مكتمل قبل" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" -msgstr "" +msgstr "مكتمل بعد" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" -msgstr "" +msgstr "خارجي أمر الإنتاج" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" -msgstr "" +msgstr "الطلب" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" -msgstr "" +msgstr "طلب مكتمل" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" -msgstr "" +msgstr "داخلي صنف" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" -msgstr "" +msgstr "طلب قيد الانتظار" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" -msgstr "" +msgstr "مكتمل" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" -msgstr "" +msgstr "لديه شحنة" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" -msgstr "" +msgstr "شحنة غير تم العثور" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" -msgstr "" +msgstr "طلب شراء" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 #: templates/email/overdue_sales_order.html:15 msgid "Sales Order" -msgstr "" +msgstr "طلب بيع" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" -msgstr "" +msgstr "طلب إرجاع" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "طلب تحويل" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" -msgstr "" +msgstr "إجمالي سعر" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" -msgstr "" +msgstr "إجمالي سعر لـ هذا طلب" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" -msgstr "" +msgstr "طلب عملة" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" -msgstr "" +msgstr "عملة لـ هذا طلب (ترك فارغ إلى استخدام شركة افتراضي)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" -msgstr "" +msgstr "هذا طلب هو مقفل و لا يمكن يكون modified" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" -msgstr "" +msgstr "جهة اتصال يقوم غير مطابقة محدد شركة" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" -msgstr "" +msgstr "يجب أن يكون تاريخ بدء تاريخ قبل هدف" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" -msgstr "" +msgstr "عنوان يقوم غير مطابقة محدد شركة" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" -msgstr "" +msgstr "طلب وصف (اختياري)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" -msgstr "" +msgstr "تحديد مشروع رمز لـ هذا طلب" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" -msgstr "" +msgstr "رابط إلى خارجي صفحة" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" -msgstr "" +msgstr "تاريخ بدء" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" -msgstr "" +msgstr "مجدول بدء تاريخ لـ هذا طلب" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" -msgstr "" +msgstr "التاريخ المستهدف" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." -msgstr "" +msgstr "Expected تاريخ لـ طلب تسليم. طلب سوف يكون متأخر بعد هذا تاريخ." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" -msgstr "" +msgstr "تاريخ صرف" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" -msgstr "" +msgstr "تاريخ طلب كان مصروف" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" -msgstr "" +msgstr "تم التحديث عند" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" -msgstr "" +msgstr "مستخدم أو مجموعة مسؤول لـ هذا طلب" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" -msgstr "" +msgstr "نقطة لـ جهة اتصال لـ هذا طلب" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" -msgstr "" +msgstr "شركة عنوان لـ هذا طلب" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" -msgstr "" +msgstr "طلب مرجع" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" -msgstr "" +msgstr "الحالة" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" -msgstr "" +msgstr "حالة طلب الشراء" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" -msgstr "" +msgstr "شركة من الذي ال عناصر هي being ordered" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" -msgstr "" +msgstr "مورد مرجع" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" -msgstr "" +msgstr "مورد طلب مرجع رمز" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" -msgstr "" +msgstr "مستلم حسب" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" -msgstr "" +msgstr "تاريخ طلب كان مكتمل" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" -msgstr "" +msgstr "الوجهة" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" -msgstr "" +msgstr "الوجهة لـ مستلم عناصر" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" -msgstr "" +msgstr "صنف مورد يجب مطابقة PO مورد" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" -msgstr "" +msgstr "بند يقوم غير مطابقة طلب الشراء" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" -msgstr "" +msgstr "بند هو مفقود مرتبط صنف" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" -msgstr "" +msgstr "يجب أن يكون الكمية موجب رقم" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" -msgstr "" +msgstr "الأرقام التسلسلية لا يمكن يكون مسند إلى افتراضي أصناف" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "السماح أي مخزون (مسلسل أو unserialized)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "مسلسل مخزون فقط" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "Unserialized مخزون فقط" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" -msgstr "" +msgstr "العميل" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" -msgstr "" +msgstr "شركة إلى الذي ال عناصر هي being sold" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" -msgstr "" +msgstr "حالة طلب البيع" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " -msgstr "" +msgstr "عميل مرجع" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" -msgstr "" +msgstr "عميل طلب مرجع رمز" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" -msgstr "" +msgstr "تاريخ شحنة" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" -msgstr "" +msgstr "مشحون حسب" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "بند هو غير مرتبط مع هذا طلب" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "لا مطابقة تم العثور لـ ال التالي الأرقام التسلسلية" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "ال التالي الأرقام التسلسلية هي غير متاح" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" -msgstr "" +msgstr "طلب هو بالفعل مكتمل" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" -msgstr "" +msgstr "طلب هو بالفعل ملغى" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" -msgstr "" +msgstr "فقط فتح طلب يمكن يكون معلّم بصفته مكتمل" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" -msgstr "" +msgstr "طلب لا يمكن يكون مكتمل بصفته هناك هي غير مكتمل شحنات" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" -msgstr "" +msgstr "طلب لا يمكن يكون مكتمل بصفته هناك هي غير مكتمل تخصيصات" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" -msgstr "" +msgstr "طلب لا يمكن يكون مكتمل بصفته هناك هي غير مكتمل البنود" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" -msgstr "" +msgstr "ال طلب هو مقفل و لا يمكن يكون modified" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" +msgstr "كمية عنصر" + +#: order/models.py:2119 +msgid "Discount" msgstr "" -#: order/models.py:1829 +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" -msgstr "" +msgstr "سطر رقم" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" -msgstr "" +msgstr "سطر رقم لـ هذا عنصر (اختياري)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" -msgstr "" +msgstr "بند مرجع" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" -msgstr "" +msgstr "بند ملاحظات" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" -msgstr "" - -#: order/models.py:1891 -msgid "Line item description (optional)" -msgstr "" - -#: order/models.py:1898 -msgid "Additional context for this line" -msgstr "" - -#: order/models.py:1908 -msgid "Unit price" -msgstr "" - -#: order/models.py:1927 -msgid "Purchase Order Line Item" -msgstr "" - -#: order/models.py:1956 -msgid "Supplier part must match supplier" -msgstr "" - -#: order/models.py:1964 -msgid "Build order must be marked as external" -msgstr "" - -#: order/models.py:1971 -msgid "Build orders can only be linked to assembly parts" -msgstr "" - -#: order/models.py:1977 -msgid "Build order part must match line item part" -msgstr "" - -#: order/models.py:1987 -msgid "An external build order is required for assembly parts" -msgstr "" - -#: order/models.py:2023 -msgid "Supplier part" -msgstr "" - -#: order/models.py:2030 -msgid "Received" -msgstr "" - -#: order/models.py:2031 -msgid "Number of items received" -msgstr "" - -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 -msgid "Purchase Price" -msgstr "" - -#: order/models.py:2040 -msgid "Unit purchase price" -msgstr "" - -#: order/models.py:2056 -msgid "External Build Order to be fulfilled by this line item" -msgstr "" - -#: order/models.py:2118 -msgid "Purchase Order Extra Line" -msgstr "" - -#: order/models.py:2147 -msgid "Sales Order Line Item" -msgstr "" - -#: order/models.py:2174 -msgid "Only salable parts can be assigned to a sales order" -msgstr "" +msgstr "التاريخ المستهدف لـ هذا بند (ترك فارغ إلى استخدام ال التاريخ المستهدف من ال طلب)" #: order/models.py:2200 +msgid "Line item description (optional)" +msgstr "بند وصف (اختياري)" + +#: order/models.py:2207 +msgid "Additional context for this line" +msgstr "Additional سياق لـ هذا سطر" + +#: order/models.py:2217 +msgid "Unit price" +msgstr "سعر الوحدة" + +#: order/models.py:2236 +msgid "Purchase Order Line Item" +msgstr "طلب الشراء بند" + +#: order/models.py:2265 +msgid "Supplier part must match supplier" +msgstr "صنف المورد يجب مطابقة مورد" + +#: order/models.py:2273 +msgid "Build order must be marked as external" +msgstr "يجب أن يكون أمر الإنتاج معلّم بصفته خارجي" + +#: order/models.py:2280 +msgid "Build orders can only be linked to assembly parts" +msgstr "أوامر الإنتاج يمكن فقط يكون مرتبط إلى تجميع أصناف" + +#: order/models.py:2286 +msgid "Build order part must match line item part" +msgstr "أمر الإنتاج صنف يجب مطابقة بند صنف" + +#: order/models.py:2296 +msgid "An external build order is required for assembly parts" +msgstr "خارجي أمر الإنتاج هو مطلوب لـ تجميع أصناف" + +#: order/models.py:2332 +msgid "Supplier part" +msgstr "صنف المورد" + +#: order/models.py:2339 +msgid "Received" +msgstr "مستلم" + +#: order/models.py:2340 +msgid "Number of items received" +msgstr "عدد عناصر مستلم" + +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 +msgid "Purchase Price" +msgstr "سعر الشراء" + +#: order/models.py:2349 +msgid "Unit purchase price" +msgstr "وحدة سعر الشراء" + +#: order/models.py:2365 +msgid "External Build Order to be fulfilled by this line item" +msgstr "خارجي أمر الإنتاج إلى يكون fulfilled حسب هذا بند" + +#: order/models.py:2427 +msgid "Purchase Order Extra Line" +msgstr "طلب الشراء إضافي سطر" + +#: order/models.py:2456 +msgid "Sales Order Line Item" +msgstr "طلب البيع بند" + +#: order/models.py:2483 +msgid "Only salable parts can be assigned to a sales order" +msgstr "فقط قابل للبيع أصناف يمكن يكون مسند إلى طلب البيع" + +#: order/models.py:2509 msgid "Sale Price" -msgstr "" +msgstr "سعر البيع" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" -msgstr "" +msgstr "وحدة سعر البيع" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" -msgstr "" +msgstr "مشحون" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" -msgstr "" +msgstr "كمية مشحون" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" -msgstr "" +msgstr "طلب البيع شحنة" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" -msgstr "" +msgstr "شحنة عنوان يجب مطابقة ال عميل" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" -msgstr "" +msgstr "شحن عنوان لـ هذا شحنة" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" -msgstr "" +msgstr "تاريخ لـ شحنة" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" -msgstr "" +msgstr "تاريخ تسليم" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" -msgstr "" +msgstr "تاريخ لـ تسليم لـ شحنة" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" -msgstr "" +msgstr "محدد حسب" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" -msgstr "" +msgstr "مستخدم من محدد هذا شحنة" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" -msgstr "" +msgstr "شحنة" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" -msgstr "" +msgstr "شحنة رقم" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" -msgstr "" +msgstr "تتبع رقم" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" -msgstr "" +msgstr "شحنة تتبع معلومات" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" -msgstr "" +msgstr "Invoice رقم" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" -msgstr "" +msgstr "مرجع رقم لـ مرتبط invoice" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" -msgstr "" +msgstr "شحنة لديه بالفعل تم تم الإرسال" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" -msgstr "" +msgstr "شحنة لديه لا مخصص عناصر المخزون" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" -msgstr "" +msgstr "يجب أن يكون شحنة محدد قبل هو يمكن يكون مكتمل" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" -msgstr "" +msgstr "طلب البيع إضافي سطر" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" -msgstr "" +msgstr "طلب البيع تخصيص" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" -msgstr "" +msgstr "عنصر المخزون لديه غير تم مسند" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" -msgstr "" +msgstr "لا يمكن تخصيص عنصر المخزون إلى سطر مع مختلف صنف" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" -msgstr "" +msgstr "لا يمكن تخصيص مخزون إلى سطر بدون صنف" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" -msgstr "" +msgstr "كمية تخصيص كمية لا يمكن تجاوز مخزون" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" -msgstr "" +msgstr "يجب أن يكون كمية تخصيص أكبر من صفر" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" -msgstr "" +msgstr "يجب أن يكون الكمية 1 لـ مسلسل عنصر المخزون" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" -msgstr "" +msgstr "طلب البيع يقوم غير مطابقة شحنة" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" -msgstr "" +msgstr "شحنة يقوم غير مطابقة طلب البيع" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" -msgstr "" +msgstr "سطر" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" -msgstr "" +msgstr "طلب البيع شحنة مرجع" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" -msgstr "" +msgstr "عنصر" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" -msgstr "" +msgstr "تحديد عنصر المخزون إلى تخصيص" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" -msgstr "" +msgstr "كمية إدخال مخزون تخصيص" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" -msgstr "" +msgstr "طلب الإرجاع مرجع" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" -msgstr "" +msgstr "شركة من الذي عناصر هي being مرتجع" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" -msgstr "" +msgstr "حالة طلب الإرجاع" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" -msgstr "" +msgstr "طلب الإرجاع بند" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" -msgstr "" +msgstr "يجب أن يكون عنصر المخزون محدد" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" -msgstr "" +msgstr "كمية إرجاع كمية يتجاوز مخزون" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" -msgstr "" +msgstr "يجب أن يكون كمية إرجاع أكبر من صفر" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" -msgstr "" +msgstr "غير صالح كمية لـ مسلسل عنصر المخزون" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" -msgstr "" +msgstr "تحديد عنصر إلى إرجاع من عميل" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" -msgstr "" +msgstr "تاريخ مستلم" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" -msgstr "" +msgstr "ال تاريخ هذا إرجاع عنصر كان مستلم" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" -msgstr "" +msgstr "Outcome لـ هذا بند" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" -msgstr "" +msgstr "تكلفة مرتبط مع إرجاع أو repair لـ هذا بند" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" +msgstr "طلب الإرجاع إضافي سطر" + +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "طلب التحويل مرجع" + +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "حالة طلب التحويل" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "المصدر لـ منقول عناصر" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "الوجهة لـ منقول عناصر" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "استهلاك مخزون" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "Rather من تحويل ال مخزون إلى ال الوجهة، \"consume\" هو، حسب removing منقول كمية من ال مخصص عنصر المخزون" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "طلب لا يمكن يكون مكتمل حتى الوجهة موقع هو تعيين" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "طلب لا يمكن يكون مكتمل حتى هو هو بالكامل مخصص" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "طلب التحويل بند" + +#: order/models.py:4027 +msgid "transferred" +msgstr "منقول" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "كمية منقول" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "طلب التحويل تخصيص" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" -msgstr "" - -#: order/serializers.py:112 +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" -msgstr "" +msgstr "بنود" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" -msgstr "" +msgstr "مكتمل سطور" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "مخصص حالة مفتاح" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "تحديث طلب حالة إلى مخصص قيمة لـ هذا منطقي قيمة" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "يجب أن يكون مخصص حالة مفتاح عدد صحيح" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "غير صالح مخصص حالة مفتاح" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "حالة غير صالح مخصص حالة مفتاح لـ هذا طلب" + +#: order/serializers.py:462 msgid "Supplier Name" -msgstr "" +msgstr "مورد اسم" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" -msgstr "" +msgstr "طلب لا يمكن يكون ملغى" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" -msgstr "" +msgstr "السماح طلب إلى يكون closed مع غير مكتمل البنود" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" -msgstr "" +msgstr "طلب لديه غير مكتمل البنود" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" -msgstr "" +msgstr "طلب هو غير فتح" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" -msgstr "" +msgstr "تلقائي التسعير" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" -msgstr "" +msgstr "تلقائيًا calculate سعر الشراء استنادًا إلى على صنف المورد بيانات" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" -msgstr "" +msgstr "سعر الشراء عملة" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" -msgstr "" +msgstr "دمج عناصر" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" -msgstr "" +msgstr "دمج عناصر مع ال نفس صنف، الوجهة و التاريخ المستهدف إلى واحد بند" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" -msgstr "" +msgstr "داخلي صنف رقم" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" -msgstr "" +msgstr "داخلي صنف اسم" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" -msgstr "" +msgstr "يجب أن يكون صنف المورد محدد" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" -msgstr "" +msgstr "يجب أن يكون طلب الشراء محدد" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" -msgstr "" +msgstr "مورد يجب مطابقة طلب الشراء" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" -msgstr "" +msgstr "طلب الشراء يجب مطابقة مورد" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" -msgstr "" +msgstr "بند" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" -msgstr "" +msgstr "تحديد الوجهة موقع لـ مستلم عناصر" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" -msgstr "" +msgstr "إدخال رمز الدفعة لـ وارد عناصر المخزون" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" -msgstr "" +msgstr "تاريخ الانتهاء" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" -msgstr "" +msgstr "إدخال انتهاء تاريخ لـ وارد عناصر المخزون" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" -msgstr "" +msgstr "إدخال الأرقام التسلسلية لـ وارد عناصر المخزون" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" -msgstr "" +msgstr "تجاوز تعبئة معلومات لـ وارد عناصر المخزون" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" -msgstr "" +msgstr "Additional ملاحظة لـ وارد عناصر المخزون" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" -msgstr "" +msgstr "الباركود" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" -msgstr "" +msgstr "تم المسح باركود" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" -msgstr "" +msgstr "باركود هو بالفعل في استخدام" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" -msgstr "" +msgstr "يجب أن يكون البنود مقدم" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" -msgstr "" +msgstr "يجب أن يكون الوجهة موقع محدد" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" +msgstr "يجب أن يكون مورد باركود قيم فريد" + +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1217 msgid "Shipments" -msgstr "" +msgstr "شحنات" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" -msgstr "" +msgstr "مكتمل شحنات" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" -msgstr "" +msgstr "مخصص سطور" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" -msgstr "" +msgstr "سعر البيع عملة" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" -msgstr "" +msgstr "مخصص عناصر" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" -msgstr "" +msgstr "لا شحنة تفاصيل مقدم" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" -msgstr "" +msgstr "يجب أن يكون الكمية موجب" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" -msgstr "" +msgstr "عنصر المخزون لديه غير نجح الكل مطلوب اختبارات" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" -msgstr "" +msgstr "إدخال الأرقام التسلسلية إلى تخصيص" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" -msgstr "" +msgstr "شحنة لديه بالفعل تم مشحون" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" -msgstr "" +msgstr "شحنة هو غير مرتبط مع هذا طلب" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "موقع المخزون حيث عناصر هي sourced (ترك فارغ إلى استخدام أي موقع)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "استبعاد عناصر المخزون من هذا موقع" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "إسناد تخصيصات إلى هذا شحنة" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "السماح مخزون إلى يكون taken من متعدد مواقع إلى fulfil مفرد بند" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "مسلسل مخزون" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "Control whether مسلسل عناصر المخزون هي included في auto-allocation" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "حد تخصيص إلى هذه البنود (ترك فارغ إلى تخصيص الكل سطور)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "بند يقوم غير belong إلى هذا طلب" + +#: order/serializers.py:2261 msgid "Return order line item" -msgstr "" +msgstr "طلب الإرجاع بند" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" -msgstr "" +msgstr "بند يقوم غير مطابقة طلب الإرجاع" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" -msgstr "" +msgstr "بند لديه بالفعل تم مستلم" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" -msgstr "" +msgstr "عناصر يمكن فقط يكون مستلم مقابل طلبات الذي هي في progress" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" -msgstr "" +msgstr "كمية إلى إرجاع" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" -msgstr "" +msgstr "سطر سعر عملة" + +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "السماح طلب إلى مكتمل مع غير مكتمل تخصيصات" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "طلب لديه غير مكتمل تخصيصات" #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" @@ -5716,1284 +6123,1317 @@ msgstr "" #: order/status_codes.py:18 order/status_codes.py:55 stock/status_codes.py:24 msgid "Returned" -msgstr "" +msgstr "مرتجع" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" -msgstr "" +msgstr "في Progress" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" -msgstr "" +msgstr "إرجاع" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" -msgstr "" +msgstr "رفض" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "مصروف" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" -msgstr "" +msgstr "متأخر طلب الشراء" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" -msgstr "" +msgstr "طلب الشراء {po} هو الآن متأخر" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" -msgstr "" +msgstr "متأخر طلب البيع" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" -msgstr "" +msgstr "طلب البيع {so} هو الآن متأخر" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" -msgstr "" +msgstr "متأخر طلب الإرجاع" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" -msgstr "" - -#: part/api.py:88 -msgid "Starred" -msgstr "" +msgstr "طلب الإرجاع {ro} هو الآن متأخر" #: part/api.py:90 -msgid "Filter by starred categories" -msgstr "" +msgid "Starred" +msgstr "مفضلة" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:92 +msgid "Filter by starred categories" +msgstr "تصفية حسب مفضلة فئات" + +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" -msgstr "" +msgstr "تصفية حسب فئة depth" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" -msgstr "" +msgstr "أعلى مستوى" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" -msgstr "" +msgstr "تصفية حسب top-level فئات" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" -msgstr "" - -#: part/api.py:162 -msgid "Parent" -msgstr "" +msgstr "تضمين sub-categories في filtered نتائج" #: part/api.py:164 +msgid "Parent" +msgstr "الأصل" + +#: part/api.py:166 msgid "Filter by parent category" -msgstr "" +msgstr "تصفية حسب الأصل فئة" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" -msgstr "" +msgstr "استبعاد sub-categories under ال محدد فئة" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "Max مستوى" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "حد ال depth لـ ال فئة tree" + +#: part/api.py:442 msgid "Has Results" -msgstr "" - -#: part/api.py:654 -msgid "Is Variant" -msgstr "" - -#: part/api.py:662 -msgid "Is Revision" -msgstr "" +msgstr "لديه نتائج" #: part/api.py:672 +msgid "Is Variant" +msgstr "هو متغير" + +#: part/api.py:680 +msgid "Is Revision" +msgstr "هو مراجعة" + +#: part/api.py:690 msgid "Has Revisions" -msgstr "" +msgstr "لديه مراجعات" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" -msgstr "" +msgstr "BOM صالح" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" -msgstr "" +msgstr "Cascade فئات" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" -msgstr "" +msgstr "إذا صحيح، تضمين عناصر في فرعي فئات لـ ال معطى فئة" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" -msgstr "" +msgstr "تصفية حسب numeric فئة ID أو ال literal 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" -msgstr "" +msgstr "تجميع صنف هو نشط" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" -msgstr "" +msgstr "تجميع صنف هو قابل للتتبع" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" -msgstr "" +msgstr "تجميع صنف هو قابل للاختبار" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" -msgstr "" +msgstr "تجميع صنف هو مقفل" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" -msgstr "" +msgstr "مكوّن صنف هو نشط" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" -msgstr "" +msgstr "مكوّن صنف هو قابل للتتبع" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" -msgstr "" +msgstr "مكوّن صنف هو قابل للاختبار" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" -msgstr "" +msgstr "مكوّن صنف هو تجميع" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" -msgstr "" +msgstr "مكوّن صنف هو افتراضي" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" -msgstr "" +msgstr "لديه متاح مخزون" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" -msgstr "" +msgstr "فئة الأصناف" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" -msgstr "" +msgstr "فئات الأصناف" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" -msgstr "" +msgstr "افتراضي موقع" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" -msgstr "" +msgstr "افتراضي موقع لـ أصناف في هذا فئة" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" -msgstr "" +msgstr "هيكلي" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." -msgstr "" +msgstr "أصناف قد غير يكون directly مسند إلى هيكلي فئة، but قد يكون مسند إلى فرعي فئات." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" -msgstr "" +msgstr "افتراضي keywords" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" -msgstr "" +msgstr "افتراضي keywords لـ أصناف في هذا فئة" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" -msgstr "" +msgstr "أيقونة" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" -msgstr "" +msgstr "أيقونة (اختياري)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" -msgstr "" +msgstr "أنت لا يمكن make هذا فئة الأصناف هيكلي because some أصناف هي بالفعل مسند إلى هو!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" -msgstr "" +msgstr "فئة الأصناف معلمة قالب" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" -msgstr "" +msgstr "افتراضي قيمة" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" -msgstr "" +msgstr "افتراضي معلمة قيمة" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" -msgstr "" +msgstr "الأصناف" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" -msgstr "" +msgstr "لا يمكن حذف معلمات لـ مقفل صنف" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" -msgstr "" +msgstr "لا يمكن modify معلمات لـ مقفل صنف" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" -msgstr "" +msgstr "لا يمكن حذف هذا صنف بصفته هو هو مقفل" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" -msgstr "" +msgstr "لا يمكن حذف هذا صنف بصفته هو هو ما زال نشط" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" -msgstr "" +msgstr "لا يمكن حذف هذا صنف بصفته هو هو مستخدم في تجميع" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" -msgstr "" +msgstr "صنف '{self}' لا يمكن يكون مستخدم في BOM لـ '{parent}' (recursive)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" -msgstr "" +msgstr "صنف '{parent}' هو مستخدم في BOM لـ '{self}' (recursive)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" -msgstr "" +msgstr "IPN يجب مطابقة تعبير نمطي نمط {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" -msgstr "" +msgstr "صنف لا يمكن يكون مراجعة لـ itself" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" -msgstr "" +msgstr "يجب أن يكون مراجعة رمز محدد لـ صنف معلّم بصفته مراجعة" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" -msgstr "" - -#: part/models.py:799 -msgid "Cannot make a revision of a template part" -msgstr "" +msgstr "مراجعات هي فقط مسموح لـ تجميع أصناف" #: part/models.py:805 +msgid "Cannot make a revision of a template part" +msgstr "لا يمكن make مراجعة لـ قالب صنف" + +#: part/models.py:811 msgid "Parent part must point to the same template" -msgstr "" +msgstr "الأصل صنف يجب نقطة إلى ال نفس قالب" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" -msgstr "" +msgstr "عنصر المخزون مع هذا الرقم التسلسلي بالفعل موجود" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" -msgstr "" +msgstr "إعدادات نسخ IPN غير مسموح في صنف" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." -msgstr "" +msgstr "نسخ صنف مراجعة بالفعل موجود." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." -msgstr "" +msgstr "صنف مع هذا اسم، IPN و مراجعة بالفعل موجود." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" -msgstr "" - -#: part/models.py:1102 -msgid "Part name" -msgstr "" - -#: part/models.py:1107 -msgid "Is Template" -msgstr "" - -#: part/models.py:1108 -msgid "Is this part a template part?" -msgstr "" - -#: part/models.py:1118 -msgid "Is this part a variant of another part?" -msgstr "" +msgstr "أصناف لا يمكن يكون مسند إلى هيكلي فئات الأصناف!" #: part/models.py:1119 +msgid "Part name" +msgstr "صنف اسم" + +#: part/models.py:1124 +msgid "Is Template" +msgstr "هو قالب" + +#: part/models.py:1125 +msgid "Is this part a template part?" +msgstr "هو هذا صنف قالب صنف؟" + +#: part/models.py:1135 +msgid "Is this part a variant of another part?" +msgstr "هو هذا صنف متغير لـ آخر صنف؟" + +#: part/models.py:1136 msgid "Variant Of" -msgstr "" +msgstr "متغير لـ" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" -msgstr "" +msgstr "صنف وصف (اختياري)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" -msgstr "" +msgstr "صنف keywords إلى improve visibility في بحث نتائج" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" -msgstr "" +msgstr "فئة الأصناف" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" -msgstr "" +msgstr "صنف مراجعة أو إصدار رقم" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" -msgstr "" - -#: part/models.py:1169 -msgid "Is this part a revision of another part?" -msgstr "" - -#: part/models.py:1170 -msgid "Revision Of" -msgstr "" +msgstr "مراجعة" #: part/models.py:1186 +msgid "Is this part a revision of another part?" +msgstr "هو هذا صنف مراجعة لـ آخر صنف؟" + +#: part/models.py:1187 +msgid "Revision Of" +msgstr "مراجعة لـ" + +#: part/models.py:1203 msgid "Where is this item normally stored?" -msgstr "" +msgstr "حيث هو هذا عنصر normally مخزن؟" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" -msgstr "" - -#: part/models.py:1224 -msgid "Expiry time (in days) for stock items of this part" -msgstr "" - -#: part/models.py:1232 part/serializers.py:898 -msgid "Minimum Stock" -msgstr "" - -#: part/models.py:1233 -msgid "Minimum allowed stock level" -msgstr "" - -#: part/models.py:1241 part/serializers.py:902 -msgid "Maximum Stock" -msgstr "" +msgstr "افتراضي انتهاء" #: part/models.py:1242 -msgid "Maximum allowed stock level" -msgstr "" +msgid "Expiry time (in days) for stock items of this part" +msgstr "انتهاء وقت (في أيام) لـ عناصر المخزون لـ هذا صنف" + +#: part/models.py:1250 part/serializers.py:884 +msgid "Minimum Stock" +msgstr "الحد الأدنى للمخزون" #: part/models.py:1251 +msgid "Minimum allowed stock level" +msgstr "أدنى مسموح مخزون مستوى" + +#: part/models.py:1259 part/serializers.py:888 +msgid "Maximum Stock" +msgstr "الحد الأقصى للمخزون" + +#: part/models.py:1260 +msgid "Maximum allowed stock level" +msgstr "أقصى مسموح مخزون مستوى" + +#: part/models.py:1269 msgid "Units of measure for this part" -msgstr "" - -#: part/models.py:1258 -msgid "Can this part be built from other parts?" -msgstr "" - -#: part/models.py:1264 -msgid "Can this part be used to build other parts?" -msgstr "" - -#: part/models.py:1270 -msgid "Does this part have tracking for unique items?" -msgstr "" +msgstr "وحدات لـ measure لـ هذا صنف" #: part/models.py:1276 -msgid "Can this part have test results recorded against it?" -msgstr "" +msgid "Can this part be built from other parts?" +msgstr "يمكن هذا صنف يكون built من أخرى أصناف؟" #: part/models.py:1282 -msgid "Can this part be purchased from external suppliers?" -msgstr "" +msgid "Can this part be used to build other parts?" +msgstr "يمكن هذا صنف يكون مستخدم إلى إنتاج أخرى أصناف؟" #: part/models.py:1288 +msgid "Does this part have tracking for unique items?" +msgstr "يقوم هذا صنف لديه تتبع لـ فريد عناصر؟" + +#: part/models.py:1294 +msgid "Can this part have test results recorded against it?" +msgstr "يمكن هذا صنف لديه اختبار نتائج recorded مقابل هو؟" + +#: part/models.py:1300 +msgid "Can this part be purchased from external suppliers?" +msgstr "يمكن هذا صنف يكون purchased من خارجي موردون؟" + +#: part/models.py:1306 msgid "Can this part be sold to customers?" -msgstr "" - -#: part/models.py:1292 -msgid "Is this part active?" -msgstr "" - -#: part/models.py:1298 -msgid "Locked parts cannot be edited" -msgstr "" - -#: part/models.py:1304 -msgid "Is this a virtual part, such as a software product or license?" -msgstr "" - -#: part/models.py:1309 -msgid "BOM Validated" -msgstr "" +msgstr "يمكن هذا صنف يكون sold إلى عملاء؟" #: part/models.py:1310 -msgid "Is the BOM for this part valid?" -msgstr "" +msgid "Is this part active?" +msgstr "هو هذا صنف نشط؟" #: part/models.py:1316 +msgid "Locked parts cannot be edited" +msgstr "مقفل أصناف لا يمكن يكون تم التحرير" + +#: part/models.py:1322 +msgid "Is this a virtual part, such as a software product or license?" +msgstr "هو هذا افتراضي صنف، such بصفته software product أو license؟" + +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 +msgid "BOM Validated" +msgstr "BOM تم التحقق" + +#: part/models.py:1334 +msgid "Is the BOM for this part valid?" +msgstr "هو ال BOM لـ هذا صنف صالح؟" + +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" -msgstr "" +msgstr "مخزن BOM checksum" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" -msgstr "" +msgstr "BOM محدد حسب" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" -msgstr "" +msgstr "تاريخ BOM محدد" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" -msgstr "" +msgstr "إنشاء مستخدم" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" -msgstr "" +msgstr "مالك مسؤول لـ هذا صنف" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" -msgstr "" +msgstr "Sell متعدد" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" -msgstr "" +msgstr "عملة مستخدم إلى ذاكرة مؤقتة التسعير حسابات" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" -msgstr "" +msgstr "أدنى BOM تكلفة" + +#: part/models.py:3233 +msgid "Minimum cost of component parts" +msgstr "أدنى تكلفة لـ مكوّن أصناف" + +#: part/models.py:3239 +msgid "Maximum BOM Cost" +msgstr "أقصى BOM تكلفة" + +#: part/models.py:3240 +msgid "Maximum cost of component parts" +msgstr "أقصى تكلفة لـ مكوّن أصناف" + +#: part/models.py:3246 +msgid "Minimum Purchase Cost" +msgstr "أدنى شراء تكلفة" + +#: part/models.py:3247 +msgid "Minimum historical purchase cost" +msgstr "أدنى تاريخي شراء تكلفة" + +#: part/models.py:3253 +msgid "Maximum Purchase Cost" +msgstr "أقصى شراء تكلفة" + +#: part/models.py:3254 +msgid "Maximum historical purchase cost" +msgstr "أقصى تاريخي شراء تكلفة" + +#: part/models.py:3260 +msgid "Minimum Internal Price" +msgstr "أدنى داخلي سعر" + +#: part/models.py:3261 +msgid "Minimum cost based on internal price breaks" +msgstr "أدنى تكلفة استنادًا إلى على داخلي سعر فواصل" + +#: part/models.py:3267 +msgid "Maximum Internal Price" +msgstr "أقصى داخلي سعر" + +#: part/models.py:3268 +msgid "Maximum cost based on internal price breaks" +msgstr "أقصى تكلفة استنادًا إلى على داخلي سعر فواصل" + +#: part/models.py:3274 +msgid "Minimum Supplier Price" +msgstr "أدنى مورد سعر" + +#: part/models.py:3275 +msgid "Minimum price of part from external suppliers" +msgstr "أدنى سعر لـ صنف من خارجي موردون" + +#: part/models.py:3281 +msgid "Maximum Supplier Price" +msgstr "أقصى مورد سعر" + +#: part/models.py:3282 +msgid "Maximum price of part from external suppliers" +msgstr "أقصى سعر لـ صنف من خارجي موردون" + +#: part/models.py:3288 +msgid "Minimum Variant Cost" +msgstr "أدنى متغير تكلفة" + +#: part/models.py:3289 +msgid "Calculated minimum cost of variant parts" +msgstr "محسوب أدنى تكلفة لـ متغير أصناف" + +#: part/models.py:3295 +msgid "Maximum Variant Cost" +msgstr "أقصى متغير تكلفة" + +#: part/models.py:3296 +msgid "Calculated maximum cost of variant parts" +msgstr "محسوب أقصى تكلفة لـ متغير أصناف" + +#: part/models.py:3302 part/models.py:3316 +msgid "Minimum Cost" +msgstr "أدنى تكلفة" + +#: part/models.py:3303 +msgid "Override minimum cost" +msgstr "تجاوز أدنى تكلفة" + +#: part/models.py:3309 part/models.py:3323 +msgid "Maximum Cost" +msgstr "أقصى تكلفة" + +#: part/models.py:3310 +msgid "Override maximum cost" +msgstr "تجاوز أقصى تكلفة" + +#: part/models.py:3317 +msgid "Calculated overall minimum cost" +msgstr "محسوب إجمالي أدنى تكلفة" + +#: part/models.py:3324 +msgid "Calculated overall maximum cost" +msgstr "محسوب إجمالي أقصى تكلفة" + +#: part/models.py:3330 +msgid "Minimum Sale Price" +msgstr "أدنى سعر البيع" + +#: part/models.py:3331 +msgid "Minimum sale price based on price breaks" +msgstr "أدنى سعر البيع استنادًا إلى على سعر فواصل" + +#: part/models.py:3337 +msgid "Maximum Sale Price" +msgstr "أقصى سعر البيع" + +#: part/models.py:3338 +msgid "Maximum sale price based on price breaks" +msgstr "أقصى سعر البيع استنادًا إلى على سعر فواصل" #: part/models.py:3344 -msgid "Minimum cost of component parts" -msgstr "" +msgid "Minimum Sale Cost" +msgstr "أدنى بيع تكلفة" -#: part/models.py:3350 -msgid "Maximum BOM Cost" -msgstr "" +#: part/models.py:3345 +msgid "Minimum historical sale price" +msgstr "أدنى تاريخي سعر البيع" #: part/models.py:3351 -msgid "Maximum cost of component parts" -msgstr "" +msgid "Maximum Sale Cost" +msgstr "أقصى بيع تكلفة" -#: part/models.py:3357 -msgid "Minimum Purchase Cost" -msgstr "" +#: part/models.py:3352 +msgid "Maximum historical sale price" +msgstr "أقصى تاريخي سعر البيع" -#: part/models.py:3358 -msgid "Minimum historical purchase cost" -msgstr "" +#: part/models.py:3370 +msgid "Part for stocktake" +msgstr "صنف لـ جرد المخزون" -#: part/models.py:3364 -msgid "Maximum Purchase Cost" -msgstr "" +#: part/models.py:3375 +msgid "Item Count" +msgstr "عنصر عد" -#: part/models.py:3365 -msgid "Maximum historical purchase cost" -msgstr "" +#: part/models.py:3376 +msgid "Number of individual stock entries at time of stocktake" +msgstr "عدد individual مخزون سجلات عند وقت لـ جرد المخزون" -#: part/models.py:3371 -msgid "Minimum Internal Price" -msgstr "" +#: part/models.py:3384 +msgid "Total available stock at time of stocktake" +msgstr "إجمالي متاح مخزون عند وقت لـ جرد المخزون" -#: part/models.py:3372 -msgid "Minimum cost based on internal price breaks" -msgstr "" +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 +msgid "Date" +msgstr "التاريخ" -#: part/models.py:3378 -msgid "Maximum Internal Price" -msgstr "" +#: part/models.py:3389 +msgid "Date stocktake was performed" +msgstr "تاريخ جرد المخزون كان performed" -#: part/models.py:3379 -msgid "Maximum cost based on internal price breaks" -msgstr "" +#: part/models.py:3396 +msgid "Minimum Stock Cost" +msgstr "أدنى مخزون تكلفة" -#: part/models.py:3385 -msgid "Minimum Supplier Price" -msgstr "" +#: part/models.py:3397 +msgid "Estimated minimum cost of stock on hand" +msgstr "Estimated أدنى تكلفة لـ مخزون على hand" -#: part/models.py:3386 -msgid "Minimum price of part from external suppliers" -msgstr "" +#: part/models.py:3403 +msgid "Maximum Stock Cost" +msgstr "أقصى مخزون تكلفة" -#: part/models.py:3392 -msgid "Maximum Supplier Price" -msgstr "" - -#: part/models.py:3393 -msgid "Maximum price of part from external suppliers" -msgstr "" - -#: part/models.py:3399 -msgid "Minimum Variant Cost" -msgstr "" - -#: part/models.py:3400 -msgid "Calculated minimum cost of variant parts" -msgstr "" - -#: part/models.py:3406 -msgid "Maximum Variant Cost" -msgstr "" - -#: part/models.py:3407 -msgid "Calculated maximum cost of variant parts" -msgstr "" - -#: part/models.py:3413 part/models.py:3427 -msgid "Minimum Cost" -msgstr "" +#: part/models.py:3404 +msgid "Estimated maximum cost of stock on hand" +msgstr "Estimated أقصى تكلفة لـ مخزون على hand" #: part/models.py:3414 -msgid "Override minimum cost" -msgstr "" - -#: part/models.py:3420 part/models.py:3434 -msgid "Maximum Cost" -msgstr "" - -#: part/models.py:3421 -msgid "Override maximum cost" -msgstr "" - -#: part/models.py:3428 -msgid "Calculated overall minimum cost" -msgstr "" - -#: part/models.py:3435 -msgid "Calculated overall maximum cost" -msgstr "" - -#: part/models.py:3441 -msgid "Minimum Sale Price" -msgstr "" - -#: part/models.py:3442 -msgid "Minimum sale price based on price breaks" -msgstr "" - -#: part/models.py:3448 -msgid "Maximum Sale Price" -msgstr "" - -#: part/models.py:3449 -msgid "Maximum sale price based on price breaks" -msgstr "" - -#: part/models.py:3455 -msgid "Minimum Sale Cost" -msgstr "" - -#: part/models.py:3456 -msgid "Minimum historical sale price" -msgstr "" - -#: part/models.py:3462 -msgid "Maximum Sale Cost" -msgstr "" - -#: part/models.py:3463 -msgid "Maximum historical sale price" -msgstr "" - -#: part/models.py:3481 -msgid "Part for stocktake" -msgstr "" - -#: part/models.py:3486 -msgid "Item Count" -msgstr "" - -#: part/models.py:3487 -msgid "Number of individual stock entries at time of stocktake" -msgstr "" - -#: part/models.py:3495 -msgid "Total available stock at time of stocktake" -msgstr "" - -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 -msgid "Date" -msgstr "" - -#: part/models.py:3500 -msgid "Date stocktake was performed" -msgstr "" - -#: part/models.py:3507 -msgid "Minimum Stock Cost" -msgstr "" - -#: part/models.py:3508 -msgid "Estimated minimum cost of stock on hand" -msgstr "" - -#: part/models.py:3514 -msgid "Maximum Stock Cost" -msgstr "" - -#: part/models.py:3515 -msgid "Estimated maximum cost of stock on hand" -msgstr "" - -#: part/models.py:3525 msgid "Part Sale Price Break" +msgstr "صنف سعر البيع فاصل" + +#: part/models.py:3438 +msgid "Part Internal Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3529 msgid "Part Test Template" -msgstr "" +msgstr "صنف اختبار قالب" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" -msgstr "" +msgstr "غير صالح قالب اسم - يجب تضمين عند أقل واحد alphanumeric character" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" -msgstr "" +msgstr "اختبار قوالب يمكن فقط يكون تم الإنشاء لـ قابل للاختبار أصناف" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" -msgstr "" +msgstr "اختبار قالب مع ال نفس مفتاح بالفعل موجود لـ صنف" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" -msgstr "" +msgstr "اختبار اسم" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" -msgstr "" +msgstr "إدخال اسم لـ ال اختبار" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" -msgstr "" +msgstr "اختبار مفتاح" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" -msgstr "" +msgstr "Simplified مفتاح لـ ال اختبار" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" -msgstr "" +msgstr "اختبار وصف" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" -msgstr "" +msgstr "إدخال وصف لـ هذا اختبار" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" -msgstr "" +msgstr "هو هذا اختبار مفعّل؟" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" -msgstr "" +msgstr "مطلوب" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" -msgstr "" +msgstr "هو هذا اختبار مطلوب إلى نجاح؟" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" -msgstr "" +msgstr "يتطلب قيمة" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" -msgstr "" +msgstr "يقوم هذا اختبار طلب قيمة عند إضافة نتيجة الاختبار؟" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" -msgstr "" +msgstr "يتطلب مرفق" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" -msgstr "" +msgstr "يقوم هذا اختبار طلب ملف مرفق عند إضافة نتيجة الاختبار؟" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" -msgstr "" +msgstr "صالح خيارات لـ هذا اختبار (comma-separated)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" -msgstr "" +msgstr "غير صالح كمية - لا وحدات محدد لـ صنف" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" -msgstr "" +msgstr "يجب أن يكون الكمية أكبر من أو equal إلى صفر" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" -msgstr "" +msgstr "BOM عنصر لا يمكن يكون modified - تجميع هو مقفل" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" -msgstr "" +msgstr "BOM عنصر لا يمكن يكون modified - متغير تجميع هو مقفل" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" -msgstr "" +msgstr "تحديد الأصل صنف" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" -msgstr "" +msgstr "Sub صنف" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" -msgstr "" +msgstr "تحديد صنف إلى يكون مستخدم في BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" -msgstr "" +msgstr "Amount لـ sub-part مستهلك إلى produce واحد صنف" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" -msgstr "" +msgstr "BOM كمية لـ هذا BOM عنصر" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" -msgstr "" +msgstr "هذا BOM عنصر هو اختياري" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" -msgstr "" +msgstr "هذا BOM عنصر هو قابل للاستهلاك (هو هو غير متتبع في أوامر الإنتاج)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" -msgstr "" +msgstr "كمية إعداد" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" -msgstr "" +msgstr "إضافي مطلوب كمية لـ إنتاج، إلى حساب لـ إعداد losses" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" -msgstr "" +msgstr "Estimated attrition لـ إنتاج، expressed بصفته percentage (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" -msgstr "" +msgstr "Rounding متعدد" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" +msgstr "Round أعلى مطلوب الإنتاج كمية إلى nearest متعدد لـ هذا قيمة" + +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" msgstr "" -#: part/models.py:4122 +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" -msgstr "" +msgstr "BOM عنصر مرجع" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" -msgstr "" +msgstr "BOM عنصر ملاحظات" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" -msgstr "" +msgstr "BOM سطر checksum" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" -msgstr "" +msgstr "تم التحقق" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" -msgstr "" +msgstr "هذا BOM عنصر لديه تم تم التحقق" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" -msgstr "" +msgstr "Gets موروث" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" -msgstr "" +msgstr "هذا BOM عنصر هو موروث حسب BOMs لـ متغير أصناف" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" -msgstr "" +msgstr "عناصر المخزون لـ متغير أصناف يمكن يكون مستخدم لـ هذا BOM عنصر" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" -msgstr "" +msgstr "يجب أن يكون الكمية عدد صحيح قيمة لـ قابل للتتبع أصناف" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" -msgstr "" +msgstr "يجب أن يكون Sub صنف محدد" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" -msgstr "" +msgstr "BOM عنصر بديل" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" -msgstr "" +msgstr "بديل صنف لا يمكن يكون ال نفس بصفته ال master صنف" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" -msgstr "" +msgstr "الأصل BOM عنصر" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" -msgstr "" +msgstr "بديل صنف" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" -msgstr "" +msgstr "صنف 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" -msgstr "" +msgstr "صنف 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" -msgstr "" +msgstr "تحديد مرتبط صنف" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" -msgstr "" +msgstr "ملاحظة لـ هذا relationship" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" -msgstr "" +msgstr "صنف relationship لا يمكن يكون تم الإنشاء بين صنف و itself" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" -msgstr "" +msgstr "نسخ relationship بالفعل موجود" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "حذف فئات فرعية" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "حذف الكل sub-categories contained ضمن هذا فئة" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "حذف الأصناف" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "حذف الكل أصناف contained ضمن هذا فئة" + +#: part/serializers.py:130 msgid "Parent Category" -msgstr "" +msgstr "الأصل فئة" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" -msgstr "" +msgstr "الأصل فئة الأصناف" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" -msgstr "" +msgstr "فئات فرعية" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" -msgstr "" +msgstr "نتائج" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" -msgstr "" +msgstr "عدد نتائج recorded مقابل هذا قالب" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" -msgstr "" +msgstr "شراء عملة لـ هذا عنصر المخزون" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" -msgstr "" +msgstr "ملف هو غير صورة" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" +#: part/serializers.py:426 +msgid "Initial Stock Quantity" +msgstr "كمية أولي مخزون" #: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 -msgid "Initial Stock Quantity" -msgstr "" - -#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." -msgstr "" +msgstr "تحديد أولي مخزون كمية لـ هذا صنف. إذا كمية هو صفر، لا مخزون هو تمت الإضافة." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" -msgstr "" +msgstr "أولي موقع المخزون" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" -msgstr "" +msgstr "تحديد أولي موقع المخزون لـ هذا صنف" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" -msgstr "" +msgstr "تحديد مورد (أو ترك فارغ إلى تخطي)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" -msgstr "" +msgstr "تحديد شركة مصنعة (أو ترك فارغ إلى تخطي)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" -msgstr "" +msgstr "صنف الشركة المصنعة رقم" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" -msgstr "" +msgstr "محدد شركة هو غير صالح مورد" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" -msgstr "" +msgstr "محدد شركة هو غير صالح شركة مصنعة" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" -msgstr "" +msgstr "صنف الشركة المصنعة مطابق هذا MPN بالفعل موجود" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" -msgstr "" +msgstr "صنف المورد مطابق هذا SKU بالفعل موجود" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" -msgstr "" +msgstr "فئة اسم" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" -msgstr "" +msgstr "كمية هذا صنف حاليًا being في الإنتاج" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" -msgstr "" +msgstr "متبقي كمية لـ هذا صنف مجدول إلى يكون built" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" -msgstr "" +msgstr "عناصر المخزون" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" -msgstr "" +msgstr "مراجعات" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" -msgstr "" +msgstr "إجمالي مخزون" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" -msgstr "" +msgstr "غير مخصص مخزون" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" -msgstr "" +msgstr "متغير مخزون" + +#: part/serializers.py:956 +msgid "Duplicate Part" +msgstr "نسخ صنف" + +#: part/serializers.py:957 +msgid "Copy initial data from another Part" +msgstr "نسخ أولي بيانات من آخر صنف" + +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "نسخ صورة" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "نسخ صورة من أصلي صنف" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "نسخ BOM" #: part/serializers.py:969 -msgid "Duplicate Part" -msgstr "" +msgid "Copy bill of materials from original part" +msgstr "نسخ قائمة المواد من أصلي صنف" -#: part/serializers.py:970 -msgid "Copy initial data from another Part" -msgstr "" +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "نسخ ملاحظات" -#: part/serializers.py:976 +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "نسخ ملاحظات من أصلي صنف" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "نسخ اختبارات" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "نسخ اختبار قوالب من أصلي صنف" + +#: part/serializers.py:988 msgid "Initial Stock" -msgstr "" +msgstr "أولي مخزون" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" -msgstr "" +msgstr "إنشاء كمية صنف مع أولي مخزون" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" -msgstr "" +msgstr "مورد معلومات" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" -msgstr "" +msgstr "إضافة أولي مورد معلومات لـ هذا صنف" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" -msgstr "" +msgstr "نسخ فئة معلمات" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" -msgstr "" +msgstr "نسخ معلمة قوالب من محدد فئة الأصناف" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" -msgstr "" +msgstr "موجود صورة" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" -msgstr "" +msgstr "اسم الملف لـ موجود صنف صورة" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" -msgstr "" +msgstr "صورة ملف يقوم غير موجود" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" -msgstr "" +msgstr "تحقق entire قائمة المواد" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" -msgstr "" +msgstr "قابل للإنتاج" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" -msgstr "" +msgstr "مطلوب لـ أوامر الإنتاج" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" -msgstr "" +msgstr "مخصص إلى أوامر الإنتاج" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" -msgstr "" +msgstr "مطلوب لـ طلبات البيع" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" -msgstr "" +msgstr "مخصص إلى طلبات البيع" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" -msgstr "" +msgstr "صنف IPN" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" -msgstr "" +msgstr "صنف وصف" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" -msgstr "" +msgstr "تحديد صنف إلى إنشاء جرد المخزون معلومات لـ ذلك صنف (و أي متغير أصناف)" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" -msgstr "" +msgstr "تحديد فئة إلى تضمين الكل أصناف ضمن ذلك فئة (و فئات فرعية)" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" -msgstr "" +msgstr "تحديد موقع إلى تضمين الكل أصناف مع مخزون في ذلك موقع (including sub-locations)" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" -msgstr "" +msgstr "إنشاء جرد المخزون سجلات" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" -msgstr "" +msgstr "حفظ جرد المخزون سجلات لـ ال محدد أصناف" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" -msgstr "" +msgstr "إنشاء تقرير" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" -msgstr "" - -#: part/serializers.py:1466 -msgid "Minimum Price" -msgstr "" - -#: part/serializers.py:1467 -msgid "Override calculated value for minimum price" -msgstr "" - -#: part/serializers.py:1474 -msgid "Minimum price currency" -msgstr "" +msgstr "إنشاء جرد المخزون تقرير لـ ال محدد أصناف" #: part/serializers.py:1481 -msgid "Maximum Price" -msgstr "" +msgid "Minimum Price" +msgstr "أدنى سعر" #: part/serializers.py:1482 -msgid "Override calculated value for maximum price" -msgstr "" +msgid "Override calculated value for minimum price" +msgstr "تجاوز محسوب قيمة لـ أدنى سعر" #: part/serializers.py:1489 +msgid "Minimum price currency" +msgstr "أدنى سعر عملة" + +#: part/serializers.py:1496 +msgid "Maximum Price" +msgstr "أقصى سعر" + +#: part/serializers.py:1497 +msgid "Override calculated value for maximum price" +msgstr "تجاوز محسوب قيمة لـ أقصى سعر" + +#: part/serializers.py:1504 msgid "Maximum price currency" -msgstr "" +msgstr "أقصى سعر عملة" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" -msgstr "" +msgstr "تحديث" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" -msgstr "" +msgstr "تحديث التسعير لـ هذا صنف" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" -msgstr "" +msgstr "يمكن غير تحويل من مقدم currencies إلى {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" -msgstr "" +msgstr "أدنى سعر يجب غير يكون أكبر من أقصى سعر" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" -msgstr "" +msgstr "أقصى سعر يجب غير يكون أقل من أدنى سعر" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" -msgstr "" +msgstr "Amount مطلوب لـ هذا عنصر (يمكن تضمين وحدات)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" -msgstr "" +msgstr "تحديد ال الأصل تجميع" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" -msgstr "" +msgstr "تحديد ال مكوّن صنف" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" -msgstr "" - -#: part/serializers.py:1989 -msgid "Select part to copy BOM from" -msgstr "" - -#: part/serializers.py:1997 -msgid "Remove Existing Data" -msgstr "" - -#: part/serializers.py:1998 -msgid "Remove existing BOM items before copying" -msgstr "" - -#: part/serializers.py:2003 -msgid "Include Inherited" -msgstr "" - -#: part/serializers.py:2004 -msgid "Include BOM items which are inherited from templated parts" -msgstr "" - -#: part/serializers.py:2009 -msgid "Skip Invalid Rows" -msgstr "" - -#: part/serializers.py:2010 -msgid "Enable this option to skip invalid rows" -msgstr "" - -#: part/serializers.py:2015 -msgid "Copy Substitute Parts" -msgstr "" +msgstr "غير صالح كمية تنسيق" #: part/serializers.py:2016 +msgid "Select part to copy BOM from" +msgstr "تحديد صنف إلى نسخ BOM من" + +#: part/serializers.py:2024 +msgid "Remove Existing Data" +msgstr "إزالة موجود بيانات" + +#: part/serializers.py:2025 +msgid "Remove existing BOM items before copying" +msgstr "إزالة موجود BOM عناصر قبل copying" + +#: part/serializers.py:2030 +msgid "Include Inherited" +msgstr "تضمين موروث" + +#: part/serializers.py:2031 +msgid "Include BOM items which are inherited from templated parts" +msgstr "تضمين BOM عناصر الذي هي موروث من templated أصناف" + +#: part/serializers.py:2036 +msgid "Skip Invalid Rows" +msgstr "تخطي غير صالح صفوف" + +#: part/serializers.py:2037 +msgid "Enable this option to skip invalid rows" +msgstr "تفعيل هذا خيار إلى تخطي غير صالح صفوف" + +#: part/serializers.py:2042 +msgid "Copy Substitute Parts" +msgstr "نسخ بديل أصناف" + +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" -msgstr "" +msgstr "نسخ بديل أصناف عند نسخ BOM عناصر" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" -msgstr "" +msgstr "منخفض مخزون إشعار" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" -msgstr "" +msgstr "ال متاح مخزون لـ {part.name} لديه fallen below ال مهيأ أدنى مستوى" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" -msgstr "" +msgstr "قديم مخزون إشعار" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" -msgstr "" +msgstr "تاريخ أنت لديه 1 عنصر المخزون approaching its انتهاء" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" -msgstr "" +msgstr "أنت لديه {item_count} عناصر المخزون approaching الخاص بهم انتهاء تواريخ" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" -msgstr "" +msgstr "تاريخ لا انتهاء" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" -msgstr "" +msgstr "منتهي {abs(days_diff)} أيام ago" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" -msgstr "" +msgstr "{days_until_expiry} أيام" #: plugin/api.py:80 msgid "Builtin" @@ -7005,277 +7445,293 @@ msgstr "" #: plugin/api.py:109 msgid "Sample" -msgstr "" +msgstr "عينة" #: plugin/api.py:123 plugin/models.py:167 msgid "Installed" -msgstr "" +msgstr "مثبت" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" -msgstr "" +msgstr "إضافة لا يمكن يكون تم الحذف بصفته هو هو حاليًا نشط" #: plugin/base/action/api.py:56 msgid "No action specified" -msgstr "" +msgstr "لا إجراء محدد" #: plugin/base/action/api.py:70 msgid "No matching action found" -msgstr "" +msgstr "لم يتم العثور على مطابق إجراء" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" -msgstr "" +msgstr "لا مطابقة تم العثور لـ باركود بيانات" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" -msgstr "" +msgstr "مطابقة تم العثور لـ باركود بيانات" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" -msgstr "" +msgstr "نموذج هو غير supported" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" -msgstr "" +msgstr "نموذج نسخة غير تم العثور" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" -msgstr "" +msgstr "باركود matches موجود عنصر" #: plugin/base/barcodes/api.py:419 msgid "No matching part data found" -msgstr "" +msgstr "لم يتم العثور على مطابق صنف بيانات" #: plugin/base/barcodes/api.py:435 msgid "No matching supplier parts found" -msgstr "" +msgstr "لم يتم العثور على مطابق أصناف المورد" #: plugin/base/barcodes/api.py:438 msgid "Multiple matching supplier parts found" +msgstr "متعدد مطابق أصناف المورد تم العثور" + +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" -msgstr "" +msgstr "لا يوجد إضافة تم العثور لـ باركود بيانات مطابق" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" -msgstr "" +msgstr "Matched صنف المورد" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" -msgstr "" +msgstr "عنصر لديه بالفعل تم مستلم" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "طلب الشراء Found\\rNo صنف المورد مطابقة" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "صنف المورد Found\\rNo طلب الشراء مطابقة" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" -msgstr "" +msgstr "لا إضافة مطابقة لـ مورد باركود" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" -msgstr "" +msgstr "متعدد مطابق البنود تم العثور" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" +msgstr "لم يتم العثور على مطابق بند" + +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" -msgstr "" +msgstr "لا طلب البيع مقدم" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" -msgstr "" +msgstr "باركود يقوم غير مطابقة موجود عنصر المخزون" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" -msgstr "" +msgstr "عنصر المخزون يقوم غير مطابقة بند" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" -msgstr "" +msgstr "Insufficient مخزون متاح" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" -msgstr "" +msgstr "عنصر المخزون مخصص إلى طلب البيع" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" -msgstr "" +msgstr "غير enough معلومات" #: plugin/base/barcodes/mixins.py:309 #: plugin/builtin/barcodes/inventree_barcode.py:101 msgid "Found matching item" -msgstr "" +msgstr "تم العثور مطابق عنصر" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" -msgstr "" +msgstr "صنف المورد يقوم غير مطابقة بند" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" -msgstr "" +msgstr "بند هو بالفعل مكتمل" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" -msgstr "" +msgstr "Further معلومات مطلوب إلى استلام بند" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" -msgstr "" +msgstr "مستلم طلب الشراء بند" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" -msgstr "" +msgstr "فشل في استلام بند" #: plugin/base/barcodes/serializers.py:53 msgid "Scanned barcode data" -msgstr "" +msgstr "تم المسح باركود بيانات" #: plugin/base/barcodes/serializers.py:62 msgid "Model name to generate barcode for" -msgstr "" +msgstr "نموذج اسم إلى إنشاء باركود لـ" #: plugin/base/barcodes/serializers.py:67 msgid "Primary key of model object to generate barcode for" -msgstr "" +msgstr "أساسي مفتاح لـ نموذج كائن إلى إنشاء باركود لـ" #: plugin/base/barcodes/serializers.py:137 msgid "Purchase Order to allocate items against" -msgstr "" +msgstr "طلب الشراء إلى تخصيص عناصر مقابل" #: plugin/base/barcodes/serializers.py:143 msgid "Purchase order is not open" -msgstr "" +msgstr "طلب الشراء هو غير فتح" #: plugin/base/barcodes/serializers.py:161 msgid "Supplier to receive items from" -msgstr "" +msgstr "مورد إلى استلام عناصر من" #: plugin/base/barcodes/serializers.py:168 msgid "PurchaseOrder to receive items against" -msgstr "" +msgstr "PurchaseOrder إلى استلام عناصر مقابل" #: plugin/base/barcodes/serializers.py:174 msgid "Purchase order has not been placed" -msgstr "" +msgstr "طلب الشراء لديه غير تم placed" #: plugin/base/barcodes/serializers.py:182 msgid "Location to receive items into" -msgstr "" +msgstr "موقع إلى استلام عناصر إلى" #: plugin/base/barcodes/serializers.py:188 msgid "Cannot select a structural location" -msgstr "" +msgstr "لا يمكن تحديد هيكلي موقع" #: plugin/base/barcodes/serializers.py:196 msgid "Purchase order line item to receive items against" -msgstr "" +msgstr "طلب الشراء بند إلى استلام عناصر مقابل" #: plugin/base/barcodes/serializers.py:202 msgid "Automatically allocate stock items to the purchase order" -msgstr "" +msgstr "تلقائيًا تخصيص عناصر المخزون إلى ال طلب الشراء" #: plugin/base/barcodes/serializers.py:215 msgid "Sales Order to allocate items against" -msgstr "" +msgstr "طلب البيع إلى تخصيص عناصر مقابل" #: plugin/base/barcodes/serializers.py:221 msgid "Sales order is not open" -msgstr "" +msgstr "طلب البيع هو غير فتح" #: plugin/base/barcodes/serializers.py:229 msgid "Sales order line item to allocate items against" -msgstr "" +msgstr "طلب البيع بند إلى تخصيص عناصر مقابل" #: plugin/base/barcodes/serializers.py:236 msgid "Sales order shipment to allocate items against" -msgstr "" +msgstr "طلب البيع شحنة إلى تخصيص عناصر مقابل" #: plugin/base/barcodes/serializers.py:242 msgid "Shipment has already been delivered" -msgstr "" +msgstr "شحنة لديه بالفعل تم delivered" #: plugin/base/barcodes/serializers.py:247 msgid "Quantity to allocate" -msgstr "" +msgstr "كمية إلى تخصيص" #: plugin/base/label/label.py:41 msgid "Label printing failed" -msgstr "" +msgstr "ملصق الطباعة فشل" #: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" -msgstr "" +msgstr "خطأ في عرض ملصق إلى PDF" #: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" -msgstr "" +msgstr "خطأ في عرض ملصق إلى HTML" #: plugin/base/label/mixins.py:156 msgid "No items provided to print" -msgstr "" +msgstr "لا عناصر مقدم إلى طباعة" #: plugin/base/ui/serializers.py:30 msgid "Plugin Name" -msgstr "" +msgstr "إضافة اسم" #: plugin/base/ui/serializers.py:34 msgid "Feature Type" -msgstr "" +msgstr "ميزة نوع" #: plugin/base/ui/serializers.py:39 msgid "Feature Label" -msgstr "" +msgstr "ميزة ملصق" #: plugin/base/ui/serializers.py:44 msgid "Feature Title" -msgstr "" +msgstr "ميزة عنوان" #: plugin/base/ui/serializers.py:49 msgid "Feature Description" -msgstr "" +msgstr "ميزة وصف" #: plugin/base/ui/serializers.py:54 msgid "Feature Icon" -msgstr "" +msgstr "ميزة أيقونة" #: plugin/base/ui/serializers.py:58 msgid "Feature Options" -msgstr "" +msgstr "ميزة خيارات" #: plugin/base/ui/serializers.py:61 msgid "Feature Context" -msgstr "" +msgstr "ميزة سياق" #: plugin/base/ui/serializers.py:64 msgid "Feature Source (javascript)" -msgstr "" +msgstr "ميزة المصدر (javascript)" #: plugin/builtin/barcodes/inventree_barcode.py:27 msgid "InvenTree Barcodes" -msgstr "" +msgstr "InvenTree باركودات" #: plugin/builtin/barcodes/inventree_barcode.py:28 msgid "Provides native support for barcodes" -msgstr "" +msgstr "يوفر native الدعم لـ باركودات" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7283,83 +7739,83 @@ msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:34 msgid "Internal Barcode Format" -msgstr "" +msgstr "داخلي باركود تنسيق" #: plugin/builtin/barcodes/inventree_barcode.py:35 msgid "Select an internal barcode format" -msgstr "" +msgstr "تحديد داخلي باركود تنسيق" #: plugin/builtin/barcodes/inventree_barcode.py:37 msgid "JSON barcodes (human readable)" -msgstr "" +msgstr "JSON باركودات (human readable)" #: plugin/builtin/barcodes/inventree_barcode.py:38 msgid "Short barcodes (space optimized)" -msgstr "" +msgstr "Short باركودات (space optimized)" #: plugin/builtin/barcodes/inventree_barcode.py:43 msgid "Short Barcode Prefix" -msgstr "" +msgstr "Short باركود Prefix" #: plugin/builtin/barcodes/inventree_barcode.py:45 msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" -msgstr "" +msgstr "Customize ال prefix مستخدم لـ short باركودات، قد يكون useful لـ environments مع متعدد InvenTree instances" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" -msgstr "" +msgstr "تلقائي إنشاء Builds" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" -msgstr "" +msgstr "تلقائيًا إنشاء أوامر الإنتاج لـ تجميعات" #: plugin/builtin/events/auto_issue_orders.py:17 msgid "Auto Issue Orders" -msgstr "" +msgstr "تلقائي صرف طلبات" #: plugin/builtin/events/auto_issue_orders.py:20 msgid "Automatically issue orders on the assigned target date" -msgstr "" +msgstr "تاريخ تلقائيًا صرف طلبات على ال مسند هدف" #: plugin/builtin/events/auto_issue_orders.py:30 msgid "Auto Issue Build Orders" -msgstr "" +msgstr "تلقائي صرف أوامر الإنتاج" #: plugin/builtin/events/auto_issue_orders.py:32 msgid "Automatically issue build orders on the assigned target date" -msgstr "" +msgstr "تاريخ تلقائيًا صرف أوامر الإنتاج على ال مسند هدف" #: plugin/builtin/events/auto_issue_orders.py:38 msgid "Auto Issue Purchase Orders" -msgstr "" +msgstr "تلقائي صرف طلبات الشراء" #: plugin/builtin/events/auto_issue_orders.py:40 msgid "Automatically issue purchase orders on the assigned target date" -msgstr "" +msgstr "تاريخ تلقائيًا صرف طلبات الشراء على ال مسند هدف" #: plugin/builtin/events/auto_issue_orders.py:46 msgid "Auto Issue Sales Orders" -msgstr "" +msgstr "تلقائي صرف طلبات البيع" #: plugin/builtin/events/auto_issue_orders.py:48 msgid "Automatically issue sales orders on the assigned target date" -msgstr "" +msgstr "تاريخ تلقائيًا صرف طلبات البيع على ال مسند هدف" #: plugin/builtin/events/auto_issue_orders.py:54 msgid "Auto Issue Return Orders" -msgstr "" +msgstr "تلقائي صرف طلبات الإرجاع" #: plugin/builtin/events/auto_issue_orders.py:56 msgid "Automatically issue return orders on the assigned target date" -msgstr "" +msgstr "تاريخ تلقائيًا صرف طلبات الإرجاع على ال مسند هدف" #: plugin/builtin/events/auto_issue_orders.py:62 msgid "Issue Backdated Orders" -msgstr "" +msgstr "صرف Backdated طلبات" #: plugin/builtin/events/auto_issue_orders.py:63 msgid "Automatically issue orders that are backdated" -msgstr "" +msgstr "تلقائيًا صرف طلبات ذلك هي backdated" #: plugin/builtin/exporter/bom_exporter.py:22 msgid "Levels" @@ -7367,572 +7823,588 @@ msgstr "" #: plugin/builtin/exporter/bom_exporter.py:24 msgid "Number of levels to export - set to zero to export all BOM levels" -msgstr "" +msgstr "عدد levels إلى تصدير - تعيين إلى صفر إلى تصدير الكل BOM levels" #: plugin/builtin/exporter/bom_exporter.py:31 #: plugin/builtin/exporter/bom_exporter.py:118 msgid "Total Quantity" -msgstr "" +msgstr "كمية الإجمالي" #: plugin/builtin/exporter/bom_exporter.py:32 msgid "Include total quantity of each part in the BOM" -msgstr "" +msgstr "تضمين إجمالي كمية لـ كل صنف في ال BOM" #: plugin/builtin/exporter/bom_exporter.py:36 msgid "Stock Data" -msgstr "" +msgstr "مخزون بيانات" #: plugin/builtin/exporter/bom_exporter.py:36 msgid "Include part stock data" -msgstr "" +msgstr "تضمين صنف مخزون بيانات" #: plugin/builtin/exporter/bom_exporter.py:40 #: plugin/builtin/exporter/stocktake_exporter.py:20 msgid "Pricing Data" -msgstr "" +msgstr "التسعير بيانات" #: plugin/builtin/exporter/bom_exporter.py:40 #: plugin/builtin/exporter/stocktake_exporter.py:20 msgid "Include part pricing data" -msgstr "" +msgstr "تضمين صنف التسعير بيانات" #: plugin/builtin/exporter/bom_exporter.py:44 msgid "Supplier Data" -msgstr "" +msgstr "مورد بيانات" #: plugin/builtin/exporter/bom_exporter.py:44 msgid "Include supplier data" -msgstr "" +msgstr "تضمين مورد بيانات" #: plugin/builtin/exporter/bom_exporter.py:49 msgid "Manufacturer Data" -msgstr "" +msgstr "شركة مصنعة بيانات" #: plugin/builtin/exporter/bom_exporter.py:50 msgid "Include manufacturer data" -msgstr "" +msgstr "تضمين شركة مصنعة بيانات" #: plugin/builtin/exporter/bom_exporter.py:55 msgid "Substitute Data" -msgstr "" +msgstr "بديل بيانات" #: plugin/builtin/exporter/bom_exporter.py:56 msgid "Include substitute part data" -msgstr "" +msgstr "تضمين بديل صنف بيانات" #: plugin/builtin/exporter/bom_exporter.py:61 msgid "Parameter Data" -msgstr "" +msgstr "معلمة بيانات" #: plugin/builtin/exporter/bom_exporter.py:62 msgid "Include part parameter data" -msgstr "" +msgstr "تضمين معلمة الصنف بيانات" #: plugin/builtin/exporter/bom_exporter.py:71 msgid "Multi-Level BOM Exporter" -msgstr "" +msgstr "Multi-Level BOM مصدّر" #: plugin/builtin/exporter/bom_exporter.py:72 msgid "Provides support for exporting multi-level BOMs" -msgstr "" +msgstr "يوفر الدعم لـ exporting multi-level BOMs" #: plugin/builtin/exporter/bom_exporter.py:114 msgid "BOM Level" -msgstr "" +msgstr "BOM مستوى" #: plugin/builtin/exporter/bom_exporter.py:124 #, python-brace-format msgid "Substitute {n}" -msgstr "" +msgstr "بديل {n}" #: plugin/builtin/exporter/bom_exporter.py:130 #, python-brace-format msgid "Supplier {n}" -msgstr "" +msgstr "مورد {n}" #: plugin/builtin/exporter/bom_exporter.py:131 #, python-brace-format msgid "Supplier {n} SKU" -msgstr "" +msgstr "مورد {n} SKU" #: plugin/builtin/exporter/bom_exporter.py:132 #, python-brace-format msgid "Supplier {n} MPN" -msgstr "" +msgstr "مورد {n} MPN" #: plugin/builtin/exporter/bom_exporter.py:138 #, python-brace-format msgid "Manufacturer {n}" -msgstr "" +msgstr "شركة مصنعة {n}" #: plugin/builtin/exporter/bom_exporter.py:139 #, python-brace-format msgid "Manufacturer {n} MPN" -msgstr "" +msgstr "شركة مصنعة {n} MPN" #: plugin/builtin/exporter/inventree_exporter.py:14 msgid "InvenTree Generic Exporter" -msgstr "" +msgstr "InvenTree Generic مصدّر" #: plugin/builtin/exporter/inventree_exporter.py:15 msgid "Provides support for exporting data from InvenTree" -msgstr "" +msgstr "يوفر الدعم لـ exporting بيانات من InvenTree" #: plugin/builtin/exporter/parameter_exporter.py:16 msgid "Exclude Inactive" -msgstr "" +msgstr "استبعاد غير نشط" #: plugin/builtin/exporter/parameter_exporter.py:17 msgid "Exclude parameters which are inactive" -msgstr "" +msgstr "استبعاد معلمات الذي هي غير نشط" #: plugin/builtin/exporter/parameter_exporter.py:29 msgid "Parameter Exporter" -msgstr "" +msgstr "معلمة مصدّر" #: plugin/builtin/exporter/parameter_exporter.py:30 msgid "Exporter for model parameter data" -msgstr "" +msgstr "مصدّر لـ نموذج معلمة بيانات" #: plugin/builtin/exporter/stocktake_exporter.py:25 msgid "Include External Stock" -msgstr "" +msgstr "تضمين خارجي مخزون" #: plugin/builtin/exporter/stocktake_exporter.py:26 msgid "Include external stock in the stocktake data" -msgstr "" +msgstr "تضمين خارجي مخزون في ال جرد المخزون بيانات" #: plugin/builtin/exporter/stocktake_exporter.py:31 msgid "Include Variant Items" -msgstr "" +msgstr "تضمين متغير عناصر" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "" +msgid "Include part variant stock in stocktake data" +msgstr "تضمين صنف متغير مخزون في جرد المخزون بيانات" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "استبعاد صفر مخزون سجلات" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "استبعاد أصناف مع صفر مخزون من ال exported dataset" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" -msgstr "" +msgstr "صنف جرد المخزون مصدّر" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" -msgstr "" +msgstr "مصدّر لـ صنف جرد المخزون بيانات" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" -msgstr "" +msgstr "أدنى وحدة تكلفة" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" -msgstr "" +msgstr "أقصى وحدة تكلفة" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" -msgstr "" +msgstr "أدنى إجمالي تكلفة" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" -msgstr "" +msgstr "أقصى إجمالي تكلفة" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" -msgstr "" +msgstr "InvenTree UI إشعارات" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" -msgstr "" +msgstr "Integrated UI إشعار طرق" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" -msgstr "" +msgstr "InvenTree بريد إلكتروني إشعارات" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" -msgstr "" +msgstr "Integrated بريد إلكتروني إشعار طرق" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" -msgstr "" +msgstr "السماح بريد إلكتروني إشعارات" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" -msgstr "" +msgstr "السماح بريد إلكتروني إشعارات إلى يكون تم الإرسال إلى هذا مستخدم" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" -msgstr "" - -#: plugin/builtin/integration/core_notifications.py:126 -msgid "Integrated Slack notification methods" -msgstr "" - -#: plugin/builtin/integration/core_notifications.py:131 -msgid "Slack incoming webhook URL" -msgstr "" +msgstr "InvenTree Slack إشعارات" #: plugin/builtin/integration/core_notifications.py:132 -msgid "URL that is used to send messages to a slack channel" -msgstr "" +msgid "Integrated Slack notification methods" +msgstr "Integrated Slack إشعار طرق" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:137 +msgid "Slack incoming webhook URL" +msgstr "Slack وارد webhook URL" + +#: plugin/builtin/integration/core_notifications.py:138 +msgid "URL that is used to send messages to a slack channel" +msgstr "URL ذلك هو مستخدم إلى إرسال messages إلى slack channel" + +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" -msgstr "" +msgstr "فتح رابط" #: plugin/builtin/integration/currency_exchange.py:22 msgid "InvenTree Currency Exchange" -msgstr "" +msgstr "InvenTree عملة صرف" #: plugin/builtin/integration/currency_exchange.py:23 msgid "Default currency exchange integration" -msgstr "" +msgstr "افتراضي عملة صرف تكامل" #: plugin/builtin/integration/machine_types.py:15 msgid "InvenTree Machines" -msgstr "" +msgstr "InvenTree آلات" #: plugin/builtin/integration/machine_types.py:16 msgid "Built-in machine types for InvenTree" -msgstr "" +msgstr "Built-in آلة أنواع لـ InvenTree" #: plugin/builtin/integration/part_notifications.py:20 msgid "Part Notifications" -msgstr "" +msgstr "صنف إشعارات" #: plugin/builtin/integration/part_notifications.py:22 msgid "Notify users about part changes" -msgstr "" +msgstr "Notify مستخدمون حول صنف تغييرات" #: plugin/builtin/integration/part_notifications.py:27 msgid "Send notifications" -msgstr "" +msgstr "إرسال إشعارات" #: plugin/builtin/integration/part_notifications.py:28 msgid "Send notifications for part changes to subscribed users" -msgstr "" +msgstr "إرسال إشعارات لـ صنف تغييرات إلى مشتركة مستخدمون" #: plugin/builtin/integration/part_notifications.py:45 msgid "Changed part notification" -msgstr "" +msgstr "تم التغيير صنف إشعار" #: plugin/builtin/integration/part_notifications.py:55 #, python-brace-format msgid "The part `{part.name}` has been triggered with a `{part_action}` event" -msgstr "" +msgstr "ال صنف `{part.name}` لديه تم triggered مع `{part_action}` event" #: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" -msgstr "" +msgstr "InvenTree PDF ملصق طابعة" #: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" -msgstr "" - -#: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 -msgid "Debug mode" -msgstr "" +msgstr "يوفر native الدعم لـ الطباعة PDF ملصقات" #: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 +msgid "Debug mode" +msgstr "تصحيح الأخطاء وضع" + +#: plugin/builtin/labels/inventree_label.py:34 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" -msgstr "" +msgstr "تفعيل تصحيح الأخطاء وضع - returns raw HTML بدلًا من لـ PDF" #: plugin/builtin/labels/inventree_machine.py:61 msgid "InvenTree machine label printer" -msgstr "" +msgstr "InvenTree آلة ملصق طابعة" #: plugin/builtin/labels/inventree_machine.py:62 msgid "Provides support for printing using a machine" -msgstr "" +msgstr "يوفر الدعم لـ الطباعة باستخدام آلة" #: plugin/builtin/labels/inventree_machine.py:164 msgid "last used" -msgstr "" +msgstr "آخر مستخدم" #: plugin/builtin/labels/inventree_machine.py:181 msgid "Options" -msgstr "" +msgstr "الخيارات" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" -msgstr "" - -#: plugin/builtin/labels/label_sheet.py:35 -msgid "Skip Labels" -msgstr "" +msgstr "صفحة حجم لـ ال ملصق sheet" #: plugin/builtin/labels/label_sheet.py:36 -msgid "Skip this number of labels when printing label sheets" -msgstr "" +msgid "Skip Labels" +msgstr "تخطي ملصقات" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:37 +msgid "Skip this number of labels when printing label sheets" +msgstr "تخطي هذا رقم لـ ملصقات عند الطباعة ملصق sheets" + +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" -msgstr "" +msgstr "طباعة border around كل ملصق" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" -msgstr "" - -#: plugin/builtin/labels/label_sheet.py:55 -msgid "Page Margin" -msgstr "" +msgstr "طباعة ال ملصق sheet في landscape وضع" #: plugin/builtin/labels/label_sheet.py:56 -msgid "Margin around the page in mm" -msgstr "" +msgid "Page Margin" +msgstr "صفحة Margin" -#: plugin/builtin/labels/label_sheet.py:69 -msgid "InvenTree Label Sheet Printer" -msgstr "" +#: plugin/builtin/labels/label_sheet.py:57 +msgid "Margin around the page in mm" +msgstr "Margin around ال صفحة في mm" #: plugin/builtin/labels/label_sheet.py:70 +msgid "InvenTree Label Sheet Printer" +msgstr "InvenTree ملصق Sheet طابعة" + +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" -msgstr "" +msgstr "Arrays متعدد ملصقات onto مفرد sheet" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" -msgstr "" +msgstr "ملصق هو أيضًا large لـ صفحة حجم" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" -msgstr "" +msgstr "لا ملصقات كانت تم الإنشاء" #: plugin/builtin/suppliers/digikey.py:17 msgid "Supplier Integration - DigiKey" -msgstr "" +msgstr "مورد تكامل - DigiKey" #: plugin/builtin/suppliers/digikey.py:18 msgid "Provides support for scanning DigiKey barcodes" -msgstr "" +msgstr "يوفر الدعم لـ المسح DigiKey باركودات" #: plugin/builtin/suppliers/digikey.py:27 msgid "The Supplier which acts as 'DigiKey'" -msgstr "" +msgstr "ال مورد الذي acts بصفته 'DigiKey'" #: plugin/builtin/suppliers/lcsc.py:19 msgid "Supplier Integration - LCSC" -msgstr "" +msgstr "مورد تكامل - LCSC" #: plugin/builtin/suppliers/lcsc.py:20 msgid "Provides support for scanning LCSC barcodes" -msgstr "" +msgstr "يوفر الدعم لـ المسح LCSC باركودات" #: plugin/builtin/suppliers/lcsc.py:28 msgid "The Supplier which acts as 'LCSC'" -msgstr "" +msgstr "ال مورد الذي acts بصفته 'LCSC'" #: plugin/builtin/suppliers/mouser.py:17 msgid "Supplier Integration - Mouser" -msgstr "" +msgstr "مورد تكامل - Mouser" #: plugin/builtin/suppliers/mouser.py:18 msgid "Provides support for scanning Mouser barcodes" -msgstr "" +msgstr "يوفر الدعم لـ المسح Mouser باركودات" #: plugin/builtin/suppliers/mouser.py:26 msgid "The Supplier which acts as 'Mouser'" -msgstr "" +msgstr "ال مورد الذي acts بصفته 'Mouser'" #: plugin/builtin/suppliers/tme.py:19 msgid "Supplier Integration - TME" -msgstr "" +msgstr "مورد تكامل - TME" #: plugin/builtin/suppliers/tme.py:20 msgid "Provides support for scanning TME barcodes" -msgstr "" +msgstr "يوفر الدعم لـ المسح TME باركودات" #: plugin/builtin/suppliers/tme.py:28 msgid "The Supplier which acts as 'TME'" +msgstr "ال مورد الذي acts بصفته 'TME'" + +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" -msgstr "" +msgstr "فقط مستخدم فائق accounts يمكن administer إضافات" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" +msgstr "إضافة تثبيت هو معطّل" + +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" -msgstr "" +msgstr "لا طرد اسم أو URL مقدم لـ تثبيت" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" -msgstr "" +msgstr "غير صالح characters في طرد اسم أو URL" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" -msgstr "" +msgstr "مثبت إضافة بنجاح" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" -msgstr "" +msgstr "مثبت إضافة إلى {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" -msgstr "" +msgstr "إضافة كان غير تم العثور في سجل" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" -msgstr "" +msgstr "إضافة هو غير packaged إضافة" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" -msgstr "" +msgstr "إضافة طرد اسم غير تم العثور" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" -msgstr "" - -#: plugin/installer.py:347 -msgid "Plugin uninstalling is disabled" -msgstr "" +msgstr "فقط staff مستخدمون يمكن administer إضافات" #: plugin/installer.py:351 +msgid "Plugin uninstalling is disabled" +msgstr "إضافة uninstalling هو معطّل" + +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" -msgstr "" +msgstr "إضافة لا يمكن يكون غير مثبت بصفته هو هو حاليًا نشط" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" -msgstr "" +msgstr "إضافة لا يمكن يكون غير مثبت بصفته هو هو mandatory" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" -msgstr "" - -#: plugin/installer.py:367 -msgid "Plugin cannot be uninstalled as it is a built-in plugin" -msgstr "" +msgstr "إضافة لا يمكن يكون غير مثبت بصفته هو هو عينة إضافة" #: plugin/installer.py:371 +msgid "Plugin cannot be uninstalled as it is a built-in plugin" +msgstr "إضافة لا يمكن يكون غير مثبت بصفته هو هو built-in إضافة" + +#: plugin/installer.py:375 msgid "Plugin is not installed" -msgstr "" +msgstr "إضافة هو غير مثبت" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" -msgstr "" +msgstr "إضافة تثبيت غير تم العثور" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" -msgstr "" +msgstr "غير مثبت إضافة بنجاح" #: plugin/models.py:39 msgid "Plugin Configuration" -msgstr "" +msgstr "إضافة تهيئة" #: plugin/models.py:40 msgid "Plugin Configurations" -msgstr "" +msgstr "إضافة Configurations" #: plugin/models.py:47 msgid "Key of plugin" -msgstr "" +msgstr "مفتاح لـ إضافة" #: plugin/models.py:55 msgid "Name of the plugin" -msgstr "" +msgstr "اسم لـ ال إضافة" #: plugin/models.py:62 plugin/serializers.py:119 msgid "Package Name" -msgstr "" +msgstr "طرد اسم" #: plugin/models.py:64 msgid "Name of the installed package, if the plugin was installed via PIP" -msgstr "" +msgstr "اسم لـ ال مثبت طرد، إذا ال إضافة كان مثبت عبر PIP" #: plugin/models.py:69 msgid "Is the plugin active" -msgstr "" +msgstr "هو ال إضافة نشط" #: plugin/models.py:176 msgid "Sample plugin" -msgstr "" +msgstr "عينة إضافة" #: plugin/models.py:184 msgid "Builtin Plugin" -msgstr "" +msgstr "Builtin إضافة" #: plugin/models.py:192 msgid "Mandatory Plugin" -msgstr "" +msgstr "Mandatory إضافة" #: plugin/models.py:210 msgid "Package Plugin" -msgstr "" +msgstr "طرد إضافة" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" -msgstr "" +msgstr "الإضافة" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" -msgstr "" +msgstr "لم يتم العثور على author" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" -msgstr "" +msgstr "إضافة '{p}' هو غير compatible مع ال حالي InvenTree إصدار {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" -msgstr "" +msgstr "إضافة يتطلب عند أقل إصدار {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" -msgstr "" +msgstr "إضافة يتطلب عند most إصدار {v}" #: plugin/samples/integration/sample.py:52 msgid "User Setting 1" -msgstr "" +msgstr "مستخدم إعداد 1" #: plugin/samples/integration/sample.py:53 msgid "A user setting that can be changed by the user" -msgstr "" +msgstr "مستخدم إعداد ذلك يمكن يكون تم التغيير حسب ال مستخدم" #: plugin/samples/integration/sample.py:57 msgid "User Setting 2" -msgstr "" +msgstr "مستخدم إعداد 2" #: plugin/samples/integration/sample.py:58 msgid "Another user setting" -msgstr "" +msgstr "آخر مستخدم إعداد" #: plugin/samples/integration/sample.py:63 msgid "User Setting 3" -msgstr "" +msgstr "مستخدم إعداد 3" #: plugin/samples/integration/sample.py:64 msgid "A user setting with choices" -msgstr "" +msgstr "مستخدم إعداد مع خيارات" #: plugin/samples/integration/sample.py:72 msgid "Enable PO" -msgstr "" +msgstr "تفعيل PO" #: plugin/samples/integration/sample.py:73 msgid "Enable PO functionality in InvenTree interface" -msgstr "" +msgstr "تفعيل PO الوظيفة في InvenTree واجهة" #: plugin/samples/integration/sample.py:78 msgid "API Key" -msgstr "" +msgstr "واجهة API مفتاح" #: plugin/samples/integration/sample.py:79 msgid "Key required for accessing external API" -msgstr "" +msgstr "مفتاح مطلوب لـ accessing خارجي واجهة API" #: plugin/samples/integration/sample.py:83 msgid "Numerical" @@ -7940,19 +8412,19 @@ msgstr "" #: plugin/samples/integration/sample.py:84 msgid "A numerical setting" -msgstr "" +msgstr "numerical إعداد" #: plugin/samples/integration/sample.py:90 msgid "Choice Setting" -msgstr "" +msgstr "Choice إعداد" #: plugin/samples/integration/sample.py:91 msgid "A setting with multiple choices" -msgstr "" +msgstr "إعداد مع متعدد خيارات" #: plugin/samples/integration/sample_currency_exchange.py:15 msgid "Sample currency exchange plugin" -msgstr "" +msgstr "عينة عملة صرف إضافة" #: plugin/samples/integration/sample_currency_exchange.py:18 msgid "InvenTree Contributors" @@ -7960,371 +8432,379 @@ msgstr "" #: plugin/samples/integration/user_interface_sample.py:27 msgid "Enable Part Panels" -msgstr "" +msgstr "تفعيل صنف لوحات" #: plugin/samples/integration/user_interface_sample.py:28 msgid "Enable custom panels for Part views" -msgstr "" +msgstr "تفعيل مخصص لوحات لـ صنف views" #: plugin/samples/integration/user_interface_sample.py:33 msgid "Enable Purchase Order Panels" -msgstr "" +msgstr "تفعيل طلب الشراء لوحات" #: plugin/samples/integration/user_interface_sample.py:34 msgid "Enable custom panels for Purchase Order views" -msgstr "" +msgstr "تفعيل مخصص لوحات لـ طلب الشراء views" #: plugin/samples/integration/user_interface_sample.py:39 msgid "Enable Broken Panels" -msgstr "" +msgstr "تفعيل Broken لوحات" #: plugin/samples/integration/user_interface_sample.py:40 msgid "Enable broken panels for testing" -msgstr "" +msgstr "تفعيل broken لوحات لـ testing" #: plugin/samples/integration/user_interface_sample.py:45 msgid "Enable Dynamic Panel" -msgstr "" +msgstr "تفعيل Dynamic Panel" #: plugin/samples/integration/user_interface_sample.py:46 msgid "Enable dynamic panels for testing" -msgstr "" +msgstr "تفعيل dynamic لوحات لـ testing" #: plugin/samples/integration/user_interface_sample.py:114 msgid "Part Panel" -msgstr "" +msgstr "صنف Panel" #: plugin/samples/integration/user_interface_sample.py:149 msgid "Broken Dashboard Item" -msgstr "" +msgstr "Broken لوحة المعلومات عنصر" #: plugin/samples/integration/user_interface_sample.py:151 msgid "This is a broken dashboard item - it will not render!" -msgstr "" +msgstr "هذا هو broken لوحة المعلومات عنصر - هو سوف غير render!" #: plugin/samples/integration/user_interface_sample.py:157 msgid "Sample Dashboard Item" -msgstr "" +msgstr "عينة لوحة المعلومات عنصر" #: plugin/samples/integration/user_interface_sample.py:159 msgid "This is a sample dashboard item. It renders a simple string of HTML content." -msgstr "" +msgstr "هذا هو عينة لوحة المعلومات عنصر. هو renders simple نص لـ HTML محتوى." #: plugin/samples/integration/user_interface_sample.py:165 msgid "Context Dashboard Item" -msgstr "" +msgstr "سياق لوحة المعلومات عنصر" #: plugin/samples/integration/user_interface_sample.py:179 msgid "Admin Dashboard Item" -msgstr "" +msgstr "مسؤول لوحة المعلومات عنصر" #: plugin/samples/integration/user_interface_sample.py:180 msgid "This is an admin-only dashboard item." -msgstr "" +msgstr "هذا هو admin-only لوحة المعلومات عنصر." #: plugin/serializers.py:86 msgid "Source File" -msgstr "" +msgstr "المصدر ملف" #: plugin/serializers.py:87 msgid "Path to the source file for admin integration" -msgstr "" +msgstr "مسار إلى ال المصدر ملف لـ مسؤول تكامل" #: plugin/serializers.py:94 msgid "Optional context data for the admin integration" -msgstr "" +msgstr "اختياري سياق بيانات لـ ال مسؤول تكامل" #: plugin/serializers.py:110 msgid "Source URL" -msgstr "" +msgstr "المصدر URL" #: plugin/serializers.py:112 msgid "Source for the package - this can be a custom registry or a VCS path" -msgstr "" +msgstr "المصدر لـ ال طرد - هذا يمكن يكون مخصص سجل أو VCS مسار" #: plugin/serializers.py:121 msgid "Name for the Plugin Package - can also contain a version indicator" -msgstr "" +msgstr "اسم لـ ال إضافة طرد - يمكن أيضًا contain إصدار indicator" #: plugin/serializers.py:128 msgid "Version" -msgstr "" +msgstr "الإصدار" #: plugin/serializers.py:130 msgid "Version specifier for the plugin. Leave blank for latest version." -msgstr "" +msgstr "إصدار specifier لـ ال إضافة. ترك فارغ لـ الأحدث إصدار." #: plugin/serializers.py:135 msgid "Confirm plugin installation" -msgstr "" +msgstr "تأكيد إضافة تثبيت" #: plugin/serializers.py:137 msgid "This will install this plugin now into the current instance. The instance will go into maintenance." -msgstr "" +msgstr "هذا سوف تثبيت هذا إضافة الآن إلى ال حالي نسخة. ال نسخة سوف انتقال إلى maintenance." #: plugin/serializers.py:150 msgid "Installation not confirmed" -msgstr "" +msgstr "تثبيت غير confirmed" #: plugin/serializers.py:152 msgid "Either packagename or URL must be provided" -msgstr "" +msgstr "يجب أن يكون Either packagename أو URL مقدم" #: plugin/serializers.py:191 msgid "Full reload" -msgstr "" +msgstr "كامل إعادة تحميل" #: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" -msgstr "" +msgstr "Perform كامل إعادة تحميل لـ ال إضافة سجل" #: plugin/serializers.py:198 msgid "Force reload" -msgstr "" +msgstr "Force إعادة تحميل" #: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" -msgstr "" +msgstr "Force إعادة تحميل لـ ال إضافة سجل، even إذا هو هو بالفعل loaded" #: plugin/serializers.py:207 msgid "Collect plugins" -msgstr "" +msgstr "Collect إضافات" #: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" -msgstr "" +msgstr "Collect إضافات و إضافة them إلى ال سجل" #: plugin/serializers.py:236 msgid "Activate Plugin" -msgstr "" +msgstr "Activate إضافة" #: plugin/serializers.py:237 msgid "Activate this plugin" -msgstr "" +msgstr "Activate هذا إضافة" #: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" -msgstr "" +msgstr "Mandatory إضافة لا يمكن يكون deactivated" #: plugin/serializers.py:264 msgid "Delete configuration" -msgstr "" +msgstr "حذف تهيئة" #: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" -msgstr "" +msgstr "حذف ال إضافة تهيئة من ال قاعدة بيانات" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "يشير إذا ال إعداد هو overridden حسب تهيئة" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" -msgstr "" +msgstr "ال مستخدم لـ الذي هذا إعداد applies" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" -msgstr "" +msgstr "عناصر" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" -msgstr "" +msgstr "إضافة غير تم العثور" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" -msgstr "" +msgstr "إضافة يقوم غير الدعم ملصق الطباعة" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "أنت تنفيذ غير لديه صلاحية إلى عرض هذا نموذج نوع" + +#: report/api.py:174 msgid "Invalid label dimensions" -msgstr "" +msgstr "غير صالح ملصق dimensions" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" -msgstr "" +msgstr "لا صالح عناصر مقدم إلى قالب" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" -msgstr "" +msgstr "قالب ملف مع هذا اسم بالفعل موجود" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" -msgstr "" +msgstr "قالب اسم" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" -msgstr "" +msgstr "قالب وصف" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" -msgstr "" +msgstr "مراجعة رقم (auto-increments)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" -msgstr "" +msgstr "إرفاق إلى نموذج على طباعة" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" -msgstr "" +msgstr "حفظ تقرير مخرج بصفته مرفق مقابل مرتبط نموذج نسخة عند الطباعة" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" -msgstr "" - -#: report/models.py:287 -msgid "Pattern for generating filenames" -msgstr "" +msgstr "اسم الملف نمط" #: report/models.py:292 +msgid "Pattern for generating filenames" +msgstr "نمط لـ جارٍ الإنشاء filenames" + +#: report/models.py:297 msgid "Template is enabled" -msgstr "" +msgstr "قالب هو مفعّل" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" -msgstr "" +msgstr "هدف نموذج نوع لـ قالب" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" -msgstr "" +msgstr "مرشحات" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" -msgstr "" +msgstr "قالب استعلام مرشحات (comma-separated قائمة لـ key=value pairs)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" -msgstr "" +msgstr "قالب ملف" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" -msgstr "" - -#: report/models.py:393 -msgid "Render report in landscape orientation" -msgstr "" +msgstr "صفحة حجم لـ PDF تقارير" #: report/models.py:398 +msgid "Render report in landscape orientation" +msgstr "Render تقرير في landscape orientation" + +#: report/models.py:403 msgid "Merge" -msgstr "" +msgstr "دمج" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" -msgstr "" +msgstr "Render مفرد تقرير مقابل محدد عناصر" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" -msgstr "" +msgstr "تقرير تم الإنشاء من قالب {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" -msgstr "" +msgstr "قالب syntax خطأ" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" -msgstr "" +msgstr "خطأ في عرض تقرير" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" -msgstr "" +msgstr "خطأ في جارٍ الإنشاء تقرير" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" -msgstr "" +msgstr "خطأ في merging تقرير مخرجات" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" -msgstr "" +msgstr "ملصق width، محدد في mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" -msgstr "" +msgstr "ملصق height، محدد في mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" -msgstr "" +msgstr "خطأ في الطباعة ملصقات" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" -msgstr "" +msgstr "مقتطف" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" -msgstr "" - -#: report/models.py:855 -msgid "Snippet file description" -msgstr "" +msgstr "تقرير مقتطف ملف" #: report/models.py:873 +msgid "Snippet file description" +msgstr "مقتطف ملف وصف" + +#: report/models.py:891 msgid "Asset" -msgstr "" +msgstr "أصل" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" -msgstr "" +msgstr "تقرير أصل ملف" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" -msgstr "" +msgstr "أصل ملف وصف" #: report/serializers.py:37 msgid "User must be authenticated to save report templates" -msgstr "" +msgstr "يجب أن يكون المستخدم authenticated إلى حفظ تقرير قوالب" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" -msgstr "" +msgstr "تحديد تقرير قالب" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" -msgstr "" - -#: report/serializers.py:159 -msgid "Select label template" -msgstr "" +msgstr "قائمة لـ عنصر أساسي keys إلى تضمين في ال تقرير" #: report/serializers.py:167 -msgid "Printing Plugin" -msgstr "" +msgid "Select label template" +msgstr "تحديد ملصق قالب" -#: report/serializers.py:168 +#: report/serializers.py:175 +msgid "Printing Plugin" +msgstr "الطباعة إضافة" + +#: report/serializers.py:176 msgid "Select plugin to use for label printing" -msgstr "" +msgstr "تحديد إضافة إلى استخدام لـ ملصق الطباعة" #: report/templates/label/part_label.html:31 #: report/templates/label/stockitem_qr.html:21 #: report/templates/label/stocklocation_qr.html:20 msgid "QR Code" -msgstr "" +msgstr "QR رمز" #: report/templates/label/part_label_code128.html:31 #: report/templates/label/stocklocation_qr_and_text.html:31 msgid "QR code" -msgstr "" +msgstr "QR رمز" #: report/templates/report/inventree_bill_of_materials_report.html:100 msgid "Bill of Materials" -msgstr "" +msgstr "قائمة المواد" #: report/templates/report/inventree_bill_of_materials_report.html:133 msgid "Materials needed" @@ -8338,916 +8818,1025 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" -msgstr "" - -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" +msgstr "صنف صورة" #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" -msgstr "" +msgstr "مطلوب لـ" #: report/templates/report/inventree_build_order_report.html:152 msgid "Issued By" -msgstr "" +msgstr "مصروف حسب" #: report/templates/report/inventree_purchase_order_report.html:15 msgid "Supplier was deleted" -msgstr "" +msgstr "مورد كان تم الحذف" #: report/templates/report/inventree_purchase_order_report.html:22 msgid "Order Details" -msgstr "" +msgstr "تفاصيل الطلب" #: report/templates/report/inventree_purchase_order_report.html:37 #: report/templates/report/inventree_sales_order_report.html:30 msgid "Unit Price" -msgstr "" +msgstr "سعر الوحدة" #: report/templates/report/inventree_purchase_order_report.html:62 #: report/templates/report/inventree_return_order_report.html:48 #: report/templates/report/inventree_sales_order_report.html:55 msgid "Extra Line Items" -msgstr "" +msgstr "إضافي البنود" #: report/templates/report/inventree_purchase_order_report.html:79 #: report/templates/report/inventree_sales_order_report.html:72 msgid "Total" -msgstr "" +msgstr "الإجمالي" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" -msgstr "" +msgstr "الرقم التسلسلي" #: report/templates/report/inventree_sales_order_shipment_report.html:23 msgid "Allocations" -msgstr "" +msgstr "تخصيصات" #: report/templates/report/inventree_sales_order_shipment_report.html:47 #: templates/email/stale_stock_notification.html:20 msgid "Batch" -msgstr "" +msgstr "دفعة" #: report/templates/report/inventree_stock_location_report.html:97 msgid "Stock location items" -msgstr "" +msgstr "موقع المخزون عناصر" #: report/templates/report/inventree_stock_report_merge.html:21 #: report/templates/report/inventree_test_report.html:21 msgid "Stock Item Test Report" -msgstr "" +msgstr "عنصر المخزون اختبار تقرير" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" -msgstr "" +msgstr "مثبت عناصر" #: report/templates/report/inventree_stock_report_merge.html:111 #: report/templates/report/inventree_test_report.html:167 msgid "Serial" -msgstr "" +msgstr "تسلسلي" #: report/templates/report/inventree_test_report.html:97 msgid "Test Results" -msgstr "" +msgstr "اختبار نتائج" #: report/templates/report/inventree_test_report.html:102 msgid "Test" -msgstr "" +msgstr "اختبار" #: report/templates/report/inventree_test_report.html:129 msgid "Pass" -msgstr "" +msgstr "نجاح" #: report/templates/report/inventree_test_report.html:131 msgid "Fail" -msgstr "" +msgstr "فشل" #: report/templates/report/inventree_test_report.html:138 msgid "No result (required)" -msgstr "" +msgstr "لا نتيجة (مطلوب)" #: report/templates/report/inventree_test_report.html:140 msgid "No result" -msgstr "" +msgstr "لا نتيجة" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "محوّل" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" -msgstr "" +msgstr "غير صالح media ملف مسار" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" -msgstr "" +msgstr "غير صالح static ملف مسار" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" -msgstr "" +msgstr "أصل ملف غير تم العثور" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" -msgstr "" +msgstr "صورة ملف غير تم العثور" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" -msgstr "" +msgstr "لا صورة ملف محدد" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" -msgstr "" +msgstr "part_image وسم يتطلب صنف نسخة" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" -msgstr "" +msgstr "company_image وسم يتطلب شركة نسخة" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" -msgstr "" +msgstr "تصفية حسب موقع depth" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" -msgstr "" +msgstr "تصفية حسب top-level مواقع" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" -msgstr "" +msgstr "تضمين sub-locations في filtered نتائج" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" -msgstr "" +msgstr "الأصل موقع" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" -msgstr "" +msgstr "تصفية حسب الأصل موقع" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" -msgstr "" +msgstr "صنف اسم (case insensitive)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" -msgstr "" +msgstr "صنف اسم يحتوي (case insensitive)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" -msgstr "" +msgstr "صنف اسم (تعبير نمطي)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" -msgstr "" +msgstr "صنف IPN (case insensitive)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" -msgstr "" +msgstr "صنف IPN يحتوي (case insensitive)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" -msgstr "" +msgstr "صنف IPN (تعبير نمطي)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" -msgstr "" +msgstr "أدنى مخزون" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" -msgstr "" +msgstr "أقصى مخزون" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" -msgstr "" +msgstr "حالة رمز" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" -msgstr "" +msgstr "خارجي موقع" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" -msgstr "" +msgstr "مستهلك حسب أمر الإنتاج" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" -msgstr "" +msgstr "مثبت في أخرى عنصر المخزون" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" -msgstr "" +msgstr "صنف Tree" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" -msgstr "" +msgstr "تم التحديث قبل" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" -msgstr "" +msgstr "تم التحديث بعد" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" -msgstr "" +msgstr "جرد المخزون قبل" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" -msgstr "" +msgstr "جرد المخزون بعد" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "تاريخ لديه جرد المخزون" + +#: stock/api.py:1001 msgid "Expiry date before" -msgstr "" +msgstr "انتهاء تاريخ قبل" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" -msgstr "" +msgstr "انتهاء تاريخ بعد" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" -msgstr "" +msgstr "قديم" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" -msgstr "" +msgstr "Cascade مواقع" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" -msgstr "" +msgstr "إذا صحيح، تضمين عناصر في فرعي مواقع لـ ال معطى موقع" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" -msgstr "" +msgstr "تصفية حسب numeric موقع ID أو ال literal 'null'" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" -msgstr "" +msgstr "الكمية مطلوب" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" -msgstr "" +msgstr "يجب أن يكون صالح صنف مورد" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" -msgstr "" +msgstr "ال معطى صنف المورد يقوم غير موجود" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" -msgstr "" +msgstr "ال صنف المورد لديه حزمة حجم محدد، but flag use_pack_size غير تعيين" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" -msgstr "" +msgstr "الأرقام التسلسلية لا يمكن يكون مورد لـ non-trackable صنف" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" -msgstr "" +msgstr "تضمين مثبت" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" -msgstr "" +msgstr "إذا صحيح، تضمين اختبار نتائج لـ عناصر مثبت underneath ال معطى عنصر المخزون" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" -msgstr "" +msgstr "تصفية حسب numeric عنصر المخزون ID" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" -msgstr "" +msgstr "عنصر المخزون مع ID {id} يقوم غير موجود" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" -msgstr "" +msgstr "تضمين صنف متغيرات" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" -msgstr "" +msgstr "تاريخ بعد" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" -msgstr "" +msgstr "تاريخ قبل" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" -msgstr "" +msgstr "موقع المخزون نوع" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" -msgstr "" +msgstr "موقع المخزون أنواع" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" -msgstr "" +msgstr "افتراضي أيقونة لـ الكل مواقع ذلك لديه لا أيقونة تعيين (اختياري)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" -msgstr "" +msgstr "موقع مخزون" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" -msgstr "" +msgstr "مواقع المخزون" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" -msgstr "" +msgstr "مالك" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" -msgstr "" +msgstr "تحديد مالك" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." -msgstr "" +msgstr "عناصر المخزون قد غير يكون directly located إلى هيكلي مواقع المخزون، but قد يكون located إلى فرعي مواقع." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" -msgstr "" +msgstr "خارجي" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" -msgstr "" +msgstr "هذا هو خارجي موقع المخزون" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" -msgstr "" +msgstr "موقع نوع" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" -msgstr "" +msgstr "موقع المخزون نوع لـ هذا موقع" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" -msgstr "" +msgstr "أنت لا يمكن make هذا موقع المخزون هيكلي because some عناصر المخزون هي بالفعل located إلى هو!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "Oldest مخزون أول (FIFO)" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "Newest مخزون أول (LIFO)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "Smallest كمية أول" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "Largest كمية أول" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "Soonest انتهاء تاريخ أول" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" -msgstr "" +msgstr "مسلسل عناصر المخزون لا يمكن يكون تم الحذف" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" -msgstr "" +msgstr "{field} يقوم غير موجود" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" -msgstr "" +msgstr "يجب أن يكون الصنف محدد" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" -msgstr "" +msgstr "عناصر المخزون لا يمكن يكون located إلى هيكلي مواقع المخزون!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "تحرير لـ الأرقام التسلسلية هو غير مسموح - هذا عنصر لديه بالفعل تم مسند الرقم التسلسلي" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" -msgstr "" +msgstr "عنصر المخزون لا يمكن يكون تم الإنشاء لـ افتراضي أصناف" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" -msgstr "" +msgstr "يجب أن يكون صنف نوع ('{self.supplier_part.part}') {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" -msgstr "" +msgstr "يجب أن يكون الكمية 1 لـ عنصر مع الرقم التسلسلي" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" -msgstr "" +msgstr "الرقم التسلسلي لا يمكن يكون تعيين إذا كمية أكبر من 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" -msgstr "" +msgstr "عنصر لا يمكن belong إلى itself" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" -msgstr "" - -#: stock/models.py:1032 -msgid "Build reference does not point to the same part object" -msgstr "" - -#: stock/models.py:1046 -msgid "Parent Stock Item" -msgstr "" - -#: stock/models.py:1058 -msgid "Base part" -msgstr "" - -#: stock/models.py:1068 -msgid "Select a matching supplier part for this stock item" -msgstr "" - -#: stock/models.py:1080 -msgid "Where is this stock item located?" -msgstr "" - -#: stock/models.py:1088 stock/serializers.py:1682 -msgid "Packaging this stock item is stored in" -msgstr "" - -#: stock/models.py:1094 -msgid "Installed In" -msgstr "" - -#: stock/models.py:1099 -msgid "Is this item installed in another item?" -msgstr "" - -#: stock/models.py:1118 -msgid "Serial number for this item" -msgstr "" - -#: stock/models.py:1135 stock/serializers.py:1667 -msgid "Batch code for this stock item" -msgstr "" +msgstr "عنصر يجب لديه إنتاج مرجع إذا is_building=True" #: stock/models.py:1140 -msgid "Stock Quantity" -msgstr "" +msgid "Build reference does not point to the same part object" +msgstr "إنتاج مرجع يقوم غير نقطة إلى ال نفس صنف كائن" -#: stock/models.py:1150 -msgid "Source Build" -msgstr "" +#: stock/models.py:1154 +msgid "Parent Stock Item" +msgstr "الأصل عنصر المخزون" -#: stock/models.py:1153 -msgid "Build for this stock item" -msgstr "" - -#: stock/models.py:1160 -msgid "Consumed By" -msgstr "" - -#: stock/models.py:1163 -msgid "Build order which consumed this stock item" -msgstr "" - -#: stock/models.py:1172 -msgid "Source Purchase Order" -msgstr "" +#: stock/models.py:1166 +msgid "Base part" +msgstr "أساس صنف" #: stock/models.py:1176 +msgid "Select a matching supplier part for this stock item" +msgstr "تحديد مطابق صنف المورد لـ هذا عنصر المخزون" + +#: stock/models.py:1188 +msgid "Where is this stock item located?" +msgstr "حيث هو هذا عنصر المخزون located؟" + +#: stock/models.py:1196 stock/serializers.py:1936 +msgid "Packaging this stock item is stored in" +msgstr "تعبئة هذا عنصر المخزون هو مخزن في" + +#: stock/models.py:1202 +msgid "Installed In" +msgstr "مثبت في" + +#: stock/models.py:1207 +msgid "Is this item installed in another item?" +msgstr "هو هذا عنصر مثبت في آخر عنصر؟" + +#: stock/models.py:1226 +msgid "Serial number for this item" +msgstr "الرقم التسلسلي لـ هذا عنصر" + +#: stock/models.py:1243 stock/serializers.py:1921 +msgid "Batch code for this stock item" +msgstr "رمز الدفعة لـ هذا عنصر المخزون" + +#: stock/models.py:1248 +msgid "Stock Quantity" +msgstr "كمية المخزون" + +#: stock/models.py:1258 +msgid "Source Build" +msgstr "المصدر إنتاج" + +#: stock/models.py:1261 +msgid "Build for this stock item" +msgstr "إنتاج لـ هذا عنصر المخزون" + +#: stock/models.py:1268 +msgid "Consumed By" +msgstr "مستهلك حسب" + +#: stock/models.py:1271 +msgid "Build order which consumed this stock item" +msgstr "أمر الإنتاج الذي مستهلك هذا عنصر المخزون" + +#: stock/models.py:1280 +msgid "Source Purchase Order" +msgstr "المصدر طلب الشراء" + +#: stock/models.py:1284 msgid "Purchase order for this stock item" -msgstr "" +msgstr "طلب الشراء لـ هذا عنصر المخزون" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" -msgstr "" +msgstr "الوجهة طلب البيع" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" -msgstr "" +msgstr "تاريخ انتهاء تاريخ لـ عنصر المخزون. مخزون سوف يكون considered منتهي بعد هذا" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "تاريخ ذلك هذا عنصر المخزون كان تم الإنشاء" + +#: stock/models.py:1326 msgid "Delete on deplete" -msgstr "" +msgstr "حذف على deplete" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" -msgstr "" +msgstr "حذف هذا عنصر المخزون عند مخزون هو نافد" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" -msgstr "" +msgstr "مفرد وحدة سعر الشراء عند وقت لـ شراء" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" -msgstr "" +msgstr "Converted إلى صنف" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" +msgstr "كمية يتجاوز متاح مخزون" + +#: stock/models.py:1903 +msgid "Invalid quantity value" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "لا يمكن إسناد مخزون إلى هيكلي موقع" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" -msgstr "" +msgstr "صنف هو غير تعيين بصفته قابل للتتبع" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" -msgstr "" +msgstr "يجب أن يكون الكمية عدد صحيح" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" -msgstr "" +msgstr "كمية يجب غير تجاوز متاح مخزون كمية ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" -msgstr "" +msgstr "يجب أن يكون الأرقام التسلسلية مقدم بصفته قائمة" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" -msgstr "" +msgstr "كمية يقوم غير مطابقة الأرقام التسلسلية" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" -msgstr "" +msgstr "اختبار قالب يقوم غير موجود" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" -msgstr "" +msgstr "عنصر المخزون لديه تم مسند إلى طلب البيع" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" -msgstr "" +msgstr "عنصر المخزون هو مثبت في آخر عنصر" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" -msgstr "" +msgstr "عنصر المخزون يحتوي أخرى عناصر" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" -msgstr "" +msgstr "عنصر المخزون لديه تم مسند إلى عميل" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" -msgstr "" +msgstr "عنصر المخزون هو حاليًا في الإنتاج" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" -msgstr "" +msgstr "مسلسل مخزون لا يمكن يكون merged" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" -msgstr "" +msgstr "نسخ عناصر المخزون" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" -msgstr "" +msgstr "عناصر المخزون يجب refer إلى ال نفس صنف" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" -msgstr "" +msgstr "عناصر المخزون يجب refer إلى ال نفس صنف المورد" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" -msgstr "" +msgstr "مخزون حالة رموز يجب مطابقة" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" -msgstr "" +msgstr "StockItem لا يمكن يكون moved بصفته هو هو غير في مخزون" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" -msgstr "" +msgstr "عنصر المخزون تتبع" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" -msgstr "" +msgstr "سجل ملاحظات" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" -msgstr "" +msgstr "عنصر المخزون نتيجة الاختبار" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" -msgstr "" +msgstr "يجب أن يكون القيمة مقدم لـ هذا اختبار" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" -msgstr "" +msgstr "يجب أن يكون المرفق تم الرفع لـ هذا اختبار" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" -msgstr "" +msgstr "غير صالح قيمة لـ هذا اختبار" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" -msgstr "" +msgstr "نتيجة الاختبار" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" -msgstr "" +msgstr "اختبار مخرج قيمة" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" -msgstr "" +msgstr "نتيجة الاختبار مرفق" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" -msgstr "" +msgstr "اختبار ملاحظات" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" -msgstr "" +msgstr "اختبار station" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" -msgstr "" +msgstr "ال معرف لـ ال اختبار station حيث ال اختبار كان performed" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" -msgstr "" +msgstr "بدأ" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" -msgstr "" +msgstr "ال طابع زمني لـ ال اختبار بدء" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" -msgstr "" +msgstr "ال طابع زمني لـ ال اختبار finish" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" -msgstr "" +msgstr "تم الإنشاء رمز الدفعة" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" -msgstr "" +msgstr "تحديد أمر الإنتاج" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" -msgstr "" +msgstr "تحديد عنصر المخزون إلى إنشاء رمز الدفعة لـ" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" -msgstr "" +msgstr "تحديد موقع إلى إنشاء رمز الدفعة لـ" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" -msgstr "" +msgstr "تحديد صنف إلى إنشاء رمز الدفعة لـ" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" -msgstr "" +msgstr "تحديد طلب الشراء" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" -msgstr "" +msgstr "إدخال كمية لـ رمز الدفعة" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" -msgstr "" +msgstr "تم الإنشاء الرقم التسلسلي" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" -msgstr "" +msgstr "تحديد صنف إلى إنشاء الرقم التسلسلي لـ" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" -msgstr "" +msgstr "كمية الأرقام التسلسلية إلى إنشاء" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" -msgstr "" +msgstr "اختبار قالب لـ هذا نتيجة" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" -msgstr "" +msgstr "لا يوجد اختبار تم العثور لـ هذا صنف مطابق" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" -msgstr "" +msgstr "يجب أن يكون قالب ID أو اختبار اسم مقدم" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" -msgstr "" +msgstr "ال اختبار finished وقت لا يمكن يكون earlier من ال اختبار بدأ وقت" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" -msgstr "" +msgstr "الأصل عنصر" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" -msgstr "" +msgstr "الأصل عنصر المخزون" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" -msgstr "" +msgstr "استخدام حزمة حجم عند إضافة: ال كمية محدد هو ال رقم لـ packs" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" -msgstr "" +msgstr "استخدام حزمة حجم" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" -msgstr "" +msgstr "إدخال الأرقام التسلسلية لـ جديد عناصر" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" -msgstr "" +msgstr "صنف المورد رقم" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" -msgstr "" +msgstr "منتهي" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" -msgstr "" +msgstr "فرعي عناصر" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" -msgstr "" +msgstr "تتبع عناصر" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" -msgstr "" +msgstr "سعر الشراء لـ هذا عنصر المخزون، per وحدة أو حزمة" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" -msgstr "" +msgstr "إدخال رقم لـ عناصر المخزون إلى ترقيم تسلسلي" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" -msgstr "" +msgstr "لا عنصر المخزون مقدم" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" -msgstr "" +msgstr "كمية يجب غير تجاوز متاح مخزون كمية ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" -msgstr "" +msgstr "الوجهة موقع المخزون" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" -msgstr "" +msgstr "الأرقام التسلسلية لا يمكن يكون مسند إلى هذا صنف" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" -msgstr "" +msgstr "الأرقام التسلسلية بالفعل موجود" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" -msgstr "" +msgstr "تحديد عنصر المخزون إلى تثبيت" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" -msgstr "" - -#: stock/serializers.py:838 -msgid "Enter the quantity of items to install" -msgstr "" - -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 -msgid "Add transaction note (optional)" -msgstr "" +msgstr "كمية إلى تثبيت" #: stock/serializers.py:851 +msgid "Enter the quantity of items to install" +msgstr "إدخال ال كمية لـ عناصر إلى تثبيت" + +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 +msgid "Add transaction note (optional)" +msgstr "إضافة transaction ملاحظة (اختياري)" + +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" -msgstr "" +msgstr "يجب أن يكون كمية إلى تثبيت عند أقل 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" -msgstr "" - -#: stock/serializers.py:870 -msgid "Selected part is not in the Bill of Materials" -msgstr "" +msgstr "عنصر المخزون هو غير متاح" #: stock/serializers.py:883 +msgid "Selected part is not in the Bill of Materials" +msgstr "محدد صنف هو غير في ال قائمة المواد" + +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" -msgstr "" +msgstr "كمية كمية إلى تثبيت يجب غير تجاوز متاح" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" -msgstr "" +msgstr "الوجهة موقع لـ غير مثبت عنصر" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" +msgstr "عنصر المخزون حالة رمز" + +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "تحديد صنف إلى تحويل عنصر المخزون إلى" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "محدد صنف هو غير صالح خيار لـ conversion" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "لا يمكن تحويل عنصر المخزون مع مسند SupplierPart" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" -msgstr "" +msgstr "تحديد حالة عناصر المخزون إلى تغيير" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" -msgstr "" +msgstr "لا عناصر المخزون محدد" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" -msgstr "" +msgstr "مواقع فرعية" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "حذف عناصر المخزون" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "حذف الكل عناصر المخزون contained ضمن هذا موقع" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "حذف مواقع فرعية" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "حذف الكل sub-locations contained ضمن هذا موقع" + +#: stock/serializers.py:1477 msgid "Parent stock location" -msgstr "" +msgstr "الأصل موقع المخزون" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" -msgstr "" +msgstr "يجب أن يكون الصنف قابل للبيع" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" -msgstr "" +msgstr "عنصر هو مخصص إلى طلب البيع" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "عنصر هو مخصص إلى طلب التحويل" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" -msgstr "" +msgstr "عنصر هو مخصص إلى أمر الإنتاج" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" -msgstr "" +msgstr "عميل إلى إسناد عناصر المخزون" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" -msgstr "" +msgstr "محدد شركة هو غير عميل" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" -msgstr "" +msgstr "مخزون assignment ملاحظات" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" -msgstr "" +msgstr "يجب أن يكون قائمة لـ عناصر المخزون مقدم" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" -msgstr "" +msgstr "مخزون merging ملاحظات" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" -msgstr "" +msgstr "السماح mismatched موردون" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" -msgstr "" +msgstr "السماح عناصر المخزون مع مختلف أصناف المورد إلى يكون merged" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" -msgstr "" +msgstr "حالة السماح mismatched" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" -msgstr "" +msgstr "السماح عناصر المخزون مع مختلف حالة رموز إلى يكون merged" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" -msgstr "" +msgstr "يجب أن يكون عند أقل two عناصر المخزون مقدم" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" -msgstr "" +msgstr "لا تغيير" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" -msgstr "" +msgstr "StockItem أساسي مفتاح قيمة" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" -msgstr "" +msgstr "عنصر المخزون هو غير في مخزون" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" -msgstr "" +msgstr "عنصر المخزون هو بالفعل في مخزون" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" -msgstr "" +msgstr "كمية يجب غير يكون سالب" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" -msgstr "" +msgstr "دمج إلى موجود مخزون" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "دمج هذا عنصر إلى موجود مخزون عند ال الوجهة إذا possible" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "مخزون transaction ملاحظات" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "تعيين موقع المخزون لـ counted عناصر (اختياري)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" -msgstr "" +msgstr "دمج مرتجع عناصر إلى موجود عناصر المخزون إذا possible" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" -msgstr "" +msgstr "Next الرقم التسلسلي" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" -msgstr "" +msgstr "Previous الرقم التسلسلي" #: stock/status_codes.py:11 msgid "OK" -msgstr "" +msgstr "موافق" #: stock/status_codes.py:12 msgid "Attention needed" @@ -9263,7 +9852,7 @@ msgstr "" #: stock/status_codes.py:15 msgid "Rejected" -msgstr "" +msgstr "مرفوض" #: stock/status_codes.py:19 msgid "Quarantined" @@ -9271,189 +9860,197 @@ msgstr "" #: stock/status_codes.py:44 msgid "Legacy stock tracking entry" -msgstr "" +msgstr "Legacy مخزون تتبع سجل" #: stock/status_codes.py:46 msgid "Stock item created" -msgstr "" +msgstr "عنصر المخزون تم الإنشاء" #: stock/status_codes.py:49 msgid "Edited stock item" -msgstr "" +msgstr "تم التحرير عنصر المخزون" #: stock/status_codes.py:50 msgid "Assigned serial number" -msgstr "" +msgstr "مسند الرقم التسلسلي" #: stock/status_codes.py:53 msgid "Stock counted" -msgstr "" +msgstr "مخزون counted" #: stock/status_codes.py:54 msgid "Stock manually added" -msgstr "" +msgstr "مخزون يدويًا تمت الإضافة" #: stock/status_codes.py:55 msgid "Stock manually removed" -msgstr "" +msgstr "مخزون يدويًا تمت الإزالة" #: stock/status_codes.py:56 msgid "Serialized stock items" -msgstr "" +msgstr "مسلسل عناصر المخزون" #: stock/status_codes.py:58 msgid "Returned to stock" -msgstr "" +msgstr "مرتجع إلى مخزون" #: stock/status_codes.py:61 msgid "Location changed" -msgstr "" +msgstr "موقع تم التغيير" #: stock/status_codes.py:62 msgid "Stock updated" -msgstr "" +msgstr "مخزون تم التحديث" #: stock/status_codes.py:65 msgid "Installed into assembly" -msgstr "" +msgstr "مثبت إلى تجميع" #: stock/status_codes.py:66 msgid "Removed from assembly" -msgstr "" +msgstr "تمت الإزالة من تجميع" #: stock/status_codes.py:68 msgid "Installed component item" -msgstr "" +msgstr "مثبت مكوّن عنصر" #: stock/status_codes.py:69 msgid "Removed component item" -msgstr "" +msgstr "تمت الإزالة مكوّن عنصر" #: stock/status_codes.py:72 msgid "Split from parent item" -msgstr "" +msgstr "تقسيم من الأصل عنصر" #: stock/status_codes.py:73 msgid "Split child item" -msgstr "" +msgstr "تقسيم فرعي عنصر" #: stock/status_codes.py:76 msgid "Merged stock items" -msgstr "" +msgstr "Merged عناصر المخزون" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "Converted إلى متغير" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "أمر الإنتاج مخرج تم الإنشاء" + +#: stock/status_codes.py:87 msgid "Build order output completed" -msgstr "" - -#: stock/status_codes.py:84 -msgid "Build order output rejected" -msgstr "" - -#: stock/status_codes.py:85 -msgid "Consumed by build order" -msgstr "" +msgstr "أمر الإنتاج مخرج مكتمل" #: stock/status_codes.py:88 +msgid "Build order output rejected" +msgstr "أمر الإنتاج مخرج مرفوض" + +#: stock/status_codes.py:89 +msgid "Consumed by build order" +msgstr "مستهلك حسب أمر الإنتاج" + +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" -msgstr "" +msgstr "مشحون مقابل طلب البيع" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" -msgstr "" - -#: stock/status_codes.py:94 -msgid "Returned against Return Order" -msgstr "" - -#: stock/status_codes.py:97 -msgid "Sent to customer" -msgstr "" +msgstr "مستلم مقابل طلب الشراء" #: stock/status_codes.py:98 +msgid "Returned against Return Order" +msgstr "مرتجع مقابل طلب الإرجاع" + +#: stock/status_codes.py:101 +msgid "Sent to customer" +msgstr "تم الإرسال إلى عميل" + +#: stock/status_codes.py:102 msgid "Returned from customer" -msgstr "" +msgstr "مرتجع من عميل" #: templates/403.html:6 templates/403.html:10 templates/403_csrf.html:7 msgid "Permission Denied" -msgstr "" +msgstr "صلاحية Denied" #: templates/403.html:11 msgid "You do not have permission to view this page." -msgstr "" +msgstr "أنت تنفيذ غير لديه صلاحية إلى عرض هذا صفحة." #: templates/403_csrf.html:11 msgid "Authentication Failure" -msgstr "" +msgstr "مصادقة Failure" #: templates/403_csrf.html:12 msgid "You have been logged out from InvenTree." -msgstr "" +msgstr "أنت لديه تم مسجل خارج من InvenTree." #: templates/404.html:6 templates/404.html:10 msgid "Page Not Found" -msgstr "" +msgstr "صفحة غير تم العثور" #: templates/404.html:11 msgid "The requested page does not exist" -msgstr "" +msgstr "ال requested صفحة يقوم غير موجود" #: templates/500.html:6 templates/500.html:10 msgid "Internal Server Error" -msgstr "" +msgstr "داخلي خادم خطأ" #: templates/500.html:11 #, python-format msgid "The %(inventree_title)s server raised an internal error" -msgstr "" +msgstr "ال %(inventree_title)s خادم raised داخلي خطأ" #: templates/500.html:12 msgid "Refer to the error log in the admin interface for further details" -msgstr "" +msgstr "تفاصيل Refer إلى ال خطأ سجل في ال مسؤول واجهة لـ further" #: templates/503.html:11 templates/503.html:15 msgid "Site is in Maintenance" -msgstr "" +msgstr "موقع هو في Maintenance" #: templates/503.html:17 msgid "The site is currently in maintenance and should be up again soon!" -msgstr "" +msgstr "ال موقع هو حاليًا في maintenance و ينبغي يكون أعلى مرة أخرى soon!" #: templates/base.html:51 msgid "Server Restart Required" -msgstr "" +msgstr "خادم إعادة تشغيل مطلوب" #: templates/base.html:54 msgid "A configuration option has been changed which requires a server restart" -msgstr "" +msgstr "تهيئة خيار لديه تم تم التغيير الذي يتطلب خادم إعادة تشغيل" #: templates/base.html:54 templates/base.html:64 msgid "Contact your system administrator for further information" -msgstr "" +msgstr "جهة اتصال الخاص بك نظام مسؤول النظام لـ further معلومات" #: templates/base.html:61 msgid "Pending Database Migrations" -msgstr "" +msgstr "قيد الانتظار قاعدة بيانات ترحيلات" #: templates/base.html:64 msgid "There are pending database migrations which require attention" -msgstr "" +msgstr "هناك هي قيد الانتظار قاعدة بيانات ترحيلات الذي طلب attention" #: templates/config_error.html:6 templates/config_error.html:10 msgid "Configuration Error" -msgstr "" +msgstr "تهيئة خطأ" #: templates/config_error.html:11 #, python-format msgid "The %(inventree_title)s server raised a configuration error" -msgstr "" +msgstr "ال %(inventree_title)s خادم raised تهيئة خطأ" #: templates/email/build_order_completed.html:9 #: templates/email/canceled_order_assigned.html:9 @@ -9465,361 +10062,365 @@ msgstr "" #: templates/email/purchase_order_received.html:9 #: templates/email/return_order_received.html:9 msgid "Click on the following link to view this order" -msgstr "" +msgstr "انقر على ال التالي رابط إلى عرض هذا طلب" #: templates/email/build_order_required_stock.html:7 msgid "Stock is required for the following build order" -msgstr "" +msgstr "مخزون هو مطلوب لـ ال التالي أمر الإنتاج" #: templates/email/build_order_required_stock.html:8 #, python-format msgid "Build order %(build)s - building %(quantity)s x %(part)s" -msgstr "" +msgstr "أمر الإنتاج %(build)s - building %(quantity)s x %(part)s" #: templates/email/build_order_required_stock.html:10 msgid "Click on the following link to view this build order" -msgstr "" +msgstr "انقر على ال التالي رابط إلى عرض هذا أمر الإنتاج" #: templates/email/build_order_required_stock.html:14 msgid "The following parts are low on required stock" -msgstr "" +msgstr "ال التالي أصناف هي منخفض على مطلوب مخزون" #: templates/email/build_order_required_stock.html:18 msgid "Required Quantity" -msgstr "" +msgstr "كمية مطلوب" #: templates/email/build_order_required_stock.html:38 #: templates/email/low_stock_notification.html:30 msgid "You are receiving this email because you are subscribed to notifications for this part " -msgstr "" +msgstr "أنت هي receiving هذا بريد إلكتروني because أنت هي مشتركة إلى إشعارات لـ هذا صنف" #: templates/email/low_stock_notification.html:9 #: templates/email/part_event_notification.html:9 msgid "Click on the following link to view this part" -msgstr "" +msgstr "انقر على ال التالي رابط إلى عرض هذا صنف" #: templates/email/low_stock_notification.html:18 #: templates/email/part_event_notification.html:19 msgid "Minimum Quantity" -msgstr "" +msgstr "كمية أدنى" #: templates/email/part_event_notification.html:32 msgid "You are receiving this email because you are subscribed to notifications for this part or a category that it is part of " -msgstr "" +msgstr "أنت هي receiving هذا بريد إلكتروني because أنت هي مشتركة إلى إشعارات لـ هذا صنف أو فئة ذلك هو هو صنف لـ" #: templates/email/stale_stock_notification.html:10 msgid "The following stock items are approaching their expiry dates:" -msgstr "" +msgstr "ال التالي عناصر المخزون هي approaching الخاص بهم انتهاء تواريخ:" #: templates/email/stale_stock_notification.html:23 msgid "Days Until Expiry" -msgstr "" +msgstr "أيام حتى انتهاء" #: templates/email/stale_stock_notification.html:57 msgid "You are receiving this email because you are subscribed to notifications for these parts" -msgstr "" +msgstr "أنت هي receiving هذا بريد إلكتروني because أنت هي مشتركة إلى إشعارات لـ هذه أصناف" #: users/admin.py:101 msgid "Users" -msgstr "" +msgstr "المستخدمون" #: users/admin.py:102 msgid "Select which users are assigned to this group" -msgstr "" +msgstr "تحديد الذي مستخدمون هي مسند إلى هذا مجموعة" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" -msgstr "" +msgstr "الصلاحيات" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" -msgstr "" +msgstr "Important تواريخ" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" -msgstr "" +msgstr "رمز وصول لديه تم revoked" #: users/authentication.py:33 msgid "Token has expired" -msgstr "" +msgstr "رمز وصول لديه منتهي" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" -msgstr "" +msgstr "واجهة API رمز وصول" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" -msgstr "" +msgstr "واجهة API رموز وصول" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" -msgstr "" +msgstr "رمز وصول اسم" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" -msgstr "" +msgstr "مخصص رمز وصول اسم" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" -msgstr "" +msgstr "تاريخ رمز وصول انتهاء" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" -msgstr "" +msgstr "آخر Seen" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" -msgstr "" +msgstr "آخر وقت ال رمز وصول كان مستخدم" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" -msgstr "" +msgstr "صلاحية تعيين" -#: users/models.py:240 +#: users/models.py:238 msgid "View" -msgstr "" +msgstr "عرض" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" -msgstr "" +msgstr "صلاحية إلى عرض عناصر" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" -msgstr "" +msgstr "إضافة" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" -msgstr "" +msgstr "صلاحية إلى إضافة عناصر" + +#: users/models.py:246 +msgid "Change" +msgstr "تغيير" #: users/models.py:248 -msgid "Change" -msgstr "" - -#: users/models.py:250 msgid "Permissions to edit items" -msgstr "" +msgstr "صلاحيات إلى تعديل عناصر" + +#: users/models.py:252 +msgid "Delete" +msgstr "حذف" #: users/models.py:254 -msgid "Delete" -msgstr "" - -#: users/models.py:256 msgid "Permission to delete items" -msgstr "" +msgstr "صلاحية إلى حذف عناصر" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" -msgstr "" +msgstr "داخلي" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" -msgstr "" +msgstr "اللغة" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" -msgstr "" +msgstr "Preferred لغة لـ ال مستخدم" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" -msgstr "" +msgstr "المظهر" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" -msgstr "" +msgstr "إعدادات لـ ال ويب UI بصفته JSON - تنفيذ غير تعديل يدويًا!" + +#: users/models.py:515 +msgid "Widgets" +msgstr "عناصر واجهة" #: users/models.py:517 -msgid "Widgets" -msgstr "" - -#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" -msgstr "" +msgstr "إعدادات لـ ال لوحة المعلومات عناصر واجهة بصفته JSON - تنفيذ غير تعديل يدويًا!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" -msgstr "" +msgstr "عرض اسم" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" -msgstr "" +msgstr "Chosen عرض اسم لـ ال مستخدم" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" -msgstr "" +msgstr "Main job عنوان أو position" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" -msgstr "" +msgstr "مستخدم حالة رسالة" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" -msgstr "" +msgstr "مستخدم موقع معلومات" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" -msgstr "" +msgstr "مستخدم هو actively باستخدام ال نظام" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" -msgstr "" +msgstr "Preferred جهة اتصال معلومات لـ ال مستخدم" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" -msgstr "" +msgstr "مستخدم نوع" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" -msgstr "" +msgstr "الذي نوع لـ مستخدم هو هذا؟" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" -msgstr "" +msgstr "مستخدمون أساسي organisation/affiliation" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" -msgstr "" +msgstr "أساسي مجموعة" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" -msgstr "" +msgstr "أساسي مجموعة لـ ال مستخدم" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" -msgstr "" +msgstr "مسؤول" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" -msgstr "" - -#: users/ruleset.py:34 -msgid "Purchase Orders" -msgstr "" +msgstr "Bills لـ Material" #: users/ruleset.py:35 -msgid "Sales Orders" -msgstr "" +msgid "Purchase Orders" +msgstr "طلبات الشراء" #: users/ruleset.py:36 +msgid "Sales Orders" +msgstr "طلبات البيع" + +#: users/ruleset.py:37 msgid "Return Orders" -msgstr "" +msgstr "طلبات الإرجاع" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "طلبات التحويل" + +#: users/serializers.py:196 msgid "Username" -msgstr "" +msgstr "اسم المستخدم" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" -msgstr "" +msgstr "أول اسم" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" -msgstr "" +msgstr "أول اسم لـ ال مستخدم" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" -msgstr "" +msgstr "آخر اسم" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" -msgstr "" +msgstr "آخر اسم لـ ال مستخدم" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" -msgstr "" +msgstr "بريد إلكتروني عنوان لـ ال مستخدم" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" -msgstr "" +msgstr "يجب أن يكون المستخدم authenticated" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" -msgstr "" +msgstr "فقط مستخدم فائق يمكن إنشاء رمز وصول لـ آخر مستخدم" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" -msgstr "" +msgstr "مسؤول النظام" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" -msgstr "" +msgstr "يقوم هذا مستخدم لديه administrative صلاحيات" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" -msgstr "" +msgstr "مستخدم فائق" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" -msgstr "" +msgstr "هو هذا مستخدم مستخدم فائق" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" -msgstr "" +msgstr "هو هذا حساب المستخدم نشط" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" -msgstr "" +msgstr "فقط مستخدم فائق يمكن تسوية هذا حقل" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" -msgstr "" +msgstr "كلمة المرور" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" -msgstr "" +msgstr "كلمة المرور لـ ال مستخدم" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" -msgstr "" +msgstr "تجاوز تحذير" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" -msgstr "" +msgstr "تجاوز ال تحذير حول كلمة المرور rules" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" -msgstr "" +msgstr "يقوم هذا مستخدم لديه staff صلاحيات" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" -msgstr "" +msgstr "أنت تنفيذ غير لديه صلاحية إلى إنشاء مستخدمون" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." -msgstr "" +msgstr "الخاص بك حساب لديه تم تم الإنشاء." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" -msgstr "" +msgstr "يرجى استخدام ال كلمة المرور إعادة تعيين دالة إلى تسجيل الدخول" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" -msgstr "" +msgstr "Welcome إلى InvenTree" diff --git a/src/backend/InvenTree/locale/bg/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/bg/LC_MESSAGES/django.po index 66e0d275a0..1b782bc7f0 100644 --- a/src/backend/InvenTree/locale/bg/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/bg/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Bulgarian\n" "Language: bg_BG\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Не е намерена крайна точка на API" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Елементите трябва да се предоставят, като списък" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Потребителя няма нужното разрешение, за да вижда този модел" @@ -65,150 +69,155 @@ msgstr "Потвърждение на електронната поща" msgid "You must type the same email each time." msgstr "Трябва ла въведете една и съща електронна поща." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Въведената основна електронна поща е невалидна." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Въведеният домейн на електронната поща не е утвърден." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Не е зададена стойност" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Преобразуването на {original} в {unit} не беше успешно" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Въведена е недопустима стойност" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Подробности за грешката могат да се намерят в администраторския панел" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Въведи дата" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Бележки" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Значението '{name}' не отговаря на шаблона" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Въведеното значение не отговаря на задължителния шаблон: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Липсва сериен номер" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Повтарящ се сериен номер" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Не са открити серийни номера" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Премахнете HTML маркерите от тази стойност" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Грешка при съединението" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Сървърът отговари с невалиден статусен код" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Възникна изключение" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Сървърът отговори с невалидна стойност за дължината на съдържанието (Content-Length)" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Размерът на изображението е твърде голям" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Сваляното на изображение превиши максималния размер" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Отдалеченият сървър върна празен отговор" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -216,159 +225,203 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Трябва да активирате двойно оторизиране преди да направите, каквото и да е." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "Китайски (опростен)" msgid "Chinese (Traditional)" msgstr "Китайски (традиционен)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Част" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Потребител" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Потребител" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Изпратено" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Изгубен" @@ -5718,1279 +6125,1312 @@ msgstr "Изгубен" msgid "Returned" msgstr "Върнат" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Изпълнява се" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Цялостна наличност" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Място в склада" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Места в склада" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/cs/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/cs/LC_MESSAGES/django.po index 0d7fadec37..d45baf0944 100644 --- a/src/backend/InvenTree/locale/cs/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/cs/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Czech\n" "Language: cs_CZ\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API endpoint nebyl nalezen" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "Seznam položek musí být k dispozici pro hromadnou operaci" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Položky musí být uvedeny jako seznam" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Zadán neplatný seznam položek" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Všechny filtry musí být použity s Pravda" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Zadaným kritériím neodpovídají žádné položky" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Nebyla poskytnuta žádná data" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Toto pole musí být unikátní." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "Položka již neodpovídá zadaným kritériím" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Uživatel nemá právo zobrazit tento model" @@ -65,150 +69,155 @@ msgstr "Potvrzení emailové adresy" msgid "You must type the same email each time." msgstr "Pokaždé musíte zadat stejný email." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Zadaná primární e-mailová adresa je neplatná." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Zadaná e-mailová doména není povolena." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Zadána neplatná jednotka ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Není k dispozici žádná hodnota" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Nelze převést {original} na {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Vyplněno neplatné množství" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "Server se znovu načítá, zkuste to prosím znovu" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Podrobnosti o chybě lze nalézt v panelu administrace" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Zadejte datum" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Neplaté desetinné číslo" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Poznámky" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Hodnota '{name}' neodpovídá formátu vzoru" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Poskytnutá hodnota neodpovídá požadovanému vzoru: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Nelze serializovat více než 1000 položek najednou" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Nevyplněné výrobní číslo" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Duplicitní výrobní číslo" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Neplatná skupina: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Rozsah skupiny {group} překračuje povolené množství ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Nenalezena žádná výrobní čísla" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Počet jedinečných sériových čísel ({n}) musí odpovídat množství ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Odstranit HTML tagy z této hodnoty" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Data obsahují zakázaný markdown obsah" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "Neplatná URH: žádný název hostitele" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "Neplatná URL: nelze zjistit název hostitele" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "URL směřuje na soukromou nebo rezervovanou IP adresu" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "Příliš mnoho přesměrování" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Chyba spojení" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Server odpověděl s neplatným stavovým kódem" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Došlo k výjimce" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Server odpověděl s neplatnou hodnotou Content-Length" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Velikost obrázku je příliš velká" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Stahování obrázku překročilo maximální velikost" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Vzdálený server vrátil prázdnou odpověď" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Zadaná URL adresa není platný soubor obrázku" @@ -216,159 +225,203 @@ msgstr "Zadaná URL adresa není platný soubor obrázku" msgid "Log in to the app" msgstr "Přihlásit se do aplikace" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "Ověření CSRF se nezdařilo. Ujistěte se, že INVENTREE_SITE_URL a INVENTREE_TRUSTED_ORIGINS jsou nastaveny správně." + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Před tím, než budete dělat cokoli jiného, musíte zapnout dvoufaktorové ověřování." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Chyba při ověření pluginu" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata musí být objekt python dict" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metadata pluginu" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Pole metadat JSON pro použití externími pluginy" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Nesprávně naformátovaný vzor" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Neznámý formát klíče" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Chybí požadovaný klíč" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Referenční pole nemůže být prázdné" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referenční číslo musí odpovídat požadovanému vzoru" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referenční číslo je příliš velké" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Neplatný výběr" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Název" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Popis" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Popis (volitelně)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Cesta" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplicitní názvy nemohou existovat pod stejným nadřazeným názvem" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Poznámky (volitelné)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Data čárového kódu" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Data čárového kódu třetí strany" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash čárového kódu" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Jedinečný hash dat čárového kódu" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Nalezen existující čárový kód" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Chyba serveru" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Server zaznamenal chybu." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Obrazek" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Musí být platné číslo" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Měna" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Vyberte měnu z dostupných možností" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Toto pole nesmí být nulové." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Neplatná hodnota" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Neplatný formát typu obsahu" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Typ obsahu nenalezen" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "Typ obsahu neodpovídá požadované třídě mixinu" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Kopírovat parametry" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "Kopírovat parametry z původní položky" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Kopírovat řádky" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Kopírovat řádkové položky z původní objednávky" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Kopírovat extra řádky" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Kopírovat extra řádkové položky z původní objednávky" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "Možnosti duplikace" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "Specifikujte možnosti pro duplikování této položky" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "Původní" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "Vyberte instanci pro duplikaci" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabština" @@ -521,46 +574,48 @@ msgstr "Čínština (zjednodušená)" msgid "Chinese (Traditional)" msgstr "Čínština (tradiční)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Dostupná aktualizace" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Aktualizace pro InvenTree je k dispozici" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Neplatná fyzikální jednotka" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Neplatný kód měny" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Stav objednávky" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Nadřazená sestava" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Zahrnout varianty" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Zahrnout varianty" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Zahrnout varianty" msgid "Part" msgstr "Díl" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategorie" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Sestava předků" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Přiřazeno mě" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Přiřazeno" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Vytvořeno před" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Vytvořeno po" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Má počáteční datum" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Datum začátku před" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Datum začátku po" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Má cílové datum" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Cílové datum před" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Cílové datum po" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Dokončeno před" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Dokončeno po" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Min. datum" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Max datum" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Vyloučit strom" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Sestavení musí být zrušeno před odstraněním" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Spotřební materiál" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Volitelné" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Sestava" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Sledováno" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testovatelné" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Objednávka nevyřízená" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Přiděleno" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Spotřebováno" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Dostupné" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Na objednávku" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "Sestava nenalezena" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Výrobní příkaz" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Lokace" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Výstup" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Filtrovat podle ID výstupní položky zásoby. Použijte 'null' pro nalezení odinstalovaných položek sestavení." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Výrobní příkazy" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Kusovník sestavy ještě nebyl schválen" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Výrobní příkaz nesmí být vytvořen pro neaktivní díl" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Výrobní příkaz nemůže být vytvořen pro odemčený díl" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Výrobní příkaz může být externě splněn pouze pro nakupovatelné díly" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Musí být specifikován odpovědný uživatel nebo skupina" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Díl výrobního příkazu nelze změnit" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Cílové datum musí být po datu zahájení" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Referenční číslo výrobního příkazu" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Reference" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Stručný popis sestavení (nepovinné)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Výrobní příkaz, kterému je tato stavba přiřazena" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Vyber téma, které chceš stavět" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referenční číslo prodejní objednávky" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Prodejní objednávka, které je tato stavba přiřazena" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Zdrojové umístění" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Vyberte lokaci, ze které chcete brát zásoby pro sestavu (nechte prázdné, chcete-li brát zásoby z libovolné lokace)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Externí sestavení" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Tento výrobní příkaz je plněn externě" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Cílová lokace" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Vyberte lokaci, kde budou dokončené položky uloženy" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Množství sestav" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Počet skladových položek k sestavení" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Dokončené položky" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Počet skladových položek, které byly dokončeny" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Stav sestavení" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Stavový kód sestavení" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Kód dávky" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Dávkový kód pro tento výstup sestavení" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Datum vytvoření" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Datum zahájení sestavení" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Plánované datum zahájení této objednávky" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Cílové datum dokončení" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Cílové datum dokončení sestavení. Sestavení bude po tomto datu v prodlení." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Datum dokončení" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "dokončil" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Vystavil" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Uživatel, který vystavil tento výrobní příkaz" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odpovědný" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Uživatel nebo skupina odpovědná za tento výrobní příkaz" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Externí odkaz" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Odkaz na externí URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Priorita sestavení" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Priorita tohoto výrobního příkazu" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Kód projektu" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Kód projektu pro tento výrobní příkaz" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Nelze dokončit výrobní příkaz s otevřenými podobjednávkami" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Nelze dokončit výrobní příkaz s neúplnými výstupy" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Nepodařilo se uvolnit úlohu pro dokončení přidělení sestavy" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Výrobní příkaz {build} byl dokončen" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Výrobní příkaz byl dokončen" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "U sledovatelných dílů musí být uvedena sériová čísla" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nebyl specifikováno žádný výstup sestavení" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Výstup sestavení je již dokončen" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Výstup neodpovídá výrobnímu příkazu" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "Výstup sestavení již byl dokončel" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Množství musí být vyšší než nula" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Množství nemůže být větší než výstupní množství" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "Výstup výroby neprošel všemi požadovanými testy" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Výstup sestavy {serial} neprošel všemi požadavky" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "Přiřazené skladové položky jsou stále ve výrobě" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Nelze částečně dokončit výrobní příkaz s přiřazenými položkami" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "Zásoby již neexistují" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Dostupné množství ({q}) překročeno" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Řádková položka výrobního příkazu" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Vytvořit objekt" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Vytvořit objekt" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Množství" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Vyžadované množství pro výrobní příkaz" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Množství spotřebovaných zásob" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Položka sestavení musí specifikovat výstup sestavení, protože hlavní díl je označen jako sledovatelný" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Vybraná skladová položka neodpovídá řádku kusovníku" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "Přiřazené množství musí být vyšší než nula" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Množství musí být 1 pro zřetězený sklad" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Zabrané množství ({q}) nesmí překročit dostupné skladové množství ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Skladová položka je nadměrně zabrána" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Skladové položky" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Zdrojová skladová položka" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Skladové množství pro sestavení" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Instalovat do" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Cílová skladová položka" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Úroveň sestavení" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Název dílu" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Vytvořit výstup" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Vytvořený výstup neodpovídá nadřazenému sestavení" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Výstupní díl se neshoduje s dílem výrobního příkazu" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Výstup sestavení je již dokončen" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Tento stavební výstup není plně přiřazen" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Zadejte množství pro výstup sestavení" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Celé množství požadované pro sledovatelné díly" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Je vyžadována celočíselná hodnota množství, protože kusovník obsahuje sledovatelné díly" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Sériová čísla" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Zadejte sériová čísla pro sestavení výstupů" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Skladové umístění pro výstup sestavy" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Automaticky zvolit sériová čísla" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automaticky přidělit požadované položky s odpovídajícími sériovými čísly" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Následující sériová čísla již existují nebo jsou neplatná" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Musí být uveden seznam výstupů sestavy" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Skladové umístění pro sešrotované výstupy" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Zahodit alokace" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Vyřadit všechny přidělené zásoby pro vyřazené výstupy" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Důvod vyřazení výstupu(ů) sestavy" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Umístění dokončených výstupů sestavy" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "Ke strukturální lokaci nelze přiřadit zásoby" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Přijmout neúplné přidělení" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Dokončit výstupy pokud zásoby nebyly plně přiděleny" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Spotřebovat přidělené zásoby" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Spotřebovat všechny zásoby, které již byly přiděleny této sestavě" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Odstranit neúplné výstupy" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Odstranit všechny výstupy sestavy, které nebyly dokončeny" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Není povoleno" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Přijmout jako spotřebované tímto výrobním příkazem" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Uvolnit před dokončením tohoto výrobního příkazu" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Nadměrně přidělené zásoby" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Jak chcete zacházet s extra skladovými položkami přiřazenými k tomuto výrobnímu příkazu" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Některé skladové položky byly nadměrně přiděleny" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Přijmout nepřidělené" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Přijmout, že skladové položky nebyly plně přiřazeny k tomuto výrobnímu příkazu" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Požadované zásoby nebyly plně přiděleny" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Přijmout neúplné" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Přijmout, že nebyl dokončen požadovaný počet výstupů sestavy" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Požadované množství sestavy nebylo dokončeno" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Výrobní příkaz má otevřené podpříkazy" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Výrobní příkaz musí být ve stavu produkce" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Výrobní příkaz má neúplné výstupy" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Linka sestavy" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Výstup sestavy" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Výstup sestavy musí odkazovat na stejnou sestavu" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Řádková položka sestavy" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part musí ukazovat na stejný díl jako výrobní příkaz" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Položka musí být skladem" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Dostupné množství ({q}) překročeno" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Pro přidělení sledovaných dílů musí být zadán výstup sestavy" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Výstup sestavy nelze zadat pro přidělení nesledovaných dílů" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Položky přidělení musí být poskytnuty" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Skladové místo, odkud se mají díly odebírat (ponechte prázdné, pokud chcete odebírat z libovolného místa)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Vynechat lokace" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Vyloučit skladové položky z tohoto vybraného umístění" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Zaměnitelné zásoby" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Skladové položky na více místech lze používat zaměnitelně" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Náhradní zásoby" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Povolit přidělování náhradních dílů" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Volitelné položky" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Přiřazení volitelných položek kusovníku k objednávce sestavy" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "Všechny položky" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "Nesledované položky" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "Sledované položky" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "Typ položky" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "Vyberte typ položky pro automatické přiřazení" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "Priorita zásob" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "Upřednostňované pořadí ve kterém jsou spotřebovávány odpovídající zásoby" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "Linky sestavy" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "Omezit přiřazení na tyto sestavné linky (nechte prázdné pro přidělení všech linek)" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Reference v kusovníku" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID dílu kusovníku" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Název dílu kusovníku" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "Informace instalace" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Sestavení" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Díl dodavatele" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Přidělené množství" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Reference sestavení" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Název kategorie dílů" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Sledovatelné" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Zděděno" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Povolit varianty" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Položka kusovníku" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "Ve výrobě" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Naplánováno na sestavení" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Externí zásoby" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Dostupné zásoby" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Dostupné náhradní zásoby" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Dostupná varianta skladu" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "Spotřebované množství přesahuje přidělené množství" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Nepovinné poznámky ke spotřebě zásob" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "Sestavení položky musí odkazovat na správný výrobní příkaz" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Duplikovat přidělení položky sestavení" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "Výrobní linka musí odkazovat na správný výrobní příkaz" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Duplikovat přiřazení výrobní linky" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Musí být poskytnuta alespoň jedna linka nebo předmět" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Nevyřízeno" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Výroba" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Pozastaveno" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Zrušeno" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Hotovo" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Výrobní příkaz {build} byl dokončen" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Výrobní příkaz byl dokončen" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Zásoby potřebné pro výrobní příkaz" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Výrobní příkaz {build} vyžaduje další zásoby" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Opožděný výrobní příkaz" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Objednávka sestavy {bo} je nyní opožděná" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "Má miniaturu" + +#: common/api.py:773 msgid "Is Link" msgstr "Je odkaz" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Je soubor" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Uživatel nemá oprávnění k odstranění těchto příloh" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "Uživatel nemá povolení k úpravě této přílohy" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Uživatel nemá oprávnění k odstranění této přílohy" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Tento výběr je uzamčen" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Neplatný kód měny" @@ -1539,15 +1641,20 @@ msgstr "Nejsou uvedeny žádné platné kódy měn" msgid "No plugin" msgstr "Žádný plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "Tagy" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Popisek kódu projektu" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Aktualizováno" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Časové razítko poslední aktualizace" @@ -1567,794 +1674,844 @@ msgstr "Jedinečný kód projektu" msgid "Project description" msgstr "Popis projektu" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Uživatel nebo skupina odpovědná za tento projekt" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Tlačítko nastavení" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Hodnota nastavení" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Zvolená hodnota není platnou možností" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Hodnota musí být logická hodnota" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Hodnota musí být celé číslo" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Hodnota musí být platné číslo" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Hodnota neprošla kontrolou platnosti" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Klíčový text musí být jedinečný" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Uživatel" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Množství cenové slevy" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Cena" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Jednotková cena při stanoveném množství" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Koncový bod" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Koncový bod, ve kterém je tento webhook přijímán" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Název tohoto webhooku" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktivní" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "Je tento kód projektu aktivní?" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Uživatel nebo skupina odpovědná za tento projekt" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Tlačítko nastavení" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Hodnota nastavení" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Zvolená hodnota není platnou možností" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Hodnota musí být logická hodnota" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Hodnota musí být celé číslo" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Hodnota musí být platné číslo" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Hodnota neprošla kontrolou platnosti" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Klíčový text musí být jedinečný" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Uživatel" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Množství cenové slevy" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Cena" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Jednotková cena při stanoveném množství" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Koncový bod" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Koncový bod, ve kterém je tento webhook přijímán" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Název tohoto webhooku" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Je tento webhook aktivní" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token pro přístup" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Tajný klíč" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Sdílený tajný klíč pro HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID zprávy" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Unikátní identifikátor pro tuto zprávu" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Hostitel" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Hostitel, od kterého byla tato zpráva přijata" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Záhlaví" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Záhlaví této zprávy" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Tělo" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Tělo zprávy" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Koncový bod, na kterém byla zpráva přijata" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Pracoval na" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Byla práce na této zprávě dokončena?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "Volitelná explicitní URL, spojená s tímto oznámením" + +#: common/models.py:1772 msgid "Id" msgstr "ID" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Název" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Odkaz" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Zveřejněno" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Souhrn" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Přečteno" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Byla tato novinka přečtena?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Soubor obrázku" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Cílový typ modelu pro tento obrázek" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "Cílové ID modelu pro tento obrázek" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Vlastní jednotka" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Symbol jednotky musí být unikátní" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Název jednotky musí být platný identifikátor" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Název jednotky" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Volitelný symbol jednotky" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definice" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definice jednotky" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Příloha" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Chybějící soubor" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Chybějící externí odkaz" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" -msgstr "" +msgstr "Žádný přiložený soubor k přejmenování" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" -msgstr "" +msgstr "Název souboru nemůže být prázdný" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" -msgstr "" +msgstr "Neplatný název souboru" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" -msgstr "" +msgstr "Nelze změnit příponu souboru" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" -msgstr "" +msgstr "Soubor s tímto názvem již existuje" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" -msgstr "" +msgstr "Chyba při ukládání přejmenovaného souboru" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Typ modelu" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Cílový typ modelu pro obrázek" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Vyberte soubor k přiložení" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "Miniatura" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "Miniatura pro tuto přílohu" + +#: common/models.py:2155 msgid "Comment" msgstr "Komentář" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Komentář přílohy" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Datum nahrání" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Datum, kdy byl soubor nahrán" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "Je obrázek" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "Pravda, pokud je tato příloha platným obrázkem" + +#: common/models.py:2183 msgid "File size" msgstr "Velikost souboru" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Velikost souboru v bytech" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Uveden neplatný typ modelu pro přílohu" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Vlastní stav" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Vlastní stavy" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Nastavení referenčního stavu" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Stav nastavený, který je prodloužen tímto vlastním stavem" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logický klíč" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Logický klíč statusu, který je rovný tomuto vlastnímu statusu v podnikové logice" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Hodnota" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Číselná hodnota, která bude uložena v databázi modelů" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Název stavu" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Popisek" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Štítek, který bude zobrazen na webu" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Barva" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Barva, která bude zobrazena ve frontendu" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Model, ke kterému je tento stav přiřazen" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Musí být vybrán model" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Musí být vybrán klíč" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Musí být vybrán logický klíč" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "Klíč se musí lišit od logického klíče" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Musí být uvedena platná referenční třída statusu" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "Klíč se musí lišit od logických klíčů referenčního statusu" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Název se musí lišit od názvů referenčního statusu" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Výběrové pole" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Výběrová pole" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Název výběrového pole" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Popis výběrového pole" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Uzamčeno" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Je tento seznam výběrů uzamčen?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Může být tento seznam výběru použit?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Zdrojový plugin" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Plugin, který poskytuje seznam výběru" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Zdrojový řetězec" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Volitelný řetězec identifikující zdroj použitý pro tento seznam" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Výchozí položka" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Výchozí položka pro tento seznam výběru" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Vytvořeno" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Datum a čas vytvoření výběrového seznamu" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Poslední aktualizace" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Datum a čas poslední aktualizace výběrového seznamu" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Položka seznamu výběrů" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Položky seznamu výběrů" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Seznam výběru, do kterého tato položka patří" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Název výběrového seznamu" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Popisek pro výběr seznamu" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Popis vstupu výběrového seznamu" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Je tento výběr výběrového listu aktivní?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Šablona parametru" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "Šablona parametru" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "Nevyžaduje jedinečnost" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "Jedinečné pro typ modelu" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "Globálně jedinečné" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Parametry zaškrtávacího pole nemohou mít jednotky" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Parametry zaškrtávacího pole nemohou mít výběr" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Volby musí být jedinečné" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Název šablony parametru musí být jedinečný" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "Cílový typ modelu pro šablonu tohoto parametru" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Název parametru" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Jednotky" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Fyzické jednotky pro tento parametr" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Popis parametru" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Zaškrtávací políčko" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Je tento parametr zaškrtávací políčko?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Volby" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Platné volby pro tento parametr (oddělené čárkami)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Seznam výběru pro tento parametr" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Povoleno" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "Je šablona tohoto parametru povolena?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "Jedinečnost" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "Vynutit jedinečnost propojených parametrů hodnot proti této šabloně" + +#: common/models.py:2858 msgid "Parameter" msgstr "Parametr" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "Parametry" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Neplatná volba pro hodnotu parametru" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "Hodnota parametru musí být jedinečná" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "Neplatný typ modelu pro daný parametr" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "ID modelu" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "ID cílového modelu pro tento parametr" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Šablona" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "Šablona parametru" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Data" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Hodnota parametru" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Poznámka" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Volitelné pole pro poznámku" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Sken čárového kódu" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Data čárového kódu" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Uživatel, který naskenoval čárový kód" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Časová značka" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Datum a čas skenování čárového kódu" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Koncový bod URL, který zpracoval čárový kód" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Kontext" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Kontextová data pro skenov čárového kódu" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Odpověď" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Data z odezvy z čárového kódu" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Výsledek" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Bylo skenování čárového kódu úspěšné?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Vyskytla se chyba" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: Odstranení Emailového logu je chráněno. Nastavte INVENTREE_PROTECT_EMAIL_LOG na False pro užmožnění odstranění." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "E-mailová zpráva" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "E-mailové zprávy" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Oznámeno" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Odesláno" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Selhalo" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Doručeno" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Potvrzeno" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Příchozí" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Odchozí" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Bez odpovědi" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Sledovat doručení" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Sledovat přečtení" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Sledovat kliknutí" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "Globální ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Identifikátor pro tuto zprávu (může být poskytnut externím systémem)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "ID vlákna" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Identifikátor pro toto vlákno (může být poskytnut externím systémem)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Vlákno" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Vlákno propojeno k této zprávě" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "Priorita" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "Emailové vlákno" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "Emailové vlákna" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Klíč" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Unikátní klíč pro toto vlákno (použitý k identifikaci vlákna)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Unikátní identifikátor pro toto vlákno" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Začato interně" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Bylo toto vlákno započato interně?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Datum a čas kdy bylo vlákno vytvořeno" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Datum a čas kdy bylo vlákno naposledy aktualizováno" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} zrušeno" msgid "A order that is assigned to you was canceled" msgstr "Objednávka, která je vám přidělena, byla zrušena" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Přijaté položky" @@ -2388,104 +2545,100 @@ msgstr "Položky byly obdrženy proti objednávce" msgid "Items have been received against a return order" msgstr "Položky byly obdrženy proti vratce" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "Označuje, zda změna tohoto nastavení vyžaduje potvrzení" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "Toto nastavení vyžaduje potvrzení před změnou. Prosím potvrďte změnu." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Indikuje zdali bylo nastavení přepsáno proměnou prostředí" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Přepsat" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Je spuštěné" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Čekající úkoly" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Naplánované úlohy" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Neúspěšné úlohy" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID úlohy" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Unikátní ID úlohy" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Zamknout" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Čas uzamčení" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Jméno úkolu" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funkce" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Název funkce" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumenty" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argumenty úlohy" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Argumenty klíčových slov" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Argumenty klíčových slov úlohy" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Název souboru" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Typ modelu" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Uživatel nemá oprávnění k vytváření nebo úpravám příloh pro tento model" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "Uživatel nemá práva vytvářet nebo upravovat parametry pro tento model" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Tento výběr je uzamčen" - #: common/setting/system.py:97 msgid "No group" msgstr "Žádná skupina" @@ -2614,13 +2767,13 @@ msgstr "Interval aktualizace měny" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Jak často aktualizovat směnné kurzy (pro vypnutí nastavte na nulu)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dny" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Plugin pro aktualizaci měn k použití" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "Limit velikosti nahrávání" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "Maximální povolená velikost pro nahrávání obrázků a souborů" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Přísná validace URL" @@ -2760,947 +2921,1017 @@ msgstr "Plugin pro generování čárových kódů" msgid "Plugin to use for internal barcode data generation" msgstr "Plugin na použití pro interní generaci čárových kódů" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "Zamykání dílu" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "Povolit zamykání dílů pro zabránení úprav" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Revize dílu" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Povolit pole revize pro díl" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Revize pouze pro sestavy" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Povolit revize pouze pro sestavy" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Povolit odstranění ze sestavy" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Povolit odstranění dílů, které jsou použity v sestavě" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Regulární vzorec výrazu pro odpovídající IPN dílu" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Povolit duplicitní IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Povolit více dílům sdílet stejný IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Povolit editaci IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Povolit změnu IPN při úpravách dílu" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Kopírovat data BOM dílu" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Kopírovat data BOM ve výchozím nastavení při duplikování dílu" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Kopírovat data parametrů dílu" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Kopírovat data parametrů ve výchozím nastavení při duplikování dílu" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Kopírovat zkušební data dílu" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Kopírovat testovací data ve výchozím nastavení při duplikování dílu" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kopírovat šablony parametrů kategorie" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Kopírování šablon parametrů kategorie při vytváření dílu" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Díly jsou ve výchozím nastavení šablony" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Díly lze ve výchozím nastavení sestavit z jiných komponentů" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Díly lze ve výchozím nastavení použít jako dílčí komponenty" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Možné zakoupit" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Díly jsou zakoupitelné ve výchozím nastavení" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Prodejné" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Díly jsou prodejné ve výchozím nastavení" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Díly jsou sledovatelné ve výchozím nastavení" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Nehmotné (virtuální)" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Díly jsou nehmotné (virtuální) ve výchozím nastavení" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Zobrazit související díly" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Zobrazit související díly pro díl" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Počáteční údaje zásob" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Povolit vytvoření počátečního skladu při přidání nové části" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Počáteční údaje dodavatele" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Povolit vytvoření počátečních dat dodavatele při přidávání nového dílu" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Formát zobrazení jména dílu" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formát pro zobrazení názvu dílu" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Výchozí ikona kategorie dílu" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Výchozí ikona kategorie dílu (prázdné znamená bez ikony)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Minimální počet desetinných míst u cen" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Minimální počet desetinných míst k zobrazení u cenových údajů" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Maximální počet desetinných míst u cen" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Maximální počet desetinných míst k zobrazení u cenových údajů" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Použít ceny dodavatele" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Zahrnout cenová zvýhodnění dodavatelů do celkových cenových kalkulací" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Přepsání historie nákupu" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Historické ceny nákupních objednávek mají přednost před cenovými zvýhodněními dodavatele" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Použít ceny skladových položek" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Použít ceny z ručně zadaných skladových údajů pro cenové kalkulace" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Stáří cen skladových položek" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Vyloučit skladové položky starší než tento počet dní z cenových kalkulací" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Použít cenu varianty" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Zahrnutí cen variant do celkových cenových kalkulací" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Pouze aktivní varianty" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Pro výpočet ceny varianty použijte pouze aktivní díly varianty" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Automatická aktualizace cen" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Automaticky aktualizovat cenu dílu když se změní interní data" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Interval přestavby cen" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Počet dní před automatickou aktualizací cen dílů" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Interní ceny" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Povolit interní ceny pro díly" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Přepis interní ceny" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Pokud jsou k dispozici, interní ceny mají přednost před výpočty cenového rozpětí" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "Povolit nulovou hodnotu kusovníku" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "Přijmout nulové množství pro položku kusovníku. Umožňuje použít nastavení množství pro definování množství požadovaného pro sestavení, nezávisle na počtu staveb" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Povolit tisk štítků" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Povolit tisk štítků z webového rozhraní" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "DPI rozlišení štítků" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Rozlišení DPI při generování obrazových souborů, které se dodávají do zásuvných modulů pro tisk štítků" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Povolit reporty" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Povolit generování reportů" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Režim ladění chyb" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Generovat reporty v režimu ladění (HTML výstup)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "Report načítaných URL" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "Povolit načítání vzdálených URL při generování reportů" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Zaznamenávat chyby reportů" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Zaznamenávat chyby, které se vyskytnou při vytváření reportů" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Velikost stránky" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Výchozí velikost stránky pro PDF reporty" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Vynutit jednotky parametru" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Pokud jsou uvedeny jednotky, musí hodnoty parametrů odpovídat zadaným jednotkám" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Globálně unikátní sériová čísla" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Sériová čísla pro skladové položky musí být globálně unikátní" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Odstranit vyčerpané zásoby" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Určuje výchozí chování při vyčerpání zásoby položky" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" -msgstr "" +msgstr "Povolit úpravy sériových čísel" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" -msgstr "" +msgstr "Povolit úravy pro sériové čísla pro skladové položky" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "Odstranit serializované zásoby" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "Povolit odstranění skladových položek se sériovým číslem" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Šablona kódu dávky" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Šablona pro generování výchozích kódů dávky pro skladové položky" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Expirace zásob" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Povolit funkci expirace zásob" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Prodat prošlé zásoby" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Povolit prodej prošlých zásob" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Čas stáří zásob" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Počet dnů, po které jsou skladové položky považovány za nevyužité před uplynutím doby expirace" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Sestavit prošlé zásoby" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Povolit sestavování s prošlými zásobami" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Kontrola vlastnictví zásob" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Umožnit kontrolu vlastnictví nad skladovými místy a položkami" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Výchozí ikona umístění zásob" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Výchozí ikona umístění zásob (prázdné znamená bez ikony)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Zobrazit nainstalované skladové položky" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Zobrazit nainstalované skladové položky ve skladových tabulkách" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Zkontrolovat BOM při instalaci položek" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Nainstalované skladové položky musí existovat v BOM pro nadřazený díl" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Povolit převod mimo sklad" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Umožnit přesun skladových položek, které nejsou na skladě, mezi skladovými místy" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "Sloučit zásoby s existujícími zásobami při převodu při výchozím nastavení" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "Výchozí stav pro sloučení zásob při převodu. (Může být změněno pro jednotlivé převody, pokud je požadováno)" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Referenční vzor objednávky sestavy" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Požadovaný vzor pro generování referenčního pole Objednávka sestavy" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Vyžadovat odpovědného vlastníka" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Ke každé objednávce musí být přiřazen odpovědný vlastník" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Vyžadovat aktivní díl" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Zabránit vytváření výrobních příkazů pro neaktivní díly" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Vyžadovat uzamčený díl" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Zabránit vytváření výrobních příkazů pro odemčené díly" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Vyžadovat schválený kusovník" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Zabránit vytváření výrobních příkazů, dokud není schválen kusovník" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Vyžadovat uzavření podobjednávek" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Zabránit dokončení výrobního příkazu dokud nebudou uzavřeny všechny podpříkazy" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Externí výrobní příkazy" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Povolit funkcionalitu externích výrobních příkazů" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "Vyžadovat externí výrobní příkazy" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "Vyžadovat externí výrobní příkaz při objenání montovaných dílů od externího dodavatele" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blokovat, dokud testy neprojdou" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Zabránit dokončení výstupů sestavy, dokud neprojdou všechny požadované testy" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Povolit vracení objednávek" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Povolit funkci vrácení objednávky v uživatelském rozhraní" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Referenční vzor návratové objednávky" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Požadovaný vzor pro vygenerování referenčního pole Návratová objednávka" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Úprava dokončených návratových objednávek" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Umožnit úpravu návratových objednávek po jejich dokončení" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Referenční vzor prodejní objednávky" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Požadovaný vzor pro generování referenčního pole prodejní objednávky" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Výchozí přeprava prodejní objednávky" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Povolit vytvoření výchozí přepravy s prodejními objednávkami" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Úprava dokončených prodejních objednávek" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Umožnit úpravy prodejních objednávek po jejich odeslání nebo dokončení" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "Zásilka vyžaduje kontrolu" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Zabránit dokončení zásilek dokud nebudou zkontrolovány položky" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Označit odeslané objednávky jako dokončené" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Prodejní objednávky označené jako odeslané se automaticky dokončí a obejdou stav „odesláno“" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "Povolit převodní příkazy" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "Povolit funkci převodních příkazů v uživatelském rozhraní" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "Referenční vzor převodního příkazu" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "Požadovaný vzor pro generování pole převodního příkazu" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "Upravit dokončené převodní příkazy" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "Povolit úpravy převodních příkazů po jejich dokončení" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "Blokovat nekompletné testy položky" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "Zabránit přiřazení skladových položek do prodejních objednávek, pokud jsou požadované testy neúplné" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Referenční vzor nákupní objednávky" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Požadovaný vzor pro generování referenčního pole nákupní objednávky" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Úprava dokončených nákupních objednávek" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Umožnit úpravy nákupních objednávek po jejich odeslání nebo dokončení" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Převést měnu" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Převést hodnotu předmětu na základní měnu při příjmu zásob" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Automatické dokončování nákupních objednávek" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Automaticky označit nákupní objednávky jako kompletní, jakmile jsou přijaty všechny řádkové položky" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "Sloučit položky nákupní objednávky" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "Sloučit nové položky objednávky s existujícími řádky, které sdílí stejnou položku, cíl a cílové datum" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Povolit pole zapomenutého hesla" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Povolení funkce zapomenutého hesla na přihlašovacích stránkách" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Povolit registrace" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Povolit samoregistraci uživatelů na přihlašovacích stránkách" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "Povolit SSO" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Povolit SSO na přihlašovacích stránkách" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Povolit SSO registraci" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Povolit samoregistraci uživatelů prostřednictvím SSO na přihlašovacích stránkách" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Povolit synchronizaci SSO skupin" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Povolit synchronizaci InvenTree skupin se skupinami poskytnutými IdP" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "klíč SSO skupiny" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Název deklarace skupinového atributu poskytnutého IdP" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "mapa SSO skupiny" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Mapování ze skupin SSO do místních InvenTree skupin. Pokud místní skupina neexistuje, bude vytvořena." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Odstranit skupiny mimo SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Zdali mají být skupiny přiřazené uživateli odstraněny pokud nemají backend of IdP. Vypnutí tohoto nastavení můžu způsobit problémy se zabezpečením" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "Vyžadován e-mail" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Požadovat, aby uživatel při registraci zadal e-mail" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Automaticky vyplnit SSO uživatele" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Automaticky vyplnit údaje o uživateli z údajů o účtu SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Mail dvakrát" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Při registraci dvakrát požádat uživatele o zadání e-mailu" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Heslo dvakrát" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Při registraci dvakrát požádat uživatele o heslo" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Povolené domény" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Omezit registraci na určité domény (oddělené čárkou a začínající @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Skupina při registraci" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Skupina do které jsou nový uživatelé přiřazeni při registraci. Pokud je povolena synchronizace SSO skupin, tato skupina lze přiřadit pouze pokud nezle přiřadit skupinu od IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Vynutit MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Uživatelé musí používat vícefaktorové zabezpečení." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "Povolení tohoto nastavení bude vyžadovat více fázové ověření u všech uživatelů. Všechny relace budou okamžitě ukončeny." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Zkontrolovat pluginy při spuštění" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Zkontrolujte, zda jsou při spuštění nainstalovány všechny pluginy - povolit v kontejnerových prostředích" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Zkontrolovat aktualizace pluginů" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Povolit pravidelné kontroly aktualizací nainstalovaných pluginů" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Povolit integraci URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Povolit plug-inům přidávat trasy URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Povolit integraci navigace" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Povolit integrování pluginů do navigace" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Povolit integraci aplikací" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Povolit pluginům přidávát aplikace" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Povolit integraci plánu" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Povolit pluginům spouštění naplánovaných úloh" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Povolit integraci událostí" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Povolit pluginům reagovat na interní události" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Povolit rozhraní intergace" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Povolit integrování pluginů do uživatelského rozhraní" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Povolit integraci emailu" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Povolit pluginům zpracování odchozích/příchozích emailů" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Povolit projektové kódy" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Povolit projektové kódy pro sledování projektů" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "Povolit inventuru" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Povolit funkcionalitu pro zaznamenávání historických stavů zásob a hodnoty" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Vyloučit externí umístění" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "Vyloučit skladové položky z externích lokací z inventury" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Perioda automatické inventury" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "Počet dní mezi automatickým záznamem inventury" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "Odstranit staré záznamy inventur" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "Odstranit záznamy inventur starší než zadaný počet dní" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "Interval odstranění inventury" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "Záznamy inventur budou odstraněny po zadaném počtu dní" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "Odstranit staré záznamy sledování zásob" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "Odstranit staré záznamy sledování zásob starší než zadaný počet dní" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "Interval odstranění sledování zásob" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "Záznamy sledování zásob budou odstraněny po zadaném počtu dní" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Zobrazit celá jména uživatelů" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Zobrazit plná jména uživatelů namísto uživatelských jmen" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Zobrazit uživatelské profily" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Zobrazit profily uživatelů na jejich profilové stránce" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "Týden začíná" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "Počáteční den v týdnu pro zobrazení v zobrazení kalendáře" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "Neděle" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "Pondělí" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "Úterý" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "Středa" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "Čtvrtek" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "Pátek" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "Sobota" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "Horizont kalendáře" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "Počet měsíců do budoucna, které se zobrazí v zobrazení kalendáře" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "měsíce" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Povolit data zkušební stanice" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Povolit sběr dat ze zkušební stanice pro výsledky testů" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "Povolit ping stroje" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Povolit pravidelný úkol pingu registrovaných strojů pro kontrolu jejich stavu" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Počet výsledků, které se mají zobrazit v každé části okna náhledu vyhledávání" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "Náhled výsledků hledání" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "Otevřít výsledky hledání v panelu náhledů a nepřejít přímo k výsledku" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Regex hledání" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Povolit regulární výrazy ve vyhledávacích dotazech" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Vyhledávání celého slova" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Vyhledávací dotazy vracejí výsledky pro shody celých slov" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Hledat poznámky" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Vyhledávací dotazi vrátí výsledky pro shody v poznámek položek" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Klávesa Escape zavře formuláře" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Zavřít modální formuláře pomocí klávesy escape" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Pevná navigační lišta" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Pozice navigační lišty je pevně nastavena na horní okraj obrazovky" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "Pevné záhlaví tabulky" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Hlavičky tabulky jsou připevněny k horní části tabulky" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Zobrazit Spotlight" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Povolit funkci spotlight navigace" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Navigační ikony" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Zobrazit ikony v navigačním panelu" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Formát data" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Preferovaný formát pro zobrazení datumů" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "Panel náhledu tabulky" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "Zobrazit náhledový panel při výběru položek v tabulkách" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Zobrazit historii skladu" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Zobrazit informace o historii zásob na stránce s podrobnostmi dílu" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Zobrazit poslední drobečkovou navigaci" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Zobrazit aktuální stránku v navigační službě" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "Zobrazit další informace o modelu" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "Zobrazit další informace v rozbalovacích nabídkách modelu" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Zobrazit plnou polohu zásob v tabulkách" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Vypnuto: Celá cesta lokace se ukáže jako nápověda. Zapnuto: Celá cesta lokace se ukáže jako prostý text." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Zobrazit celé kategorie dílů v tabulkách" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Vypnuto: Celá kategorie se ukáže jako nápověda. Zapnuto: Celá kategorie se ukáže jako prostý text." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "Zobrazit podsestavy v tabulce kusovníku" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "Povolit zobrazení podsestav v tabulce kusovníku" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Přijímat zprávy o chybách" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Dostávat oznámení o systémových chybách" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Poslední použité tiskárny" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Uložte poslední použité tiskárny pro uživatele" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "Zobrazit položky na poslední úrovni" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "Automaticky zobrazit položky místo podúrovní pro umístění nebo kategorie bez podkategorií" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Všechny modely" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Není zadán typ modelu přílohy" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Neplatný typ přílohy modelu" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "Velikost souboru překračuje maximální limit nahrávání {max_size} MB" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "Neplatný název souboru" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Minimální počet míst nesmí být větší než maximální počet míst" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Maximální počet míst nesmí být menší než minimální počet míst" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Prázdná doména není povolena." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Neplatný název domény: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Hodnota musí být napsána velkými písmeny" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Hodnota musí být platný variabilní identifikátor" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Díl je aktivní" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Výrobce je aktivní" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Díl dodavatele je aktivní" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "Primární díl dodavatele" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Interní díl je aktivní" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Dodavatel je aktivní" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Výrobce" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Společnost" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Má zásoby" @@ -4123,8 +4387,8 @@ msgstr "Kontaktní telefonní číslo" msgid "Contact email address" msgstr "Kontaktní e-mailová adresa" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontakt" @@ -4176,283 +4440,283 @@ msgstr "DIČ" msgid "Company Tax ID" msgstr "DIČ společnosti" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adresa" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adresy" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Vyberte společnost" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Název adresy" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Název popisující záznam adresy" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Primární adresa" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Nastavit jako primární adresu" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Řádek 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "1. řádek adresy" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Řádek 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "2. řádek adresy" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "PSČ" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Město/Region" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "PSČ město/region" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Stát/kraj" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Stát nebo provincie" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Země" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Adresovaná země" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Doručovací poznámky pro kurýra" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Poznámky pro kurýra" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Interní přepravní poznámky" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Doručovací poznámky pro interní použití" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Odkaz na informace o adrese (externí)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Výrobce dílu" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Základní díl" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Zvolte díl" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Vyberte výrobce" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Číslo dílu výrobce" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL pro odkaz na díl externího výrobce" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Popis dílu výrobce" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Jednotky balení musí být kompatibilní s jednotkami základních dílů" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Jednotky balení musí být větší než nula" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Odkazovaný díl výrobce musí odkazovat na stejný základní díl" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Dodavatel" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Vyberte dodavatele" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Skladová evidence dodavatele" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Je tento díl dodavatele aktivní?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "Primární" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "Je tento primární díl dodavatele připojen k dílu?" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Vyberte díl výrobce" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "Adresa URL pro odkaz na externí díl dodavatele" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Popis dílu dodavatele" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "základní cena" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimální poplatek (např. poplatek za skladování)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Balení" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Balení dílu" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Počet kusů v balení" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Celkové množství dodávané v jednom balení. Pro jednotlivé položky ponechte prázdné." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "více" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Objednat více" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Množství dostupné od dodavatele" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Dostupnost aktualizována" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Datum poslední aktualizace údajů o dostupnosti" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Cenová sleva dodavatele" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Výchozí měna používaná pro tohoto dodavatele" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Jméno společnosti" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Skladem" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Množstevní sleva" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "Hezké jméno" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Při exportu dat došlo k chybě" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Plugin pro export dat vrátil nesprávný formát dat" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Exportovat formát" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Vyberte formát export souboru" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Exportovací plugin" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Vyberte exportovací plugin" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Další informace ke stavu této položky" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Vlastní status klíče" @@ -4476,123 +4740,152 @@ msgstr "Umístěno" msgid "Invalid status code" msgstr "Neplatný kód statusu" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Datový soubor" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Datový soubor k importu" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Sloupce" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Cílový typ modelu pro tuto relaci importu" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Stav importu" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Výchozí Hodnoty" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Přepsání Pole" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Filtry pole" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Aktualizovat existující záznamy" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Pokud je povoleno, existující záznamy budou aktualizovány s novými daty" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Některá povinná pole nebyla namapována" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "Dokončená historie počtu řádků" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "Historie počtu řádků" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Existující databázový identifikátor pro tento záznam" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "Sloupec je již napamován k poli databáze" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Pole je již namapováno do datového sloupce" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Mapování sloupců musí být připojeno k platné relaci importu" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Sloupec neexistuje v datovém souboru" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Pole neexistuje v cílovém modelu" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Vybrané pole je pouze pro čtení" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "Vyhledávání může být nastaveno pouze pro související (cizí klíč) pole" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "Neplatné pole vyhledávání. Platné možnosti jsou: {options}" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Importovací relace" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Pole" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Sloupec" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "Vyhledávací pole" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "Pole databáze pro vyhledávání cizích klíčů. Ponechte prázdné pro automatické vyhledávání." + +#: importer/models.py:674 msgid "Row Index" msgstr "Index řádku" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Původní data řádku" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Chyby" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Platné" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "ID je vyžadováno pro aktualizaci existujících záznamů." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "Bylo nalezeno více výsledků - ujistěte se, že hodnota je jedinečná, nebo vyberte konkrétní vyhledávací pole" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Žádný záznam nalezen pro zadané ID" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Poskytnut neplatný formát ID" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "ID je vyžadováno pro aktualizaci existujících záznamů." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Nepodporovaný formát souboru" @@ -4600,43 +4893,47 @@ msgstr "Nepodporovaný formát souboru" msgid "Failed to open data file" msgstr "Nepodařilo se otevřít datový soubor" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "Datový soubor nelze dekódovat jako text" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Neplatné rozměry datového souboru" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Neplatné výchozí nastavení pole" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Neplatné přepsaní pole" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Neplatný filtr pole" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Řádky" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Seznam ID řádků které mají být přijaty" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Žádké řádky nebyly poskytnuty" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "Řádek nepatří k této relaci" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "Řádek obsahuje neplatná data" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "Řádek již byl dokončen" @@ -4672,115 +4969,115 @@ msgstr "Datový soubor obsahuje příliš mnoho sloupců" msgid "Data file contains too many rows" msgstr "Datový soubor obsahuje příliš mnoho řádků" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Hodnota musí být platný objekt slovníku" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopie" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Počet kopií, které se mají tisknout pro každý štítek" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Připojeno" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Neznámý" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Tisk" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Varování" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Žádná média" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Zaseknutí papíru" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Odpojeno" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Chyba" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Tiskárna štítků" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Přímo vytisknout štítky pro různé položky." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Umístění tiskárny" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Určení rozsahu tiskárny na konkrétní místo" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Název zařízení" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Typ zařízení" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Typ zařízení" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Ovladač" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Ovladač používaný pro toto zařízení" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Zařízení mohou být vypnuty" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Ovladač k dispozici" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Žádné chyby" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Zahájeno" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Stav zařízení" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Zařízení" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Nastavení žařízení" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Typ nastavení" @@ -4792,7 +5089,7 @@ msgstr "Klíč vlastnosti" msgid "Value of the property" msgstr "Hodnota vlastnosti" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Skupina" @@ -4816,117 +5113,118 @@ msgstr "Maximální pokrok" msgid "Maximum value for progress type, required if type=progress" msgstr "Maximální hodnota pro pokrok typu, vyžadováno pokud typ=pokrok" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Označení objednávky" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Vynikající" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Má projektový kód" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Vytvořil(a)" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Vytvořeno před" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Vytvořeno po" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Má počáteční datum" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Datum začátku před" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Datum začátku po" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Má cílové datum" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Cílové datum před" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Cílové datum po" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "Aktualizováno před" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "Aktualizováno po" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Má cenu" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Dokončeno před" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Dokončeno po" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Externí výrobní příkaz" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Objednávka" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Objednávka byla dokončena" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Interní díl" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Objednávka čeká na vyřízení" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Dokončeno" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Má zásilku" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "Zásilka nebyla nalezena" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Nákupní objednávka" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Nákupní objednávka" msgid "Sales Order" msgstr "Prodejní objednávka" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Vratka" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "Převodní příkaz" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Celková cena" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Celková cena za tuto objednávku" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Měna objednávky" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Měna pro tuto objednávku (nechte prázdné pro použití výchozí hodnoty společnosti)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Tato objednávka je uzamčena a nelze ji upravit" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Kontakt nesouhlasí s vybranou společností" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "Datum zahájení musí být před cílovým datem" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "Adresa nesouhlasí s vybranou společností" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Popis objednávky (volitelné)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Vyberte kód projektu pro tuto objednávku" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Odkaz na externí stránku" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Datum zahájení" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Plánované datum zahájení této objednávky" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Cílené datum" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Očekávané datum doručení objednávky. Objednávka bude po tomto datu splatná." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Datum vystavení" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Datum vystavení objednávky" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "Aktualizováno v" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Uživatel nebo skupina odpovědná za tuto objednávku" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Kontaktní bod pro tuto objednávku" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Adresa společnosti pro tuto objednávku" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Číslo objednávky" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Stav" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Stav objednávky" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Společnost, od které se položky objednávají" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Reference dodavatele" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Referenční kód objednávky dodavatele" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "přijal" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Datum dokončení objednávky" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Místo určení" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Cílové místo pro přijaté položky" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Dodavatel dílu se musí shodovat s dodavatelem PO" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Řádková položka neodpovídá nákupní objednávce" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "Řádkové položce chybí propojený díl" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Množství musí být kladné" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "Sériová čísla nemohou být přiřazena virtuálním dílům" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "Povolit jakékoliv zásoby (serializované nebo neserializované)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "Pouze serializované zásoby" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "Pouze neserializované zásoby" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Zákazník" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Společnost, jíž se položky prodávají" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Stav prodejní objednávky" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Reference zákazníka " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Referenční kód objednávky zákazníka" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Datum odeslání" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "odesláno společností" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Řádková položka není přiřazena k této objednávce" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Nebyla nalezena žádná shoda pro následující sériová čísla" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Následující sériová čísla nejsou k dispozici" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Objednávka je již dokončena" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Objednávka je již zrušena" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Pouze otevřená objednávka může být označena jako kompletní" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Objednávku nelze dokončit, protože dodávky jsou nekompletní" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Objednávka nemůže být dokončena, protože jsou neúplné přiřazení" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Objednávka nemůže být dokončena, protože jsou neúplné řádkové položky" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "Objednávka je uzamčena a nelze ji upravit" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Množství položky" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "Sleva" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "Procento slevy aplikované na tuto položky (0-100)" + +#: order/models.py:2138 msgid "Line Number" msgstr "Číslo linky" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "Číslo řádku pro tuto položku (nepovinné)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Označení řádkové položky" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Poznámky k řádkovým položkám" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Cílové datum pro tuto řádkovou položku (pro použití cílového data z objednávky ponechte prázdné)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Popis řádkové položky (nepovinné)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Dodatečný kontext pro tento řádek" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Cena za jednotku" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Řádková položka nákupní objednávky" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Dodavatelský díl musí odpovídat dodavateli" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "Objednávka sestavení musí být označená jako externí" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Objednávka sestavení může být propojena pouze s montážními díly" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "Výrobní příkaz musí odpovídat lince předmětu dílu" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "Externí výrobní příkaz je vyžadován pro montážní díly" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Díl dodavatele" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Doručeno" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Počet přijatých položek" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Nákupní cena" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Jednotková nákupní cena" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Externí výrobní příkaz který má být splněn touto linkovou položkou" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Nákupní příkaz extra linka" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Řádková položka prodejní objednávky" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "K prodejní objednávce lze přiřadit pouze prodejné díly" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Prodejní cena" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Jednotková prodejní cena" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Odesláno" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Odeslané množství" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Zásilka prodejní objednávky" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "Adresa zásilky musí odpovídat adrese zákazníka" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Dodací adresa pro tuto zásilku" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Datum odeslání" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Datum doručení" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Datum doručení zásilky" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Kontroloval(a)" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Uživatel, který zkontroloval tuto zásilku" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Doprava" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Číslo zásilky" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Sledovací číslo" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Informace o sledování zásilky" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Číslo faktury" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Referenční číslo přiřazené faktury" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Zásilka již byla odeslána" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Zásilka nemá žádné přidělené skladové položky" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "Zásilka musí být zkontrolována než může být dokončená" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Prodejní příkaz extra linka" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Přidělení prodejní objednávky" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Skladová položka nebyla přiřazena" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Nelze přidělit skladovou položku na řádek s jiným dílem" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Nelze přidělit skladovou položku na řádek bez dílu" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Přidělené množství nesmí překročit množství zásob" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Zabrané množství musí být větší než nula" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Množství musí být 1 pro serializovanou skladovou položku" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Prodejní objednávka neodpovídá zásilce" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Zásilka neodpovídá prodejní objednávce" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Řádek" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Odkaz na zásilku z prodejní objednávky" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Položka" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Vyberte skladovou položku pro přidělení" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Zadejte množství pro přidělení zásob" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Reference návratové objednávky" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Společnost, od které se vrací položky" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Stav návratové objednávky" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Linkový předmět vratky" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Zásobní položka musí být specifikována" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Množství vratky přesahuje množstvní zásob" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "Množstvní vratky musí být více než nula" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Neplatné množství pro sériovou skladovou položku" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Vyberte položku pro vrácení od zákazníka" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Datum přijetí" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "Datum příjetí této vratky" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Výsledek" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Výsledky pro tuto položku" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Náklady spojené s návratem nebo opravou této položky" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Vratka extra linka" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID objednávky" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "Reference převodního příkazu" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID objednávky k duplikaci" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "Stav převodního příkazu" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Kopírovat řádky" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "Zdroj pro přenášené položky" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Kopírovat řádkové položky z původní objednávky" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "Cíl pro přenášené položky" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Kopírovat extra řádky" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "Spotřebovat zásoby" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Kopírovat extra řádkové položky z původní objednávky" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "Spíše než převést zásoby na místo určení, \"konzumovat\" je odebráním převedeného množství z přidělených zásob" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Kopírovat parametry" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "Příkaz nelze dokončit bez uvedené cílové lokace" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" -msgstr "Kopírovat parametry objednávky z původní objednávky" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "Příkaz nelze dokončit, dokud nebude plně přidělen" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "Převodní příkaz položky" + +#: order/models.py:4027 +msgid "transferred" +msgstr "převedeno" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "převedené množství" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "Přidělení převodního příkazu" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "Nepodařilo se spotřebovat položky proti převodní objednávce" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "Nepodařilo se převést položky proti převodní objednávce" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Řádkové položky" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Dokončené řádky" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Duplikovat objednávku" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "Vlastní stavový klíč" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Specifikujte možnosti pro duplikaci této objednávky" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "Aktualizovat stav objednávky na vlastní hodnotu pro tuto logickou hodnotu" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Neplatné ID objednávky" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "Vlastní stavový klíč musí být celé číslo" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "Neplatný vlastní stavový klíč" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "Neplatný vlastní stavový klíč pro stav této objednávky" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Název dodavatele" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Objednávku nelze zrušit" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Povolit uzavření objednávky s neúplnými řádkovými položkami" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Objednávka má nedokončené řádkové položky" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Objednávka není otevřena" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Automatická cena" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Automaticky vypočítat nákupní cenu na základě údajů o dílech dodavatele" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Měna nákupní ceny" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Sloučit položky" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Sloučit položky se stejným dílem, místem určení a cílovým datem do jedné řádkové položky" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Číslo zboží (SKU)" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Interní číslo dílu" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Interní název dílu" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Musí být uveden díl dodavatele" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Objednávka musí být zadána" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Dodavatel musí odpovídat objednávce" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Objednávka musí odpovídat dodavateli" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Řádková položka" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Vyberte cílové umístění pro přijaté položky" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Zadat kód šarže pro příchozí skladové položky" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Datum expirace" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Zadejte datum expirace pro příchozí skladové položky" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Zadat sériová čísla pro příchozí skladové položky" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Přepsat informace o obalu pro příchozí skladové položky" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Dodatečná poznámka pro příchozí skladové položky" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Čárový kód" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Naskenovaný čárový kód" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Tento čárový kód se již používá" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Musí být uvedeny řádkové položky" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Místo určení musí být specifikováno" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Hodnoty dodaných čárových kódů musí být unikátní" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "Dodaná sériová čísla musí být jedinečná" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Zásilky" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Dokončené zásilky" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "Přidělené řádky" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Měna prodejní ceny" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Přidělené položky" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Nebyly poskytnuty žádné údaje o zásilce" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Řádková položka není přiřazena k této objednávce" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Množství musí být kladné" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "Skladová položka neprošla všemi požadovanými testy" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Zadejte sériová čísla pro přidělení" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Zásilka již byla odeslána" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Zásilka není spojena s touto objednávkou" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Nebyla nalezena žádná shoda pro následující sériová čísla" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "Skladové místo, odkud mají být položky získávány (nechce prázdné pro jakékoliv)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Následující sériová čísla nejsou k dispozici" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "Vyloučit zásoby z této lokace" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "Přiřadit přiřazení k této zásilce" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "Povolit odebrání zásob z více míst k naplnění jedné položky" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "Serializované zásoby" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "Určuje zda serializované zásoby jsou zahrnuty do automatického přiřazení" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "Omezit přiřazení na tyto linkové položky (nechte prázdné pro přidělení všech linek)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "Linková položka nepatří k této objednávce" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Řádkový předmět vratky" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Řádková položka neodpovídá vratce" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Řádková položka již byla přijata" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Položky lze přijímat pouze proti objednávkám, které probíhají" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Množství k vrácení" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Měna ceny řádku" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "Povolit dokončit příkaz s neúplnými alokacemi" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "Příkaz má neúplné alokace" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Ztraceno" @@ -5718,1279 +6125,1312 @@ msgstr "Ztraceno" msgid "Returned" msgstr "Vráceno" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Zpracovává se" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Vrátit zpět" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Oprava" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Náhrada" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Vrácení peněz" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Odmítnout" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Vydáno" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Objednávka po splatnosti" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Nákupní objednávka {po} je nyní opožděná" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Opožděná prodejní objednávka" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Prodejní objednávka {so} je nyní opožděná" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Vratka po termínu vrácení" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Vratka {ro} je nyní opožděná" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Označené" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Filtrovat podle kategorií s hvězdičkou" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Hloubka" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filtrovat podle hloubky kategorie" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Nejvyšší úroveň" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filtrovat podle nejvyšších kategorií" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Kaskáda" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Zahrnout podkategorie do filtrovaných výsledků" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Předek" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Filtrovat podle nadřazené kategorie" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Vyloučit podkategorie v zadané kategorii" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "Maximální úroveň" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "Omezení hloubky stromu kategorie" + +#: part/api.py:442 msgid "Has Results" msgstr "Má výsledky" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Je varianta" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Je revizí" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Má revize" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "Kusovník schválen" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Kaskádové kategorie" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Pokud je pravda, zahrne položky z podkategorií dané kategorie" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Filtrovat podle numerického ID kategorie nebo doslovného 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "Sestavený díl je aktivní" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "Sestavený díl je sledovatelný" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Sestavený díl je testovatelný" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "Sestavený díl je uzamčen" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "Kompotenta je aktivní" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "Komponenta je sledovatelná" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Díl komponenty je testovatelný" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "Komponenta je část sestavy" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "Komponenta je virtuální" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "Má dostupné zásoby" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Využití" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Kategorie dílu" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Kategorie dílů" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Výchozí umístění" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Výchozí umístění dílů v této kategorii" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Strukturální" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Díly nesmějí být přímo zařazeny do strukturální kategorie, ale mohou být zařazeny do jejích podkategorií." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Výchozí klíčová slova" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Výchozí klíčová slova pro díly v této kategorii" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ikona" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ikona (volitelná)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Nemůžete tuto kategorii označit jako strukturální, protože má již přiřazené díly!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Šablona parametru kategorie dílu" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Výchozí hodnota" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Výchozí hodnota parametru" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Díly" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "Nelze odstranit parametry zamčeného dílu" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "Nelze upravit parametry zamčeného dílu" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Tento díl nelze smazat, protože je uzamčen" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Tento díl nelze odstanit, protože je stále aktivní" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Tento díl nelze odstranit, protože je použit v sestavě" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Díl '{self}' nelze použít v kusovníku '{parent}' (rekurzivní)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Díl '{parent}' je využit v kusovníku '{self}' (rekurzivní)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN musí odpovídat regex vzoru {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Díl nemůže být revize same sebe" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "Kód revize musí být specifikován pro díl označený jako revize" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Revize jsou povoleny pouze pro sestavy" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Nelze provést revizi šablony" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "Nadřazený díl musí odkazovat na stejnou šablonu" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Skladová položka s tímto sériovým číslem již existuje" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Duplicitní IPN není povoleno v nastavení dílu" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Duplicitní díl revize již existuje." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Díl s tímto názvem, IPN a revizí již existuje." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Díly nemohou být přiřazeny do strukturálních kategorií!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Název dílu" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Je šablonou" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Je tento díl šablona?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Je tento díl varianta jiného dílu?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Varianta" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Popis dílu (nepovinné)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Klíčová slova" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Klíčová slova dílu pro zlepšení vyhledávání" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Kategorie dílu" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "Interní číslo dílu (IPN)" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Číslo revize nebo verze dílu" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revize" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Je tento díl revizí jiného dílu?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Revize" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Kde je tato položka obvykle skladněna?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Výchozí expirace" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Expirační čas (ve dnech) pro zásoby tohoto dílu" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimální zásoby na skladě" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Minimální povolená úroveň zásob" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "Maximální zásoby" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "Maximální povolená úroveň zásob" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Měrné jednotky pro tento díl" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Lze tento díl sestavit z jiných dílů?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Lze tento díl použít k sestavení jiných dílů?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Lze u tohoto dílu sledovat jednotlivé položky?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Může mít tento díl zaznamenány výsledky testu?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Může být tento díl zakoupen od externích dodavatelů?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Lze tento díl prodávat zákazníkům?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Je tento díl aktivní?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Uzamčené díly nelze upravit" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Je to virtuální díl, například softwarový produkt nebo licence?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "Je tento díl spotřební, jako lepidlo, nebo šroub?" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "Kusovník ověřen" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Je kusovník pro tuto část platný?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Kontrolní součet kusovníku" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Uložený kontrolní součet kusovníku" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Kusovník zkontroloval" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Datum kontroly kusovníku" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Vytváření uživatele" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Vlastník odpovědný za tento díl" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Prodat více" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Měna použitá pro výpočet cen v mezipaměti" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimální cena kusovníku" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Minimální cena komponent dílu" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maximální cena kusovníku" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Maximální cena komponent dílu" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimální nákupní cena" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Minimální historická nákupní cena" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maximální nákupní cena" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Maximální historická nákupní cena" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimální interní cena" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Minimální cena závislá na množstevní slevě" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maximální interní cena" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Maximální cena závislá na množstevní slevě" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Minimální cena dodavatele" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Minimální cena dílu od externích dodavatelů" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Maximální cena dodavatele" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Maximální cena dílu od externích dodavatelů" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Minimální cena variant" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Vypočítané minimální náklady na varianty dílů" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Maximální cena variant" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Vypočítané maximální náklady na varianty dílů" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimální cena" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Přepsat minimální náklady" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maximální cena" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Přepsat maximální náklady" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Vypočítané minimální celkové náklady" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Vypočítané maximální celkové náklady" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Minimální prodejní cena" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Minimální prodejní cena na základě cenových zvýhodnění" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Maximální prodejní cena" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Maximální prodejní cena na základě cenových zvýhodnění" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Minimální prodejní cena" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Minimální historická prodejní cena" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Maximální prodejní cena" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Maximální historická prodejní cena" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Díl na inventuru" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Počet položek" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Počet jednotlivých položek zásob v době inventury" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Celkové dostupné zásoby v době inventury" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Datum" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Datum provedení inventury" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Minimální cena zásob" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Odhadovaná minimální cena zásob k dispozici" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maximální cena zásob" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Odhadovaná maximální cena zásob k dispozici" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Částeční sleva v ceně" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "Interní cenové slevy dílů" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Šablona testu položky" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Neplatný název šablony - musí obsahovat alespoň jeden alfanumerický znak" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Zkušební šablony lze vytvořit pouze pro testovatelné části" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Testovací šablona se stejným klíčem již existuje pro díl" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Název testu" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Zadejte název testu" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Testovací klíč" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Zjednodušený klíč pro testování" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Popis testu" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Zadejte popis pro tento test" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Je tento test povolen?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Požadováno" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Je tato zkouška vyžadována k projití?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Požadovaná hodnota" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Vyžaduje tato zkouška hodnotu při výpočtu výsledku zkoušky?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Vyžaduje přílohu" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Vyžaduje tato zkouška soubor při přidání výsledku testu?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Platné volby pro tento test (oddělené čárkami)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "Neplatné množství - nebyly zadány žádné jedotky pro tento díl" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "Množství musí být větší nebo rovno nule" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "Položku kusovníku nelze změnit - sestava je uzamčena" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Položku kusovníku nelze změnit - varianta montáže je uzamčena" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Vyberte nadřazený díl" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Poddílec" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Vyberte díl které bude použit v kusovníku" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "Množství" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "Množství pod-dílů spotřebované při výrobě jednoho dílu" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Kusovníkové množství pro tuto kusovníkovou položku" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Tato položka kusovníku je nepovinná" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Tento předmět kusovníku je spotřebovatelný (není sledován v objednávkách stavby)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Nastavit množství" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Dodatečné množství potřebné pro sestavení k vyúčtování ztráty nastavení" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Přirozené ztráty" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Odhadované přirozené ztráty pro stavbu, vyjádřeno v procentech (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Zaokrouhlení více" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Zaokrouhlit požadované množství produkce na nejbližší násobek této hodnoty" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Reference položky kusovníku" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Poznámky k položce kusovníku" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Kontrolní součet" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Kontrolní součet řádku kusovníku" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Schváleno" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Tato položka kusovníku ještě nebyla schválena" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Se zdědí" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Tento kusovník se zdědí kusovníky pro varianty dílů" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Skladové položky pro varianty dílu lze použít pro tuto položku kusovníku" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Množství musí být celé číslo pro sledovatelné díly" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Poddíl musí být specifikován" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Náhradní položka kusovníku" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Náhradní díl nemůže být stejný jako hlavní díl" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Nadřazená položka kusovníku" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Náhradní díl" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Díl 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Díl 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Vyberte související díl" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Poznámka pro tento vztah" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Část vztahu nemůže být vytvořena mezi dílem samotným" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Duplicitní vztah již existuje" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "Odstranit podkategorie" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "Odstranit všechny podkategorie obsažené v této kategorii" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "Odstranit díly" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "Odstranit všechny díly v této kategorii" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Nadřazená kategorie" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Nadřazená kategorie dílu" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Podkategorie" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Výsledky" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Počet výsledků zaznamenaných podle této šablony" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Nákupní měna této skladové položky" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Soubor není obrázek" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Původní díl" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Vyberte původní díl, který má být duplikován" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kopírovat obrázek" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Kopírovat obrázek z původního dílu" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Kopírovat kusovník" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Kopírovat kusovník z původního dílu" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Kopírovat data parametrů z původního dílu" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Kopírovat poznámky" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Kopírovat poznámky z původního dílu" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Kopírovat testy" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "Kopírovat testovací šablony z původního dílu" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Počáteční skladové množství" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Zadejte počáteční skladové množství pro tuto část. Pokud je množství nulové, není přidáno žádné." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Počáteční skladové místo" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Zadejte počáteční skladové místo pro tento díl" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Vyberte dodavatele (nebo nechte prázdné pro přeskočení)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Vyberte výrobce (nebo nechte prázdné pro přeskočení)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Číslo dílu výrobce" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Vybraná společnost není platný dodavatel" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Vybraná společnost není platný výrobce" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Výrobce dílu se stejným MPN již existuje" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Dodavatelský díl s tímto SKU již existuje" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Název kategorie" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Budova" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Množství tohoto dílu, které je v současné době ve výrobě" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Zbývající množství tohoto dílu, které má být postaveno" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Skladové položky" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Revize" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Celkem skladem" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Nezařazené zásoby" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Skladové varianty" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Duplikovat díl" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Kopírovat počáteční data z jiného dílu" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kopírovat obrázek" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Kopírovat obrázek z původního dílu" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Kopírovat kusovník" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Kopírovat kusovník z původního dílu" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Kopírovat poznámky" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Kopírovat poznámky z původního dílu" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Kopírovat testy" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Kopírovat testovací šablony z původního dílu" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Počáteční zásoby" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Vytvořit díl s počátečním množstvím zásob" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Informace o dodavateli" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Přidat počáteční informace dodavatele pro tento díl" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Kopírovat parametry kategorie" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Kopírovat šablony parametrů z vybrané kategorie dilu" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Stávající obrázek" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Název souboru existujícího obrázku dílu" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Obrázek neexistuje" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Schválit celý kusovník" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Lze postavit" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Vyžadováno pro výrobní objednávku" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Přířazeno výrobním objednávkám" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Vyžadováno pro prodejní objednávky" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Přiřazeno prodejním objednávkám" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "IPN dílu" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "Popis dílu" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "Vyberte díl u kterého chce vytvořit informace inventury (i pro jeho varianty)" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "Vyberte kategorii pro obsažení všech dílů v dané kategorii (a podkategoriích)" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "Vyberte lokaci pro obsažení všech dílů se zásobami na dané lokaci (včetně pod-lokací)" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "Generovat vstupy inventury" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "Uložit vstupy inventury pro vybrané díly" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "Generovat report" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "Generovat report inventury pro vybrané díly" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Minimální cena" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Přespat vypočítanou hodnotu pro minimální cenu" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Měna minimální ceny" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Maximální cena" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Přespat vypočítanou hodnotu pro maximální cenu" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Měna maximální ceny" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Aktualizovat" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Aktualizovat cenu pro díl" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Nelze převést z poskytnutých měn na {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Minimální cena musí být vyšší než maximální cena" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Maximální cena nesmí být nížší než minimální cena" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "Množství vyžadováno pro tuto položku (může zahrnout jednotky)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Vybrat nadřazenou sestavu" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Vyberte komponentu dílu" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "Neplatný formát množství" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Vyberte díl pro kopírování kusovníku z" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Odstranit existující data" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Odstranit existující položky kusovníku před kopírováním" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Zahrnout zděděné" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Zahrnout položky kusovníku které jsou zdědené z šablonových dílů" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Přeskočit neplatné řádky" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Povolte tuto možnost pro přeskočení neplatných řádků" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Kopírovat náhradní díly" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopírovat náhradní díly při duplikaci položek kusovníku" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Oznámení o nízkých zásobách" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Dostupné zásoby pro {part.name} klesly pod nastavenou minimální úroveň" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "Oznámení o zastaralých zásobách" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "Máte 1 skladovou položku blížící se k datu expirace" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "Máte skladem {item_count} položek, jejichž data expirace se blíží" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "Bez data expirace" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "Expirovalo před {abs(days_diff)} dny" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Expiruje dnes" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} dní" @@ -7011,7 +7451,7 @@ msgstr "Příklad" msgid "Installed" msgstr "Nainstalováno" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Plugin nemůže být odstraněn, protože je aktuálně aktivní" @@ -7023,23 +7463,23 @@ msgstr "Činnost nebyla specifikována" msgid "No matching action found" msgstr "Nebyla nalezena odpovídající činnost" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Pro data čárového kódu nebyla nalezena shoda" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Pro data čárového kódu byla nalezena shoda" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Model není podporován" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Instance modelu nebyla nalezena" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Čárový kód odpovídá existující položce" @@ -7055,51 +7495,67 @@ msgstr "Žádné odpovídající díly dodavatelů nebyly nalezeny" msgid "Multiple matching supplier parts found" msgstr "Vícero odpovídajících dílů dodavatelů bylo nalezeno" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "Nemáte dostatečná oprávnění pro nákupní objednávky" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Žádný odpovídající plugin pro čárové kódy nebyl nalezen" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Odpovídající díl dodavatele" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Položka již byla obdržena" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "Objednávka nenašela\\rŽádnou shodu dílu dodavatele" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "Díl dodavatele nenašel\\rŽádnou shodu objednávky" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Žádný plugin neodpovídá čárový kód dodavatele" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Vícero odpovídajících řádkových položek bylo nalezeno" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Žádná odpovídající řádková položka nebyla nalezena" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "Nemáte dostatečná oprávnění pro prodejní objednávky" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Žádná prodejní objednávka nebyla poskytnuta" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Čárový kód neodpovídá žádné existující skladové položce" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Skladová položka se neshoduje s řádkovou položkou" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Nedostatečný počet zásob" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Skladová položka byla přidělena prodejní objednávce" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Nedostatek informací" @@ -7108,23 +7564,23 @@ msgstr "Nedostatek informací" msgid "Found matching item" msgstr "Nalezena odpovídající položka" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Dodavatelská položka se neshoduje s řádkovou položkou" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Řádková položka je již dokončena" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Další informace potřebné k přijetí položky" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Obdržené položky objednávky" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Nepodařilo se přijmout řádkovou položku" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Poskytuje nativní podporu pro čárové kódy" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Předpona krátkého čárového kódu" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Přizpůsobit předponu využívanou pro krátké čárové kódy, může být užitečné pro prostředtí s více instancemi InvenTree" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "Automaticky vytvářet sestavy" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "Automaticky vytvářet požadavky pro sestavení pro výrobní linky" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "Zahrnout varianty předmětu" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "Zahrnout varianty dílu při výpočtu cen" +msgid "Include part variant stock in stocktake data" +msgstr "Zahrnout variantu zásoby do údajů o inventuře" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "Vyloučit nulové položky" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "Vyloučit díly které mají nulové zásoby z exportovaného datasetu" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "Exportér inventury dílu" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "Exportér pro data inventury dílu" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "Minimální cena jednotky" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "Maximální cena jednotky" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "Minimální celková cena" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "Maximální celková cena" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "Oznámení InvenTree UI" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "Integrovaná metoda oznámení UI" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree emailová notifikace" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "Integrovaná metoda notifikace emailem" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "Povolit emailové notifikace" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "Povolí posílat emailové notifikace tomuto uživateli" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree Slack notifikace" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "Integrovaná metoda notifikace Slack" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "URL příchozího Slack Webhooku" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "ULR využívána k posílání zpráv do slack kanálu" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Otevřít odkaz" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Poskytuje nativní podporu pro tisk PDF štítků" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Režim ladění" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Povolit režim ladění - vrátí HTML místo PDF" @@ -7653,55 +8117,55 @@ msgstr "naposledy použito" msgid "Options" msgstr "Možnosti" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Velikost stránky pro štítek" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Přeskočit štítky" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Přeskočit tento počet štítků při tisku listů štítků" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Rámeček" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Vytisknout okraj kolem každého štítku" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Na šířku" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Vytisknout list štítků na šířku" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Okraj stránky" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Okraj kolem stránky v mm" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree tiskárna listů štítků" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Sestaví více štítků na jeden list" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Štítek je příliš velký pro velikost stránky" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Nebyly vygenerovány žádné štítky" @@ -7753,77 +8217,85 @@ msgstr "Poskytuje podporu pro skenování TME čárových kódů" msgid "The Supplier which acts as 'TME'" msgstr "Dodavatel, který funguje jako 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "Pip není nainstalováno v aktuálním prostředí" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "Pouze superuživatelské účty mohou spravovat pluginy" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Instalace pluginu je zakázana" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "Neplatná URL a nezadaný název balíčku" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "Není k dispozici žádný název balíčku nebo URL pro instalaci" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "Neplatné znaky v názvu balíčku nebo v URL" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Plugin byl úspěšně nainstalován" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin nainstalovaný do {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Plugin nebyl nalezen v registru" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Plugin není plugin balíček" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Název balíčku pluginu nebyl nalezen" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Pouze pracovníci mohou spravovat pluginy" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Odinstalace pluginu je zakázána" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Plugin nemůže být odinstalován, protože je aktuálně aktivní" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Plugin nemůže být odinstalován, protože je povinný" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Plugin nemůže být odinstalován, protože to je vzorový plugin" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "Plugin nemůže být odinstalován, protože to je vestavěný plugin" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Plugin není nainstalován" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Inslalace pluginu nebyla nalezena" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Plugin odinstalován úspěšně" @@ -7871,25 +8343,25 @@ msgstr "Povinný plugin" msgid "Package Plugin" msgstr "Balíčkový plugin" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Nebyl nalezen žádný autor" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Plugin '{p}' není kompatibilní s aktuální verzí InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Plugin vyžaduje alespoň verzi {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plugin vyžaduje nanejvýš verzi {v}" @@ -8114,176 +8586,184 @@ msgstr "Odstranit nastavení" msgid "Delete the plugin configuration from the database" msgstr "Odstranit konfiguraci pluginu z databáze" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "Indikuje zdali je nastavení přepsáno konfigurací" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "Uživatel pro kterého platí toto nastavení" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Položky" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Plugin nebyl nalezen" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Plugin nepodporuje tisk štítků" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "Nemáte oprávnění pro zobrazení modelu tohoto typu" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Neplatné rozměry štítku" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Žádné platné položky nebyly k šabloně poskytnuté" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Letter" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Šablona s tímto názvem již existuje" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Název šablony" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Popis šablony" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Číslo revize (automatické navýšení)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Připojit k modelu při tisku" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Uložit výstup reportu jako přílohu v instanci propojeného modelu při tisku" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Šablona pro názvy souborů" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Šablona pro generování názvů souborů" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Šablona je povolena" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Cílový typ modelu pro šablonu" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtry" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Filtry dotazů šablon (čárkou oddělený seznam klíčových=dvojic hodnot)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Vzorový soubor" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Velikost stránky pro PDF reporty" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Vykreslit report v orientaci na šířku" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "Sloučit" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "Vykreslit jeden report proti vybraným položkám" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Report generován ze šablony {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "Chyba syntaxe šablony" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "Chyba při vykreslování reportu" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Chyba při generování reportu" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "Chyba při slučování výstupů reportu" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Šířka [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Šířka štítku zadaná v mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Výška [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Výška štítku uvedená v mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Chyba při tisku štítků" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Úryvek" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Nahlásit soubor úryvku" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Popis souboru úryvku" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Aktivum" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Nahlásit soubor aktiva" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Popis souboru aktiva" @@ -8291,23 +8771,23 @@ msgstr "Popis souboru aktiva" msgid "User must be authenticated to save report templates" msgstr "Uživatel musí být ověřen pro uložení šablon reportu" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Vybrat šablonu reportu" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Seznam primárních klíčů k zahrnutí v reportu" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Vybrat šablonu pro štítek" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Tiskový plugin" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Vybrat plugin pro tisk štítků" @@ -8338,13 +8818,10 @@ msgstr "Potřebné materiály" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Obrázek dílu" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Vydáno" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Vyžadováno pro" @@ -8380,8 +8857,8 @@ msgstr "Celkem" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Sériové číslo" @@ -8405,7 +8882,7 @@ msgstr "Report o testu skladové položky" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Instalované položky" @@ -8438,810 +8915,922 @@ msgstr "Žádný výsledek (povinný)" msgid "No result" msgstr "Žádný výsledek" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "Převedeno" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "Neplatná cesta k media souboru" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "Neplatná cesta ke statickému souboru" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "Soubor aktiva nebyl nalezen" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Soubor obrázku nebyl nalezen" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "Nebyl zadán žádný obrázek" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image tag vyžaduje instanci dílu" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image tag vyžaduje intanci společnosti" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Filtrovat dle hloubky lokace" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Filtrovat dle nejvyšší lokace" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Zahrnout pod-lokace ve filtrovaných výsledcích" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Nadřazená místo" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filtrovat podle nadřazené lokace" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Název dílu (citlivost písmen na malá a velká písmena)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Název dílu obsahuje (citlivost písmen na malá a velká písmena)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Název dílu (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "IPN dílu (citlivost písmen na malá a velká písmena)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "IPN dílu obsahuje (citlivost písmen na malá a velká písmena)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "IPN dílu (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Minimální zásoby" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Maximální zásoby" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Kód stavu" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Externí umístění" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Spotřebováno výrobním příkazem" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Nainstalováno v jiné skladové položce" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Strom dílů" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Aktualizováno před" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Aktualizováno po" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Inventura před" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Inventura po" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "Má datum inventury" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Datum expirace ped" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Datum expirace po" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Zastaralé" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "Zadejte PK skladové položky, abyste vyloučili danou položku a všechny její potomky" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "Umístění kaskády" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "Pokud je pravda, uveďte předměty v podružených místech dané lokace" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Filtrovat podle numberické ID lokace nebo doslovného 'null'" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Množství je povinné" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Platný díl musí být dodán" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Daný dodavatelský díl neexistuje" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Dodavatelský díl na nastavenou velikost balení, ale znak use_pack_size není nastaven" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Sériové čísla nemohou být zadána pro díl bez sledovanosti" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "Zahrnout nainstalované" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Pokud je pravda, zahrne výslekdy testů pro předměty nainstalované pod danou skladovou položku" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "Filtrovat podle číselného ID položky skladu" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Skladová položka s ID {id} neexistuje" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "Zahrnout varianty" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "Datum po" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "Datum před" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Typ skladového umístění" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Typy skladových umístění" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Výchozí ikona pro všechny lokace které nemají ikonu nastavenou (volitelné)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Skladové umístění" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Skladová umístění" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Správce" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Vybrat vlastníka" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Skladové položky nelze umístit přímo do strukturálních skladových umístění, ale lze je umístit do podřízených skladových umístění." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Externí" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Toto je externí skladové umístění" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Typ umístění" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Typ tohoto skladového umístění" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Toto skladové umístění nemůžete označit jako strukturální, protože již obsahuje skladové položky!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "Nejstarší zásoby první (FIFO)" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "Nejnovější zásoby první (LIFO)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "Nejmenší množství první" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "Největší množství první" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "Nejbližší datum expirace první" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "Serializované zásoby nelze odstranit" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field} neexistuje" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Díl musí být zadán" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Skladové položky nelze umístit do strukturálních skladových umístění!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "Úprava sériových čísel není povoleno - této položce již bylo přiřazeno sériové číslo" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Nelze vytvořit skladovou položku pro virtuální díl" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Typ dílu ('{self.supplier_part.part}') musí být {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Množství musí být 1 pro položku se sériovým číslem" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Sériové číslo nemůže být nastaveno, když množství je více než 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Položka nemůže patřit sama sobě" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Předmět musí mít stavební referenci pokud is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Stavební reference neukazuje na stejný objekt dílu" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Nadřazená skladová položka" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Základní díl" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Vyberte odpovídající díl dodavatele pro tuto skladovou položku" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Kde se tato skladová položka nachází?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Balení, ve kterém je tato skladová položka uložena" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Instalováno v" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Je tato položka nainstalována v jiné položce?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Sériové číslo pro tuto položku" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Kód šarže pro tuto skladovou položku" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Mnižství" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Zdrojová sestavení" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Postavit pro tuto skladovou položku" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Použito v" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Výrobní příkaz, který spotřeboval tuto skladovou položku" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Zdrojová nákupní objednávka" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Nákupní objednávka pro tuto skladovou položku" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Cílová prodejní objednávka" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Datum expirace pro skladovou položku. Po tomto datu bude položka brána jako expirovaná" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "Datum, kdy byla tato zásoba vytvořena" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Odstranit po vyčerpání" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Odstranit tuto skladovou položku po vyčerpání zásob" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Jednotková kupní cena v okamžiku nákupu" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Převedeno na díl" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "Množství přesahuje dostupné zásoby" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "Neplatné množství" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "Nelze přiřadit zásoby ke strukturálnímu umístění" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "Množství nesmí překročit dostupné skladové množství" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "Serializované skladové položky musí být rozebrány v celém rozsahu" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "Nebyly zadány žádné řádky BOM" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "Položka s instalovanými položkami musí být rozebrána v celém rozsahu" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Díl není nastaven jako sledovatelný" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Množstvní musí být celé číslo" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Množství nesmí překročit dostupné množství zásob ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Sériové čísla musí být poskytnuta jako seznam" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Množství neodpovídá sériovým číslům" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "Nelze přiřadit zásoby ke strukturálnímu umístění" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Testovací šablona neexistuje" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Skladová položka byla přidělena prodejní objednávce" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Skladová položka je nainstalována v jiné položce" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Skladová položka obsahuje jiné položky" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Skladová položka byla přidělena zákazníkovi" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Skladová položka je ve výrobě" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Serializované zásoby nelze sloučit" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Duplicitní skladové položky" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Skladové položky musí odkazovat na stejný díl" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Skladové položky musí odkazovat na stejný díl dodavatele" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Kódy stavu zásob se musí shodovat" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Zásobová položka nemůže být přesunuta, protože není skladem" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Sledování skladových položek" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Poznámky k záznamu" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Výsledek testu skladové položky" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Pro tuto zkoušku musí být uvedena hodnota" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Pro tento test musí být nahrána příloha" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "Neplatná hodnota pro tento test" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Výsledek testu" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Výstupní hodnota testu" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Příloha výsledků testu" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Poznámky testu" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Testovací stanice" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "Identifikátor testovací stanice kde byl test proveden" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Začátek" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Čas začátku testu" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Ukončeno" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Čas dokončení testu" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Vygenerovaný kód šarže" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Vyberte výrobní příkaz" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Vyberte skladovou položku, pro kterou se má vygenerovat kód šarže" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Vyberte umístění, pro které se má vygenerovat kód šarže" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Vyberte díl, pro který se má vygenerovat kód šarže" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Vyberte nákupní objednávku" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Zadejte množství pro kód dávky" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Vygenerované sériové číslo" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Vyberte díl, pro který se má vygenerovat sériové číslo" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Množství sériových čísel k vygenerování" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Testovací šablona pro tento výsledek" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "Pro tento díl nebyl nalezen žádný odpovídající test" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "ID šablony nebo název testu musí být uveden" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "Čas ukončení testu nesmí být dřívější než čas zahájení testu" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Nadřazená položka" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Nadřazená skladová položka" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Použít velikost balení při přidání: definované množství je počet v balení" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "Použít velikost balení" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Zadejte sériová čísla pro nové položky" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Číslo dílu dodavatele" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Expirováno" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Podřízené položky" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Sledování položky" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Nákupní cena této skladové položky za jednotku nebo balení" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Zadejte počet skladových položek k serializaci" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "Nebyla poskytnuta žádná skladová položka" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Množství nesmí překročit dostupné skladové množství ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Cílové skladové umístění" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "K tomuto dílu nelze přiřadit sériová čísla" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Sériová čísla již existují" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Vyberte skladovou položku k instalaci" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Množství k instalaci" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Zadejte množství položek k instalaci" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Přidat poznámku o transakci (volitelné)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Množství k instalaci musí být alespoň 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Skladová položka je nedostupná" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Vybraný díl není v kusovníku" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Množství k instalaci nesmí překročit dostupné množství" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Cílové umístění pro odinstalovanou položku" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Vyberte díl pro převedení do skladové položky" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Vybraný díl není platnou volbou pro převod" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Nelze převést skladovou položku s přiřazeným dílem dodavetele" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Stavový kód skladové položky" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "BOM řádek, který definuje část komponenty pro vyřazení" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "Množství komponent k vytvoření" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "Cílové umístění pro komponenty položky" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "Stavový kód pro položky komponent" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "Jednotková cena pro položky komponent (nechte prázdné pro automatické přidělení nákladů)" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "Počet sestav k demontáži" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "Výchozí cílové místo pro komponenty položky" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "BOM položka není platná pro vybranou skladovou položku" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "Duplicitní BOM položky poskytnuty" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Vyberte díl pro převedení do skladové položky" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Vybraný díl není platnou volbou pro převod" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Nelze převést skladovou položku s přiřazeným dílem dodavetele" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Vybrat skladové položky pro změnu stavu" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Nejsou vybrány žádné skladové položky" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Podumístění" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "Odstranit skladové položky" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "Odstranit všechny skladové položky obsažené v této lokaci" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "Odstranit podkategorie" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "Odstranit všechny podkategorie obsažené v této lokaci" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Nadřazené skladové umístění" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Díl musí být prodejný" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Položka je přidělena prodejní objednávce" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "Položka je přiřazená v převodní objednávce" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Položka je přidělena výrobnímu příkazu" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Zákazník, kterému mají být přiděleny skladové položky" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Vybraná společnost není zákazník" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Poznámky ke skladové položce" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Musí být poskytnut seznam skladových položek" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Poznámky ke sloučení skladových položek" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Povolit neodpovídající dodavatele" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Povolit sloučení skladových položek s různými díly dodavatele" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Povolit neodpovídající stav" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Povolit sloučení skladových položek s různými stavovými kódy" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Musí být poskytnuty alespoň dvě skladové položky" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Beze změny" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Hodnota primárního klíče skladové položky" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Skladová položka není skladem" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "Skladová položka je již na skladě" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "Množství nesmí být záporné" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Poznámky ke skladovací transakci" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "Sloučit do existující zásoby" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "Sloučit tuto položku s existujícími zásobami v cílové destinaci, pokud je to možné" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Poznámky ke skladovací transakci" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "Nastavit umístění zásob pro počítané položky (volitelné)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "Sloučit vrácené položky do existujích položek, pokud je to možné" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Další sériové číslo" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Předchozí sériové číslo" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Skladové položky sloučeny" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "Rozloženo na komponenty" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "Vytvořeno z demontáže" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Převedeno na variantu" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Výstup výrobního příkazu vytvořen" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Výstup výrobního příkazu dokončen" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Výstup výrobního příkazu odmítnut" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Spotřebováno výrobním příkazem" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Odesláno na základě prodejní objednávky" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Přijato proti objednávce" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Vráceno proti vratce" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Odesláno zákazníkovi" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Vráceno od zákazníka" @@ -9527,19 +10124,19 @@ msgstr "Uživatelé" msgid "Select which users are assigned to this group" msgstr "Vyberte, kteří uživatelé jsou zařazeni do této skupiny" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Osobní údaje" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Oprávnění" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Důležité termíny" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Token byl zrušen" @@ -9547,279 +10144,283 @@ msgstr "Token byl zrušen" msgid "Token has expired" msgstr "Token vypršel" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API token" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API tokeny" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Název tokenu" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Uživatelský název tokenu" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Datum vypršení tokenu" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Naposledy aktivní" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Čas posledního použití tokenu" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Zrušeno" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Nastavení oprávnění" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Zobrazit" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Oprávnění k zobrazení položek" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Přidat" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Oprávnění přidat položky" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Změnit" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Oprávnění k úpravě položek" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Odstranit" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Oprávnění k odstranění položek" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Bot" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Interní" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Host" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Jazyk" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Preferovaný jazyk uživatele" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Motiv" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Nastavení webového rozhraní jako JSON - neupravujte ručně!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Widgety" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Nastavení widgetů hlavního panelu jako JSON - neupravujte ručně!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Zobrazované jméno" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Zvolené zobrazované jméno pro uživatele" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Pozice" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Název nebo funkce hlavního zaměstnání" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Zpráva statusu uživatele" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Informace o umístění uživatele" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "Uživatel aktivně používá systém" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Upřednostňované kontaktní údaje pro uživatele" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Typ uživatele" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "Jaký typ uživatele to je?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organizace" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Primární organizace / přidružení uživatelů" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Primární skupina" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Primární skupina uživatele" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Administrátor" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "Kusovník" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Zakoupené objednávky" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Prodejní objednávky" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Návratové objednávky" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "Převodní příkazy" + +#: users/serializers.py:196 msgid "Username" msgstr "Uživatelské jméno" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Křestní jméno" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Křestní jméno uživatele" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Příjmení" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Příjmení uživatele" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Emailová adresa uživatele" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "Uživatel musí být autentizován" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "Pouze superuživatel může vytvořit token pro jiného uživatele" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "Administrátor" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "Má tento uživatel administrativní oprávnění" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Super-uživatel" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Je tento uživatel superuživatel" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Je tento uživatelský účet aktivní" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Pouze superuživatel může toto pole upravit" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Heslo" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Heslo uživatele" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "Přepsat varování" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Přepsat varování o pravidlech pro heslo" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "Personál" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "Má tento uživatel oprávnění personálu" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Nemáte oprávnění k vytváření uživatelů" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Váš účet byl vytvořen." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Pro přihlášení použijte funkci obnovení hesla" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Vítejte v InvenTree" diff --git a/src/backend/InvenTree/locale/da/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/da/LC_MESSAGES/django.po index 8934869d8d..ae771ff7a1 100644 --- a/src/backend/InvenTree/locale/da/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/da/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Danish\n" "Language: da_DK\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API endpoint ikke fundet" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Elementer skal angives som en liste" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Alle filtre må kun bruges med sand" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Ingen data angivet" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Dette felt skal være unikt." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Bruger har ikke tilladelse til at se denne model" @@ -65,150 +69,155 @@ msgstr "Bekræftelse af e-mailadresse" msgid "You must type the same email each time." msgstr "Du skal indtaste den samme e-mail hver gang." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Den indtastede email adresse er ikke gyldig." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Det angivne e-mail domæne er ikke godkendt." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Ingen værdi angivet" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Kunne ikke konvertere {original} til {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Ugyldigt antal angivet" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Fejloplysninger kan findes i admin panelet" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Angiv dato" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Ugyldig decimalværdi" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Bemærkninger" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Værdi '{name}' vises ikke i mønsterformat" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Den angivne værdi matcher ikke det påkrævede mønster: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Kan ikke serialisere mere end 1000 elementer på én gang" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Serienummer streng er tom" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Duplikeret serienummer" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ugyldig gruppe: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Ingen serienumre fundet" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Antal unikke serienumre ({n}) skal matche antal ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Fjern HTML-tags fra denne værdi" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Data indeholder forbudt markdown indhold" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Forbindelsesfejl" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Serveren svarede med ugyldig statuskode" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Der opstod en fejl" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Serveren svarede med ugyldig Content-Length værdi" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Billedstørrelsen er for stor" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Billeddownload overskred maksimumstørrelsen" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Fjernserver returnerede tomt svar" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Angivet URL er ikke en gyldig billedfil" @@ -216,159 +225,203 @@ msgstr "Angivet URL er ikke en gyldig billedfil" msgid "Log in to the app" msgstr "Log ind på appen" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata skal være et python dict objekt" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON metadata felt, til brug af eksterne plugins" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Forkert formateret mønster" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Ukendt formatnøgle angivet" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Mangler nødvendig formatnøgle" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Referencefelt må ikke være tomt" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Reference skal matche det påkrævede mønster" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referencenummer er for stort" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Ugyldigt valg" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Navn" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Beskrivelse" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Beskrivelse (valgfri)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Sti" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown noter (valgfri)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Stregkode Data" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Tredjeparts stregkode data" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Stregkode Hash" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Unik hash af stregkode data" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Eksisterende stregkode fundet" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Serverfejl" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "En fejl blev logget af serveren." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Billede" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Skal være et gyldigt tal" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Vælg valuta fra tilgængelige muligheder" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Dette felt kan ikke være tomt." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Ugyldig værdi" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabisk" @@ -521,46 +574,48 @@ msgstr "Kinesisk (forenklet)" msgid "Chinese (Traditional)" msgstr "Kinesisk (traditionelt)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Opdatering tilgængelig" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "En opdatering til InvenTree er tilgængelig" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Ugyldig fysisk enhed" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Ikke en gyldig valutakode" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Ordre status" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Overordnet produktion" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Del" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategori" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Tildelt til Mig" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Tildelt Til" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Oprettet før" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Oprettet efter" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Har startdato" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Start dato før" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Start dato efter" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Produktion skal anulleres, før den kan slettes" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Forbrugsvare" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Valgfri" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Sporet" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Ordre Udestående" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Allokeret" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Tilgængelig" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Produktionsordre" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Lokation" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Produktionsordrer" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Monteringens stykliste er ikke blevet valideret" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Ansvarlig bruger eller gruppe skal specificeres" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Byggeordre enhed kan ikke ændres" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Produktionsordre reference" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Reference" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Vælg dele til produktion" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Salgsordrereference" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Kilde Lokation" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Vælg lokation for lager, som skal benyttes til denne produktion (lad feltet stå tomt for at benytte vilkårligt lager)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Ekstern Byg" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Denne byggeordre er gennemført eksternt" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Destinations Placering" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Vælg placering, hvor de færdige elementer vil blive gemt" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Produktions antal" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Antal lagervarer som skal produceres" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Afsluttede elementer" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Antal lagervarer som er færdiggjort" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Produktions Status" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Produktions statuskode" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Batch Kode" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Batch kode til dette produktions output" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Oprettelsesdato" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Planlagt startdato for denne byggeordre" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Projekteret afslutningsdato" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Dato for afslutning" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "udført af" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Udstedt af" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Bruger som udstedte denne byggeordre" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ansvarlig" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Bruger eller gruppe ansvarlig for denne byggeordre" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Ekstern link" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link til ekstern URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Bygge Prioritet" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Prioritet af denne byggeordre" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Projektkode" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Projektkode for denne byggeordre" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Bygningsordre {build} er fuldført" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "En byggeordre er fuldført" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Tilgængeligt antal ({q}) overskredet" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Antal" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Lagervarer" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Kilde lagervare" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Del Navn" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Serienummer" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Indtast serienumre for bygge output" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Automatisk alloker serienumre" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Følgende serienumre findes allerede eller er ugyldige" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Ikke tilladt" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Accepter som forbrugt af denne byggeordre" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Accepter Ikke tildelt" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Accepter at lagervarer ikke er fuldt tildelt til denne byggeordre" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Accepter ufuldført" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Bygge linje" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Varen skal være på lager" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Tilgængeligt antal ({q}) overskredet" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Stykliste Reference" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "Stykliste del ID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Stykliste Del Navn" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Byg" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Leverandør Del" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Tildelt Antal" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Stykliste Del" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "I Produktion" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Ekstern Lager" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Tilgængelig Lager" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Afventende" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Produktion" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "På Hold" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Annulleret" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Fuldført" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Bygningsordre {build} er fuldført" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "En byggeordre er fuldført" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "Ingen plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Projekt Kode Label" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Opdateret" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "Unik projekt kode" msgid "Project description" msgstr "Projektbeskrivelse" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Værdien skal være en boolsk værdi" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Værdi skal være et heltalsværdi" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Skal være et gyldigt tal" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Værdien består ikke valideringskontrol" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Nøglestrengen skal være unik" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Bruger" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Pris" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktiv" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Værdien skal være en boolsk værdi" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Værdi skal være et heltalsværdi" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Skal være et gyldigt tal" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Værdien består ikke valideringskontrol" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Nøglestrengen skal være unik" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Bruger" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Pris" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token for adgang" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Hemmelighed" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Besked ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Vært" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Vært, hvorfra denne meddelelse blev modtaget" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Overskrift" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Overskrift for denne besked" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Titel" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Tilknytning" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publiceret" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Forfatter" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Opsummering" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Læs" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Blev dette nyhedselement læst?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Billedfil" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Vedhæftning" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Manglende fil" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Manglende eksternt link" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Vælg fil, der skal vedhæftes" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "Filstørrelse" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "Filstørrelse i bytes" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Filstørrelse" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "Filstørrelse i bytes" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Værdi" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Numerisk værdi, der vil blive gemt i modeldatabasen" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Label" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Farve" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Farve der vil blive vist på frontend" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Låst" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Parameter skabelon navn skal være unikt" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Stregkode Scan" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Stregkode data" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Sendt" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Fejlede" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Leveret" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Bekræftet" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Indkommende" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Udgående" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Intet Svar" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Spor Levering" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Spor Læst" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Spor Klik" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "Global ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Identifikator for denne meddelelse (leveres muligvis af et eksternt system)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "Tråd ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "E-mail Tråd" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "E-mail Tråde" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Nøgle" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Filnavn" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "Valuta Opdaterings Interval" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Placeret" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Datafil" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Afsendt" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Mistet" @@ -5718,1279 +6125,1312 @@ msgstr "Mistet" msgid "Returned" msgstr "Returneret" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Igangværende" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Retur" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Reparér" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Erstat" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Refusion" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Afvis" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree E-Mail Notifikationer" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "Integrerede E-mail notifikations metoder" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "Tillad E-mail notifikationer" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "Tillad at E-mail notifikationer sendes til denne bruger" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Flettede lagervarer" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Konverteret til variant" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Byggeordre output genereret" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Byggeorder output fuldført" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Brugt efter byggeordre" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Afsendt mod salgsordre" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Modtaget mod indkøbsordre" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Returneret mod returordre" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Sendt til kunde" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Returneret fra kunde" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Fornavn på brugeren" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Efternavn" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Efternavn på brugeren" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Email adresse på brugeren" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superbruger" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Er denne bruger en superbruger" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Er denne brugerkonto aktiv" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Kun en superbruger kan justere dette felt" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Adgangskode" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Brugers adgangskode" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "Tilsidesæt advarsel" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Tilsidesæt advarslen om adgangskode regler" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Du har ikke tilladelse til at oprette brugere" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Din konto er oprettet." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Benyt funktionen til nulstilling af adgangskode til at logge ind" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Velkommen til InvenTree" diff --git a/src/backend/InvenTree/locale/de/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/de/LC_MESSAGES/django.po index 227a6855f3..5869f12ee7 100644 --- a/src/backend/InvenTree/locale/de/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/de/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API-Endpunkt nicht gefunden" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Elemente müssen als Liste angegeben werden" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Ungültige Artikelliste angegeben" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Alle Filter dürfen nur mit true verwendet werden" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Keine Gegenstände erfüllen die vorgegebenen Kriterien" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Keine Daten verfügbar" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Dieses Feld muss eindeutig sein." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Benutzer hat keine Berechtigung, dieses Modell anzuzeigen" @@ -65,150 +69,155 @@ msgstr "Bestätigung der E-Mail Adresse" msgid "You must type the same email each time." msgstr "E-Mail Adressen müssen übereinstimmen." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Die angegebene primäre E-Mail-Adresse ist ungültig." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Die angegebene E-Mail-Domain ist nicht freigegeben." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Ungültige Einheit angegeben ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Kein Wert angegeben" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Konnte {original} nicht in {unit} umwandeln" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Keine gültige Menge" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Fehlerdetails finden Sie im Admin-Panel" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Datum eingeben" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Ungültiger Dezimalwert" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Notizen" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Wert '{name}' hält das Musterformat nicht ein" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Angegebener Wert entspricht nicht dem benötigten Muster: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Kann nicht mehr als 1000 Elemente auf einmal serialisieren" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Keine Seriennummer angegeben" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Duplizierter Seriennummer" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ungültige Gruppe: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Gruppenbereich {group} überschreitet die zulässige Menge ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Keine Seriennummern gefunden" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Anzahl der eindeutigen Seriennummern ({n}) muss mit der Anzahl ({q}) übereinstimmen" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Entferne HTML-Tags von diesem Wert" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Daten enthalten verbotene Markdown-Inhalte" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Verbindungsfehler" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Server antwortete mit ungültigem Statuscode" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Ausnahme aufgetreten" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Server antwortete mit ungültigem Wert für die Inhaltslänge" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Bild ist zu groß" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Bilddownload überschreitet maximale Größe" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Remote-Server gab leere Antwort zurück" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Angegebene URL ist kein gültiges Bild" @@ -216,159 +225,203 @@ msgstr "Angegebene URL ist kein gültiges Bild" msgid "Log in to the app" msgstr "Bei der App anmelden" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Sie müssen die Zwei-Faktor-Authentifizierung aktivieren, bevor Sie etwas tun können." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Fehler beim Ausführen der Plugin Validierung" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadaten müssen ein Python-Dict Objekt sein" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Plugin Metadaten" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON-Metadatenfeld, für die Verwendung durch externe Plugins" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Falsch formatiertes Muster" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Unbekannter Formatschlüssel angegeben" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Erforderlicher Formatschlüssel fehlt" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Referenz-Feld darf nicht leer sein" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referenz muss erforderlichem Muster entsprechen" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referenznummer ist zu groß" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Ungültige Auswahl" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Name" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Beschreibung" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Beschreibung (optional)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Pfad" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Doppelte Namen können nicht unter dem selben Elternteil existieren" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown Notizen (optional)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Barcode-Daten" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Drittanbieter-Barcode-Daten" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Barcode-Hash" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Eindeutiger Hash der Barcode-Daten" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Bestehender Barcode gefunden" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Serverfehler" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Ein Fehler wurde vom Server protokolliert." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Bild" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Muss eine gültige Nummer sein" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Währung" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Währung aus verfügbaren Optionen auswählen" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Dieses Feld darf nicht leer sein." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Ungültiger Wert" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "Content type stimmt nicht mit der benötigten Mixin-Klasse überein" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Parameter kopieren" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabisch" @@ -521,46 +574,48 @@ msgstr "Chinesisch (Vereinfacht)" msgid "Chinese (Traditional)" msgstr "Chinesisch (Traditionell)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Update verfügbar" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Ein Update für InvenTree ist verfügbar" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Ungültige physikalische Einheit" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Kein gültiger Währungscode" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Bestellstatus" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Eltern-Bauauftrag" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Varianten einschließen" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Varianten einschließen" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Varianten einschließen" msgid "Part" msgstr "Teil" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategorie" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Vorgänger-Build" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Mir zugewiesen" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Zugewiesen zu" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Erstellt vor" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Erstellt nach" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Hat Startdatum" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Gültigkeitsdauer vor" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Gültigkeitsdauer nach" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "geplantes Bestelldatum" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Zieldatum vor" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Zieldatum nach" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Abgeschlossen vor" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Abgeschlossen nach" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Baum ausschließen" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Bauauftrag muss abgebrochen werden, bevor er gelöscht werden kann" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Verbrauchsmaterial" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Optional" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Baugruppe" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Nachverfolgt" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Prüfbar" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Offene Bestellung" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Zugeordnet" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Verbraucht" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Verfügbar" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Bestellt" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Bauauftrag" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Lagerort" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Bauprodukt" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Bauaufträge" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Die Stückliste wurde noch nicht kontrolliert" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Baureihenfolge kann nicht für ein inaktives Teil erstellt werden" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Baureihenfolge kann nicht für ein inaktives Teil erstellt werden" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Verantwortlicher Benutzer oder Gruppe muss angegeben werden" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Teil in Bauauftrag kann nicht geändert werden" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Zieldatum muss nach dem Startdatum liegen" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Bauauftragsreferenz" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referenz" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Kurze Beschreibung des Baus (optional)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Teil für den Bauauftrag wählen" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Auftrag Referenz" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Quell-Lagerort" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Entnahme-Lagerort für diesen Bauauftrag wählen (oder leer lassen für einen beliebigen Lagerort)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Ziel-Lagerort" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Lagerort an dem fertige Objekte gelagert werden auswählen" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Bau-Anzahl" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Anzahl der zu bauenden Lagerartikel" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Fertiggestellte Teile" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Anzahl der fertigen Lagerartikel" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Bauauftrags-Status" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Bau-Statuscode" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Losnummer" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Losnummer für dieses Endprodukt" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Erstelldatum" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Startdatum des Bauauftrags" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Geplantes Startdatum des Bauauftrags" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "geplantes Fertigstellungsdatum" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Zieldatum für Bauauftrag-Fertigstellung." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Fertigstellungsdatum" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "Fertiggestellt von" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Aufgegeben von" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Nutzer der diesen Bauauftrag erstellt hat" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Verantwortlicher Benutzer" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Benutzer oder Gruppe verantwortlich für diesen Bauauftrag" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Externer Link" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link zu einer externen URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Bauauftrags-Priorität" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Priorität dieses Bauauftrags" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Projektcode" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Projektcode für diesen Auftrag" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Fehler beim Abladen der Aufgabe, um die Build-Allokation abzuschließen" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Bauauftrag {build} wurde fertiggestellt" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Ein Bauauftrag wurde fertiggestellt" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Seriennummern müssen für nachverfolgbare Teile angegeben werden" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "kein Endprodukt angegeben" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Endprodukt bereits hergstellt" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Endprodukt stimmt nicht mit dem Bauauftrag überein" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Anzahl muss größer Null sein" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Menge kann nicht größer als die Ausgangsmenge sein" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Build Ausgabe {serial} hat nicht alle erforderlichen Tests bestanden" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Verfügbare Menge ({q}) überschritten" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Bauauftragsposition" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Objekt bauen" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Objekt bauen" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Anzahl" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Erforderliche Menge für Auftrag" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Bauauftragsposition muss ein Endprodukt festlegen, da der übergeordnete Teil verfolgbar ist" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Ausgewählter Lagerbestand stimmt nicht mit BOM-Linie überein" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Anzahl muss 1 für Objekte mit Seriennummer sein" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Zugewiesene Menge ({q}) darf nicht verfügbare Menge ({a}) übersteigen" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "BestandObjekt ist zu oft zugewiesen" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Lagerartikel" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Quell-Lagerartikel" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Anzahl an Lagerartikel dem Bauauftrag zuweisen" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Installiere in" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Ziel-Lagerartikel" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Name des Teils" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Endprodukt" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Endprodukt stimmt nicht mit übergeordnetem Bauauftrag überein" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Endprodukt entspricht nicht dem Teil des Bauauftrags" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Dieses Endprodukt wurde bereits fertiggestellt" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Dieses Endprodukt ist nicht vollständig zugewiesen" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Menge der Endprodukte angeben" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Ganzzahl für verfolgbare Teile erforderlich" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Ganzzahl erforderlich da die Stückliste nachverfolgbare Teile enthält" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Seriennummer" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Seriennummer für dieses Endprodukt eingeben" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Lagerort für Bauprodukt" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Seriennummern automatisch zuweisen" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Benötigte Lagerartikel automatisch mit passenden Seriennummern zuweisen" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Die folgenden Seriennummern existieren bereits oder sind ungültig" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Eine Liste von Endprodukten muss angegeben werden" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Lagerort für ausgemusterte Ausgänge" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Zuteilungen verwerfen" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Bestandszuteilung für ausgemusterte Endprodukte verwerfen" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Grund für das Verwerfen des Bauauftrages/der Bauaufträge" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Lagerort für fertige Endprodukte" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Unvollständige Zuweisung akzeptieren" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Endprodukte fertigstellen, auch wenn Bestand nicht fertig zugewiesen wurde" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Zugewiesen Bestand verbrauchen" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Verbrauche alle Bestände, die diesem Bauauftrag bereits zugewiesen wurden" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Unfertige Endprodukte entfernen" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Lösche alle noch nicht abgeschlossenen Endprodukte" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Nicht erlaubt" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Als von diesem Bauauftrag verbraucht setzen" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Bestandszuordnung vor dem Abschluss dieses Bauauftrags freigeben" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Überbelegter Lagerbestand" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Wie sollen zusätzliche Lagerbestandteile, die dem Bauauftrag zugewiesen wurden, behandelt werden" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Der Bestand einiger Lagerartikel ist überbelegt" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Nicht zugewiesene akzeptieren" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Akzeptieren, dass Lagerartikel diesem Bauauftrag nicht vollständig zugewiesen wurden" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Benötigter Bestand wurde nicht vollständig zugewiesen" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Unvollständig Zuweisung akzeptieren" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Akzeptieren, dass die erforderliche Anzahl der Bauaufträge nicht abgeschlossen ist" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Benötigte Teil-Anzahl wurde noch nicht fertiggestellt" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Bauauftrag hat unvollständige Aufbauten" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Bauauftragsposition" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Endprodukt" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Endprodukt muss auf den gleichen Bauauftrag verweisen" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Bauauftragspositionsartikel" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part muss auf dasselbe Teil verweisen wie der Bauauftrag" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Teil muss auf Lager sein" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Verfügbare Menge ({q}) überschritten" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Für Zuweisung von verfolgten Teilen muss ein Endprodukt angegeben sein" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Endprodukt kann bei Zuweisung nicht-verfolgter Teile nicht angegeben werden" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Zuweisungen müssen angegeben werden" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Lagerort, von dem Teile bezogen werden sollen (leer lassen, um sie von jedem Lagerort zu nehmen)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Lagerort ausschließen" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Lagerartikel vom ausgewählten Ort ausschließen" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Wechselbares Lagerbestand" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Lagerartikel an mehreren Standorten können austauschbar verwendet werden" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Ersatzbestand" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Zuordnung von Ersatzteilen erlauben" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Optionale Positionen" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Optionale Stücklisten-Positionen dem Bauauftrag hinzufügen" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "Alle Artikel" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "Unverfolgte Artikel" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "Verfolgte Artikel" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "Item-Typ" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "Elementtyp zur automatischen Zuweisung auswählen" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Stücklisten-Referenz" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "Stückliste Teil-ID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Stückliste Teil-Name" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Zusammenbau" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Zuliefererteil" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Zugewiesene Menge" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Teilkategorienname" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Nachverfolgbar" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Vererbt" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Varianten zulassen" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Stücklisten-Position" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "In Produktion" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Geplant zum Erstellen" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Externes Lager" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Verfügbarer Bestand" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Verfügbares Ersatzmaterial" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Verfügbarer Varianten Lagerbestand" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "Verbrauchsmenge überschreitet die zugewiesene Menge" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Optionale Notizen für den Bestandsverbrauch" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Dupliziere Bauauftrag Artikelzuordnung" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Mindestens ein Element oder eine Zeile muss angegeben werden" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Ausstehend" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "in Arbeit" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Pausiert" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Storniert" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Fertig" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Bauauftrag {build} wurde fertiggestellt" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Ein Bauauftrag wurde fertiggestellt" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Bestand für Bauauftrag erforderlich" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Bauauftrag {build} erfordert zusätzlichen Bestand" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Überfälliger Bauauftrag" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Bauauftrag {bo} ist jetzt überfällig" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "Link" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Datei" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Benutzer hat keine Berechtigung zum Löschen der Anhänge" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Benutzer hat keine Berechtigung zum Löschen des Anhangs" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Ungültiges Währungskürzel" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "Kein Plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Aktualisiert" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Zeitstempel der letzten Aktualisierung" @@ -1567,794 +1674,844 @@ msgstr "Eindeutiger Projektcode" msgid "Project description" msgstr "Projektbeschreibung" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Benutzer oder Gruppe verantwortlich für dieses Projekt" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Einstellungs-Wert" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Wert ist keine gültige Option" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Wahrheitswert erforderlich" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Nur Ganzzahl eingeben" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Schlüsseltext muss eindeutig sein" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Benutzer" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Preisstaffelungs Anzahl" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Preis" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Stückpreis für die angegebene Anzahl" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Endpunkt" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Endpunkt, an dem dieser Webhook empfangen wird" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Name für diesen Webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktiv" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Benutzer oder Gruppe verantwortlich für dieses Projekt" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Einstellungs-Wert" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Wert ist keine gültige Option" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Wahrheitswert erforderlich" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Nur Ganzzahl eingeben" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Schlüsseltext muss eindeutig sein" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Benutzer" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Preisstaffelungs Anzahl" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Preis" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Stückpreis für die angegebene Anzahl" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Endpunkt" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Endpunkt, an dem dieser Webhook empfangen wird" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Name für diesen Webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Ist dieser Webhook aktiv" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token für Zugang" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Geheimnis" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Shared Secret für HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Nachrichten-ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Eindeutige Kennung für diese Nachricht" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Host" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Host von dem diese Nachricht empfangen wurde" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Kopfzeile" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Header dieser Nachricht" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Body" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Body dieser Nachricht" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Endpunkt, über den diese Nachricht empfangen wurde" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Bearbeitet" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Wurde die Arbeit an dieser Nachricht abgeschlossen?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "ID" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Titel" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Veröffentlicht" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Zusammenfassung" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Gelesen" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Wurde diese Nachricht gelesen?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Bilddatei" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Benutzerdefinierte Einheit" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Einheitensymbol muss eindeutig sein" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Einheitsname muss eine gültige Kennung sein" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Einheitsname" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Optionales Einheitssymbol" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definition" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Einheitsdefinition" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Anhang" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Fehlende Datei" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Fehlender externer Link" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Modelltyp" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Datei zum Anhängen auswählen" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Upload Datum" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Datum der hochgeladenen Datei" -#: common/models.py:2118 -msgid "File size" -msgstr "Dateigröße" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "Dateigröße in Bytes" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "Ungültiger Modelltyp für Anhang angegeben" - -#: common/models.py:2177 -msgid "Custom State" +#: common/models.py:2178 +msgid "Is image" msgstr "" -#: common/models.py:2178 -msgid "Custom States" +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Dateigröße" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "Dateigröße in Bytes" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "Ungültiger Modelltyp für Anhang angegeben" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Wert" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Name des Bundeslandes" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Bezeichnung" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Bezeichnung, die im Frontend angezeigt wird" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Farbe" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Farbe, die im Frontend angezeigt wird" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Name muss sich von den Namen des Referenzstatus unterscheiden" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Auswahlliste" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Auswahllisten" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Name der Auswahlliste" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Beschreibung der Auswahlliste" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Gesperrt" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Ist diese Auswahlliste gesperrt?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Kann diese Auswahlliste benutzt werden?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Standardeintrag" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Erstellt" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Zuletzt aktualisiert" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Parameter Vorlage" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Checkbox-Parameter können keine Einheiten haben" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Checkbox-Parameter können keine Auswahl haben" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Auswahl muss einzigartig sein" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Name des Parameters" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Einheiten" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Physikalische Einheiten für diesen Parameter" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Parameter-Beschreibung" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Checkbox" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Ist dieser Parameter eine Checkbox?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Auswahlmöglichkeiten" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Gültige Optionen für diesen Parameter (durch Kommas getrennt)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Aktiviert" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Ungültige Auswahl für Parameterwert" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Vorlage" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Wert" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Parameter Wert" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Notiz" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Optionales Notizfeld" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Barcode Scan" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Zeitstempel" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Kontext" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Ergebnis" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Angekündigt" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Gesendet" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Fehlgeschlagen" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Zugestellt" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Bestätigt" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Eingehend" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Ausgehend" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Keine Rückmeldung" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Schlüssel" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} storniert" msgid "A order that is assigned to you was canceled" msgstr "Eine Bestellung, die Ihnen zugewiesen war, wurde storniert" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Artikel erhalten" @@ -2388,104 +2545,100 @@ msgstr "Artikel wurden aus einer Bestellung erhalten" msgid "Items have been received against a return order" msgstr "Artikel wurden aus einer Rücksendung erhalten" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Wird ausgeführt" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Anstehende Aufgaben" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Geplante Aufgaben" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Fehlgeschlagene Aufgaben" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Aufgabe-ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Eindeutige Aufgaben-ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Sperren" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Sperrzeit" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Aufgabenname" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funktion" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Funktionsname" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Parameter" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Aufgaben-Parameter" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Schlüsselwort Parameter" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Schlüsselwort Parameter für Aufgaben" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Dateiname" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Modelltyp" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Benutzer hat keine Berechtigung, Anhänge für dieses Modell zu erstellen oder zu bearbeiten" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "Keine Gruppe" @@ -2614,13 +2767,13 @@ msgstr "Währungsaktualisierungsintervall" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Wie oft Wechselkurse aktualisiert werden sollen (auf Null zum Deaktivieren setzen)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "Tage" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Zu verwendendes Währungs-Aktualisierungs-Plugin" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Strenge URL-Prüfung" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Artikelrevisionen" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Revisions-Feld für Artikel aktivieren" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Löschen aus Baugruppe erlauben" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Erlaube das Löschen von Teilen, die in einer Baugruppe verwendet werden" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "RegEx Muster für die Zuordnung von Teil-IPN" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Mehrere Artikel mit gleicher IPN erlaubt" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Mehrere Artikel mit gleicher IPN erlaubt" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Ändern von IPN erlaubt" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Ändern der IPN während des Bearbeiten eines Teils erlaubt" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Teil-Stückliste kopieren" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Stückliste von Teil kopieren wenn das Teil dupliziert wird " -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Teil-Parameter kopieren" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Parameter-Daten für dieses Teil kopieren wenn das Teil dupliziert wird" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Teil-Testdaten kopieren" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Test-Daten für dieses Teil kopieren wenn das Teil dupliziert wird" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kategorie-Parametervorlage kopieren" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Kategorie-Parameter Vorlagen kopieren wenn ein Teil angelegt wird" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Teile sind standardmäßig Vorlagen" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Teile können standardmäßig aus anderen Teilen angefertigt werden" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponente" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Teile können standardmäßig in Baugruppen benutzt werden" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Kaufbar" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Artikel sind grundsätzlich kaufbar" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Verkäuflich" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Artikel sind grundsätzlich verkaufbar" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Artikel sind grundsätzlich verfolgbar" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuell" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Teile sind grundsätzlich virtuell" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Verwandte Teile anzeigen" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Verwandte Teile eines Teils anzeigen" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Initialer Lagerbestand" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Erstellen von Lagerbestand beim Hinzufügen eines neuen Teils erlauben" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Initiale Lieferantendaten" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Erstellen von Lieferantendaten beim Hinzufügen eines neuen Teils erlauben" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Anzeigeformat für Teilenamen" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Format für den Namen eines Teiles" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Standardsymbol der Teilkategorie" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Standardsymbol der Teilkategorie (leer bedeutet kein Symbol)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Dezimalstellen für minimalen Preis" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Mindestanzahl der Dezimalstellen bei der Darstellung der Preisdaten" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Dezimalstellen für maximalen Preis" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Maximale Anzahl der Dezimalstellen bei der Darstellung der Preisdaten" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Zulieferer-Preise verwenden" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Lieferanten-Staffelpreise in die Gesamt-Preisberechnungen einbeziehen" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Kaufverlauf überschreiben" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Historische Bestellungspreise überschreiben die Lieferanten-Staffelpreise" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Lagerartikel-Preis verwenden" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Preise aus manuell eingegebenen Lagerdaten für Preisberechnungen verwenden" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Lagerartikelpreis Alter" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Lagerartikel, die älter als diese Anzahl an Tagen sind, von der Preisberechnung ausschließen" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Variantenpreise verwenden" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Variantenpreise in die Gesamt-Preisberechnungen einbeziehen" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Nur aktive Varianten" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Nur aktive Variantenteile zur Berechnung der Variantenbepreisung verwenden" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Intervall für Neuberechnung von Preisen" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Anzahl der Tage bis die Teile-Preisberechnungen automatisch aktualisiert werden" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Interne Preise" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Interne Preise für Teile aktivieren" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Interne Preisüberschreibung" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Falls verfügbar, überschreiben interne Preise Preispannenberechnungen" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Labeldruck aktivieren" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Labeldruck über die Website aktivieren" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Label Bild DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "DPI-Auflösung bei der Erstellung von Bilddateien für Etikettendruck-Plugins" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Berichte aktivieren" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Berichterstellung aktivieren" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Entwickler-Modus" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Berichte im Entwickler-Modus generieren (als HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Berichtsfehler protokollieren" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Fehler, die beim Erstellen von Berichten auftreten, protokollieren" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Seitengröße" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Standardseitenformat für PDF-Bericht" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Parameter Einheiten durchsetzen" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Wenn Einheiten angegeben werden, müssen die Parameterwerte mit den angegebenen Einheiten übereinstimmen" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Global einzigartige Seriennummern" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Seriennummern für Lagerartikel müssen global eindeutig sein" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Erschöpften Lagerartikel löschen" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Legt das Standardverhalten fest, wenn ein Lagerartikel aufgebraucht ist" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Losnummer Vorlage" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Vorlage für die Generierung von Standard-Losnummern für Lagerbestände" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Bestands-Ablauf" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Ablaufen von Bestand ermöglichen" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Abgelaufenen Bestand verkaufen" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Verkauf von abgelaufenem Bestand erlaubt" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Bestands-Stehzeit" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Anzahl an Tagen, an denen Bestand als abgestanden markiert wird, bevor sie ablaufen" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Abgelaufenen Bestand verbauen" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Verbauen von abgelaufenen Bestand erlaubt" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Bestands-Eigentümerkontrolle" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Eigentümerkontrolle für Lagerorte und Teile aktivieren" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Standardsymbol für Lagerort" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Standardsymbol für Lagerstandort (leer bedeutet kein Symbol)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Zeige installierte Lagerartikel" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Anzeige der installierten Lagerartikel in Bestandstabellen" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Prüfe BOM bei der Installation von Elementen" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Installierte Lagerbestandteile müssen im BOM für den übergeordneten Teil vorhanden sein" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Erlaube Verschieben von \"nicht auf Lager\" Bestand" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Lagerartikel, die nicht auf Lager sind, können zwischen Lagerstandorten übertragen werden" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Bauauftragsreferenz-Muster" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Benötigtes Muster für die Generierung des Referenzfeldes für Bauaufträge" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Verantwortlicher Besitzer erforderlich" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Jeder Bestellung muss ein verantwortlicher Besitzer zugewiesen werden" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blockieren bis Test bestanden" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Verhindert die Fertigstellung bis alle erforderlichen Tests bestanden sind" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Rücksendungen aktivieren" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Aktivieren der Rücksendung-Funktion in der Benutzeroberfläche" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Referenz Muster für Rücksendungen" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Benötigtes Muster für die Generierung des Referenzfeldes für Rücksendungen" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Abgeschlossene Rücksendungen bearbeiten" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Bearbeitung von Rücksendungen nach Abschluss erlauben" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Auftragsreferenz-Muster" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Benötigtes Muster für die Generierung des Referenzfeldes für Aufträge" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Auftrag Standardsendung" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Erstelle eine Standardsendung für Aufträge" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Abgeschlossene Aufträge bearbeiten" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Bearbeitung von Aufträgen nach Versand oder Abschluss erlauben" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Versendete Bestellungen als abgeschlossen markieren" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Als versendet markierte Aufträge werden automatisch abgeschlossen und überspringen den Status \"Versandt\"" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Bestellungsreferenz-Muster" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Benötigtes Muster für die Generierung des Referenzfeldes für Bestellungen" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Abgeschlossene Einkaufsaufträge bearbeiten" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Bearbeitung von Einkaufsaufträgen nach Versand oder Abschluss erlauben" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Bestellungen automatisch abschließen" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Bestellung automatisch als abgeschlossen markieren, wenn der Empfang aller Artikel bestätigt wurde" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Passwort vergessen aktivieren" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Passwort-vergessen-Funktion auf den Anmeldeseiten aktivieren" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Registrierung erlauben" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "Selbstregistrierung für Benutzer auf den Anmeldeseiten aktivieren" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "SSO aktivieren" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "SSO auf den Anmeldeseiten aktivieren" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "SSO Selbstregistrierung aktivieren" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Selbstregistrierung über SSO für Benutzer auf den Anmeldeseiten aktivieren" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "SSO Gruppensynchronisation aktivieren" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "SSO Gruppenschlüssel" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Passwort vergessen aktivieren" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Passwort-vergessen-Funktion auf den Anmeldeseiten aktivieren" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Registrierung erlauben" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "Selbstregistrierung für Benutzer auf den Anmeldeseiten aktivieren" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "SSO aktivieren" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "SSO auf den Anmeldeseiten aktivieren" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "SSO Selbstregistrierung aktivieren" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "Selbstregistrierung über SSO für Benutzer auf den Anmeldeseiten aktivieren" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "SSO Gruppensynchronisation aktivieren" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "SSO Gruppenschlüssel" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "" + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email-Adresse erforderlich" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Benutzer müssen bei der Registrierung eine E-Mail angeben" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "SSO-Benutzer automatisch ausfüllen" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Benutzer-Details automatisch aus SSO-Konto ausfüllen" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "E-Mail zweimal" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Bei der Registrierung den Benutzer zweimal nach der E-Mail-Adresse fragen" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Passwort zweimal" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Bei der Registrierung den Benutzer zweimal nach dem Passwort fragen" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Erlaubte Domains" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Anmeldung auf bestimmte Domänen beschränken (kommagetrennt, beginnend mit @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Gruppe bei Registrierung" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "MFA erzwingen" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Benutzer müssen Multifaktor-Authentifizierung verwenden." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Plugins beim Start prüfen" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Beim Start überprüfen, ob alle Plugins installiert sind - Für Container aktivieren" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Nach Plugin-Aktualisierungen suchen" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Periodische Überprüfungen auf Updates für installierte Plugins aktivieren" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "URL-Integration aktivieren" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Plugins zum Hinzufügen von URLs aktivieren" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Navigations-Integration aktivieren" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Plugins zur Integration in die Navigation aktivieren" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "App-Integration aktivieren" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Plugins zum Hinzufügen von Apps aktivieren" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Terminplan-Integration aktivieren" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Geplante Aufgaben aktivieren" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Ereignis-Integration aktivieren" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Plugins ermöglichen auf interne Ereignisse zu reagieren" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Externe Standorte ausschließen" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Automatische Inventur-Periode" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Vollständige Namen von Benutzern anzeigen" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Vollständigen Namen von Benutzern anstatt Benutzername anzeigen" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Teststation-Daten aktivieren" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Teststation-Datenerfassung für Testergebnisse aktivieren" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Anzahl der Ergebnisse, die in der Vorschau pro Sektion angezeigt werden sollen" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Regex Suche" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Reguläre Ausdrücke in Suchabfragen aktivieren" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Ganzes Wort suchen" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Suchabfragen liefern Ergebnisse für ganze Wortkombinationen" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Esc-Taste schließt Formulare" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Benutze die Esc-Taste, um Formulare zu schließen" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Fixierter Navigationsleiste" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Position der Navigationsleiste am oberen Bildschirmrand fixieren" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Datumsformat" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Bevorzugtes Format für die Anzeige von Daten" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Fehlerberichte empfangen" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Benachrichtigungen bei Systemfehlern erhalten" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Zuletzt verwendete Druckmaschinen" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Die zuletzt benutzten Druckmaschinen für einen Benutzer speichern" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Eine leere Domain ist nicht erlaubt." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Ungültiger Domainname: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Teil ist aktiv" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Hersteller ist aktiv" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Lieferantenteil ist aktiv" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Internes Teil ist aktiv" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Lieferant ist aktiv" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Hersteller" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Firma" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "Kontakt-Telefon" msgid "Contact email address" msgstr "Kontakt-Email" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontakt" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adresse" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adressen" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Firma auswählen" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Adresstitel" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Titel zur Beschreibung des Adresseintrages" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Primäre Adresse" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Als primäre Adresse festlegen" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Linie 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Adresszeile 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Linie 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Adresszeile 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Postleitzahl" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Stadt/Region" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Postleitzahl Stadt/Region" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Staat/Provinz" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Bundesland" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Land" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Adresse Land" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Versandnotizen" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Notizen für Versandkurier" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Interne Versandnotizen" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Versandnotizen für interne Verwendung" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Link zu Adressinformationen (extern)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Herstellerteil" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Basisteil" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Teil auswählen" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Hersteller auswählen" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Hersteller-Teilenummer" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "Externe URL für das Herstellerteil" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Teilbeschreibung des Herstellers" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Packeinheiten müssen mit den Basisteileinheiten kompatibel sein" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Packeinheiten müssen größer als Null sein" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Verlinktes Herstellerteil muss dasselbe Basisteil referenzieren" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Zulieferer" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Zulieferer auswählen" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Lagerbestandseinheit (SKU) des Zulieferers" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Ist dieser Lieferantenteil aktiv?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Herstellerteil auswählen" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "Teil-URL des Zulieferers" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Zuliefererbeschreibung des Teils" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "Basiskosten" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Mindestpreis" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Verpackungen" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Teile-Verpackungen" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Packmenge" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Gesamtmenge, die in einer einzelnen Packung geliefert wird. Für Einzelstücke leer lassen." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "Vielfache" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Mehrere bestellen" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Verfügbare Menge von Lieferanten" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Verfügbarkeit aktualisiert" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Datum des letzten Updates der Verfügbarkeitsdaten" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Standard-Währung für diesen Zulieferer" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Firmenname" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Auf Lager" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Export-Format" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Export-Dateiformat wählen" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Export-Plugin" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Export-Plugin wählen" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Platziert" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Datendatei" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Zu importierende Datei" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Spalten" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Importstatus" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Standardwerte" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Feld" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Spalte" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Fehler" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Gültig" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Dateiformat nicht unterstützt" @@ -4600,43 +4893,47 @@ msgstr "Dateiformat nicht unterstützt" msgid "Failed to open data file" msgstr "Fehler beim Öffnen der Datei" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Ungültige Dateigröße" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Zeilen" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Liste der zu akzeptierenden Zeilen IDs" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Keine Zeilen ausgewählt" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopien" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Anzahl der zu druckenden Kopien für jedes Label" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Verbunden" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Unbekannt" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Drucken" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Warnung" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Keine Medien" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Papierstau" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Verbindung getrennt" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Etikettendrucker" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Drucken Sie Etiketten direkt für verschiedene Artikel." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Druckerstandort" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Den Drucker an einen bestimmten Ort aufstellen" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Name des Geräts" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Gerätetyp" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Typ der Maschine" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Treiber" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Verwendeter Treiber für die Maschine" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Maschinen können deaktiviert werden" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Treiber verfügbar" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Keine Fehler" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Initialisiert" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Status der Maschine" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Maschine" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Maschinenkonfiguration" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Konfigurationstyp" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Gruppe" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Bestellreferenz" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Ausstehend" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Erstellt von" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Hat Preise" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Bestellung" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Bestellung abgeschlossen" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Internes Teil" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Bestellung ausstehend" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Fertig" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Bestellung" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Bestellung" msgid "Sales Order" msgstr "Auftrag" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Rücksendeauftrag" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Gesamtpreis" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Gesamtpreis für diese Bestellung" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Auftragswährung" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Währung für diesen Auftrag (leer lassen, um Firmenstandard zu verwenden)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Kontakt stimmt nicht mit der ausgewählten Firma überein" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Auftragsbeschreibung (optional)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Projektcode für diesen Auftrag auswählen" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Link auf externe Seite" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Zieldatum" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Geplantes Lieferdatum für Auftrag." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Aufgabedatum" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Datum an dem die Bestellung aufgegeben wurde" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Nutzer oder Gruppe der/die für diesen Auftrag zuständig ist/sind" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Ansprechpartner für diesen Auftrag" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Firmenadresse für diesen Auftrag" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Bestell-Referenz" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Bestellungs-Status" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Firma bei der die Teile bestellt werden" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Zulieferer-Referenz" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Zulieferer Bestellreferenz" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "Empfangen von" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Datum an dem der Auftrag fertigstellt wurde" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Ziel-Lager" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Teile-Zulieferer muss dem Zulieferer der Bestellung entsprechen" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Position stimmt nicht mit Kaufauftrag überein" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Anzahl muss eine positive Zahl sein" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Kunde" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Firma an die die Teile verkauft werden" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Kundenreferenz" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Bestellreferenz" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Versanddatum" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "Versand von" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Position ist nicht diesem Auftrag zugeordnet" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Folgende Serienummern konnten nicht gefunden werden" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Bestellung ist bereits abgeschlossen" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Bestellung ist bereits storniert" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Nur ein offener Auftrag kann als abgeschlossen markiert werden" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Auftrag kann nicht abgeschlossen werden, da unvollständige Sendungen vorhanden sind" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Auftrag kann nicht abgeschlossen werden, da es unvollständige Positionen gibt" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Anzahl" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Position - Referenz" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Position - Notizen" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Zieldatum für diesen Einzelposten (leer lassen, um das Zieldatum des Auftrags zu verwenden)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Positionsbeschreibung (optional)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Zusätzlicher Kontext für diese Zeile" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Stückpreis" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Lieferantenteil muss mit Lieferant übereinstimmen" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Zuliefererteil" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Empfangen" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Empfangene Objekt-Anzahl" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Preis" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Preis pro Einheit" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Nur verkaufbare Teile können einem Auftrag zugewiesen werden" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Verkaufspreis" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Stückverkaufspreis" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Versendet" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Versendete Menge" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Versanddatum" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Lieferdatum" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Versanddatum" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Kontrolliert von" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Benutzer, der diese Sendung kontrolliert hat" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Sendung" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Sendungsnummer" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Sendungsverfolgungsnummer" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Informationen zur Sendungsverfolgung" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Rechnungsnummer" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Referenznummer für zugehörige Rechnung" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Sendung wurde bereits versandt" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Sendung hat keine zugewiesene Lagerartikel" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Lagerartikel wurde nicht zugewiesen" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Kann Lagerartikel keiner Zeile mit einem anderen Teil hinzufügen" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Kann Lagerartikel keiner Zeile ohne Teil hinzufügen" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Die zugeordnete Anzahl darf nicht die verfügbare Anzahl überschreiten" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Reserviermenge muss größer null sein" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Anzahl für serialisierte Lagerartikel muss 1 sein" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Auftrag gehört nicht zu Sendung" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Sendung gehört nicht zu Auftrag" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Position" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Sendungsnummer-Referenz" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Position" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Lagerartikel für Zuordnung auswählen" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Anzahl für Bestandszuordnung eingeben" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Rücksendungsreferenz" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Firma von der die Artikel zurückgeschickt werden" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Status der Rücksendung" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Artikel zur Rücksendung auswählen" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Empfangsdatum" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Ergebnis" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Ergebnis für dieses Zeilenelement" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Kosten für die Rückgabe oder Reparatur dieses Objektes" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Parameter kopieren" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Positionen" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Abgeschlossene Positionen" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Lieferant" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Bestellung kann nicht verworfen werden" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Erlaube das Schließen des Auftrags mit unvollständigen Positionen" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Auftrag hat unvollständige Positionen" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Der Auftrag ist nicht offen" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Automatische Preisgestaltung" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Kaufpreis automatisch basierend auf Lieferantenbestandsdaten berechnen" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Kaufpreiswährung" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Elemente zusammenfügen" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Zusammenführen von Elementen mit dem gleichen Teil, Ziel- und Zieldatum zu einem Zeilenelement" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Lieferanten-Teilenummer" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Interne Teilenummer" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Zuliefererteil muss ausgewählt werden" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Bestellung muss angegeben sein" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Lieferant muss mit der Bestellung übereinstimmen" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Die Bestellung muss mit dem Lieferant übereinstimmen" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Position" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Zielort für empfangene Teile auswählen" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Losnummer für eingehende Lagerartikel" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Ablaufdatum" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Seriennummern für eingehende Lagerartikel" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Barcode" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Gescannter Barcode" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Barcode ist bereits in Verwendung" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Positionen müssen angegeben werden" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Ziel-Lagerort muss angegeben werden" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Barcode muss eindeutig sein" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Abgeschlossene Sendungen" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Verkaufspreis-Währung" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Keine Sendungsdetails angegeben" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Position ist nicht diesem Auftrag zugeordnet" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Anzahl muss positiv sein" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Seriennummern zum Zuweisen eingeben" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Sendung wurde bereits versandt" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Sendung ist nicht diesem Auftrag zugeordnet" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Folgende Serienummern konnten nicht gefunden werden" - -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" + +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Artikel der Bestellzeile zurücksenden" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Artikel entspricht nicht der Rücksendeschrift" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Artikel wurde bereits erhalten" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Artikel können nur bei laufenden Bestellungen empfangen werden" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Verkaufspreis-Währung" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Verloren" @@ -5718,1279 +6125,1312 @@ msgstr "Verloren" msgid "Returned" msgstr "Zurückgegeben" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "In Bearbeitung" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Zurück" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Reparatur" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Ersetzen" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Rückerstattung" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Ablehnen" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Aufgegeben" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Überfällige Bestellung" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Bestellung {po} ist jetzt überfällig" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Überfälliger Auftrag" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Auftrag {so} ist jetzt überfällig" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Markiert" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Nach markierten Kategorien filtern" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Ebenen" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filter nach Kategorietiefe" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Oberste Ebene" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Mehrstufig" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Unterkategorien in gefilterte Ergebnisse einbeziehen" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Übergeordnetes" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Nach übergeordneter Kategorie filtern" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Unterkategorien in der angegebenen Kategorie ausschließen" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Ergebnisse" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Verwendet" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Teil-Kategorie" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Teil-Kategorien" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Standard-Lagerort" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Standard-Lagerort für Teile dieser Kategorie" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Strukturell" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Teile können nicht direkt einer strukturellen Kategorie zugeordnet werden, können aber untergeordneten Kategorien zugeordnet werden." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Standard Stichwörter" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Standard-Stichworte für Teile dieser Kategorie" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Symbol" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Symbol (optional)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Sie können diese Teilekategorie nicht als strukturell festlegen, da ihr bereits Teile zugewiesen sind!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Standard-Wert" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Standard Parameter Wert" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Teile" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Dieses Teil kann nicht gelöscht werden, da es noch aktiv ist" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Dieses Teil kann nicht gelöscht werden, da es in einem Bauauftrag verwendet wird" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Teil '{self}' kann in der Stückliste nicht für '{parent}' (rekursiv) verwendet werden" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Teil '{parent}' wird in der Stückliste für '{self}' (rekursiv) verwendet" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN muss mit Regex-Muster {pattern} übereinstimmen" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Ein Lagerartikel mit dieser Seriennummer existiert bereits" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Doppelte IPN in den Teil-Einstellungen nicht erlaubt" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Teil mit diesem Namen, IPN und Revision existiert bereits." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Strukturellen Teilekategorien können keine Teile zugewiesen werden!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Name des Teils" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Ist eine Vorlage" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Ist dieses Teil eine Vorlage?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Ist dieses Teil eine Variante eines anderen Teils?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variante von" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Artikelbeschreibung (optional)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Schlüsselwörter" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Schlüsselworte um die Sichtbarkeit in Suchergebnissen zu verbessern" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Teile-Kategorie" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN (Interne Produktnummer)" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Revisions- oder Versionsnummer" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Version" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Revision von" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Standard Ablaufzeit" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Ablauf-Zeit (in Tagen) für Bestand dieses Teils" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimaler Bestand" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Minimal zulässiger Bestand" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Maßeinheit für diesen Teil" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Kann dieses Teil aus anderen Teilen angefertigt werden?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Kann dieses Teil zum Bauauftrag von anderen genutzt werden?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Hat dieses Teil Tracking für einzelne Objekte?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Kann dieses Teil von externen Zulieferern gekauft werden?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Kann dieses Teil an Kunden verkauft werden?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Ist dieses Teil aktiv?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Ist dieses Teil virtuell, wie zum Beispiel eine Software oder Lizenz?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Prüfsumme der Stückliste gespeichert" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Stückliste kontrolliert von" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "BOM Kontrolldatum" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Erstellungs-Nutzer" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Verantwortlicher Besitzer für dieses Teil" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Mehrere verkaufen" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Währung für die Berechnung der Preise im Cache" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimale Stücklisten Kosten" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Minimale Kosten für Teile" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maximale Stücklisten Kosten" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Maximale Kosten für Teile" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimale Einkaufskosten" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Minimale historische Kaufkosten" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maximale Einkaufskosten" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Maximale historische Einkaufskosten" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimaler interner Preis" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Minimale Kosten basierend auf den internen Staffelpreisen" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maximaler interner Preis" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Maximale Kosten basierend auf internen Preisstaffeln" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Minimaler Lieferantenpreis" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Mindestpreis für Teil von externen Lieferanten" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Maximaler Lieferantenpreis" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Maximaler Preis für Teil von externen Lieferanten" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Minimale Variantenkosten" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Berechnete minimale Kosten für Variantenteile" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Maximale Variantenkosten" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Berechnete maximale Kosten für Variantenteile" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimale Kosten" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Mindestkosten überschreiben" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maximale Kosten" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Maximale Kosten überschreiben" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Berechnete Mindestkosten" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Berechnete Maximalkosten" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Mindestverkaufspreis" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Mindestverkaufspreis basierend auf Staffelpreisen" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Maximaler Verkaufspreis" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Maximalverkaufspreis basierend auf Staffelpreisen" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Mindestverkaufskosten" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Minimaler historischer Verkaufspreis" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Maximale Verkaufskosten" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Maximaler historischer Verkaufspreis" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Teil für die Inventur" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Stückzahl" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Anzahl einzelner Bestandseinträge zum Zeitpunkt der Inventur" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Insgesamt verfügbarer Lagerbestand zum Zeitpunkt der Inventur" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Datum" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Datum der Inventur" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Mindestbestandswert" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Geschätzter Mindestwert des vorhandenen Bestands" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maximaler Bestandswert" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Geschätzter Maximalwert des vorhandenen Bestands" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Ungültiger Vorlagenname - es muss mindestens ein alphanumerisches Zeichen enthalten sein" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Testvorlage mit demselben Schlüssel existiert bereits für Teil" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Test-Name" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Namen für diesen Test eingeben" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Testschlüssel" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Vereinfachter Schlüssel zum Test" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Test-Beschreibung" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Beschreibung für diesen Test eingeben" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Ist dieser Test aktiviert?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Benötigt" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Muss dieser Test erfolgreich sein?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Erfordert Wert" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Muss für diesen Test ein Wert für das Test-Ergebnis eingetragen werden?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Anhang muss eingegeben werden" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Muss für diesen Test ein Anhang für das Test-Ergebnis hinzugefügt werden?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Gültige Optionen für diesen Test (durch Komma getrennt)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Ausgangsteil auswählen" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Untergeordnetes Teil" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Teil für die Nutzung in der Stückliste auswählen" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Diese Stücklisten-Position ist optional" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Diese Stücklisten-Position ist ein Verbrauchsartikel (sie wird nicht in Bauaufträgen verfolgt)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Referenz der Postion auf der Stückliste" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Notizen zur Stücklisten-Position" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Prüfsumme" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "überprüft" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Diese Stücklistenposition wurde validiert" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Wird vererbt" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Diese Stücklisten-Position wird in die Stücklisten von Teil-Varianten vererbt" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Bestand von Varianten kann für diese Stücklisten-Position verwendet werden" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Menge muss eine Ganzzahl sein" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Zuliefererteil muss festgelegt sein" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Stücklisten Ersatzteile" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Ersatzteil kann nicht identisch mit dem Hauptteil sein" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Übergeordnete Stücklisten Position" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Ersatzteil" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Teil 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Teil 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "verknüpftes Teil auswählen" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Teil-Beziehung kann nicht zwischen einem Teil und sich selbst erstellt werden" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Doppelte Beziehung existiert bereits" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Übergeordnete Kategorie" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Übergeordnete Teilkategorie" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Unter-Kategorien" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Ergebnisse" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Anzahl der Ergebnisse, die in dieser Vorlage aufgezeichnet wurden" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Kaufwährung dieses Lagerartikels" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Originalteil" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Originalteil zum Duplizieren auswählen" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Bild kopieren" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Bild vom Originalteil kopieren" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Stückliste kopieren" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Stückliste vom Originalteil kopieren" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Parameterdaten vom Originalteil kopieren" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Anmerkungen kopieren" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Notizen aus Originalteil kopieren" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Start-Bestandsmenge" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Initiale Lagermenge für dieses Teil. Wenn die Menge null ist, wird kein Lagerbestand hinzugefügt." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Initialer Lagerort" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Lagerstandort für dieses Teil angeben" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Lieferant auswählen (oder leer lassen, um zu überspringen)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Hersteller auswählen (oder leer lassen, um zu überspringen)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Hersteller-Teilenummer" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Ausgewählte Firma ist kein gültiger Lieferant" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Ausgewählte Firma ist kein gültiger Hersteller" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Herstellerteil mit dieser MPN existiert bereits" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Lieferantenteil mit dieser SKU existiert bereits" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Kategoriename" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Im Bau" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Lagerartikel" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Gesamtbestand" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Nicht zugewiesenes Lager" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Alternatives Lager" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Teil duplizieren" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Initiale Daten von anderem Teil kopieren" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Bild kopieren" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Bild vom Originalteil kopieren" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Stückliste kopieren" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Stückliste vom Originalteil kopieren" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Anmerkungen kopieren" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Notizen aus Originalteil kopieren" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Initialer Lagerbestand" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Erstelle Teil mit Ausgangsbestand" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Lieferanteninformationen" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Lieferanteninformationen zu diesem Teil hinzufügen" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Kategorieparameter kopieren" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Parametervorlagen aus der ausgewählten Teilkategorie kopieren" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Vorhandenes Bild" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Dateiname eines vorhandenen Teilbildes" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Bilddatei existiert nicht" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Gesamte Stückliste validieren" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Herstellbar" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Niedrigster Preis" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Berechneten Wert für Mindestpreis überschreiben" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Mindestpreis Währung" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Höchster Preis" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Berechneten Wert für maximalen Preis überschreiben" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Maximalpreis Währung" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Aktualisieren" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Preis für dieses Teil aktualisieren" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Konnte nicht von den angegebenen Währungen in {default_currency} umrechnen" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Mindestpreis darf nicht größer als der Maximalpreis sein" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Der Maximalpreis darf nicht kleiner als der Mindestpreis sein" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Teil auswählen, von dem Stückliste kopiert wird" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Bestehende Daten entfernen" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Bestehende Stücklisten-Positionen vor dem Kopieren entfernen" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Vererbtes einschließen" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Stücklisten-Positionen einbeziehen, die von Vorlage-Teilen geerbt werden" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Ungültige Zeilen überspringen" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Aktiviere diese Option, um ungültige Zeilen zu überspringen" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Ersatzteile kopieren" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Ersatzteile beim Duplizieren von Stücklisten-Positionen kopieren" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Benachrichtigungen über geringen Bestand" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Der verfügbare Bestand für {part.name} ist unter das konfigurierte Mindestniveau gefallen" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Installiert" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Das Plugin kann nicht gelöscht werden, da es derzeit aktiv ist" @@ -7023,23 +7463,23 @@ msgstr "Keine Aktion angegeben" msgid "No matching action found" msgstr "Keine passende Aktion gefunden" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Keine Treffer für Barcode" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Treffer für Barcode gefunden" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Barcode entspricht einem bereits vorhandenen Artikel" @@ -7055,51 +7495,67 @@ msgstr "Keine passenden Zulieferteile gefunden" msgid "Multiple matching supplier parts found" msgstr "Mehrere passende Zulieferteile gefunden" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Zulieferteil zugeordnet" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Artikel wurde bereits erhalten" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Mehrere passende Elemente gefunden" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Kein passendes Element gefunden" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Barcode stimmt nicht mit einem vorhandenen Lagerartikel überein" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Lagerartikel stimmt nicht mit dem Element überein" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Unzureichender Bestand verfügbar" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Lagerartikel der Bestellung zugeordnet" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Nicht genügend Informationen" @@ -7108,23 +7564,23 @@ msgstr "Nicht genügend Informationen" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Weitere Informationen zum Empfang des Zeilenelements erforderlich" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Erhaltene Bestellartikel" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Bietet native Unterstützung für Barcodes" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL, die verwendet wird, um Nachrichten an einen Slack-Kanal zu senden" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Link öffnen" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Bietet native Unterstützung für das Drucken von PDF-Etiketten" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Debug-Modus" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Debug-Modus aktivieren - gibt Roh-HTML statt PDF zurück" @@ -7653,55 +8117,55 @@ msgstr "Zuletzt benutzt" msgid "Options" msgstr "Optionen" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Seitengröße für das Etikett" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Etiketten überspringen" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Diese Anzahl der Etiketten beim Drucken von Etiketten überspringen" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Rand" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Einen Rahmen um jedes Label drucken" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Querformat" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Labelblatt im Querformat drucken" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree Etikettendrucker" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Anordnen mehrerer Etiketten auf einem einzigen Blatt" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Label ist zu groß für Seitengröße" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Es wurden keine Etiketten generiert" @@ -7753,77 +8217,85 @@ msgstr "Unterstützt das Scannen von TME-Barcodes" msgid "The Supplier which acts as 'TME'" msgstr "Der Lieferant, der als 'TME' fungiert" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Plugin-Installation ist deaktiviert" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Plugin wurde erfolgreich installiert" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin installiert in {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Plugin wurde nicht in der Registry gefunden" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Plugin ist kein gepacktes Plugin" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Plugin-Paketname nicht gefunden" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Nur Mitarbeiter können Plugins verwalten" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Plugin-Deinstallation ist deaktiviert" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Plugin kann nicht deinstalliert werden, da es momentan aktiv ist" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Plugin erfolgreich deinstallieren" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "Paket-Plugin" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Kein Autor gefunden" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Plugin '{p}' ist nicht kompatibel mit der aktuellen InvenTree Version {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Plugin benötigt mindestens Version {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plugin benötigt maximal Version {v}" @@ -8114,176 +8586,184 @@ msgstr "Konfiguration löschen" msgid "Delete the plugin configuration from the database" msgstr "Plugin-Konfiguration aus der Datenbank löschen" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Teile" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Plugin nicht gefunden" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "US-Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "US-Letter" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Vorlagen Name" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Beschreibung der Vorlage" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Dateinamen-Muster" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filter" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Seitengröße für PDF-Berichte" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Bericht in Querformat anzeigen" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Breite [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Label-Breite in mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Höhe [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Label-Höhe in mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Schnipsel" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Berichts-Snippet" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Snippet-Beschreibung" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Ressource" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Berichts-Ressource" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Ressource-Beschreibung" @@ -8291,23 +8771,23 @@ msgstr "Ressource-Beschreibung" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Etiketten-Vorlage auswählen" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "Benötigte Materialien" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Artikelbild" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Aufgegeben" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "benötigt für" @@ -8380,8 +8857,8 @@ msgstr "Summe" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Seriennummer" @@ -8405,7 +8882,7 @@ msgstr "Lagerartikel Test-Bericht" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Verbaute Objekte" @@ -8438,810 +8915,922 @@ msgstr "Kein Ergebnis (erforderlich)" msgid "No result" msgstr "Kein Ergebnis" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Bilddatei nicht gefunden" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image tag benötigt eine Bauteilinstanz" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image tag erfordert eine Firmeninstanz" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Filtern nach Standorttiefe" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Unterorte in gefilterte Ergebnisse einbeziehen" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Übergeordneter Ort" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filtern nach übergeordnetem Ort" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Statuscode" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Externer Standort" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Teile-Baum" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Gültigkeitsdauer vor" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Gültigkeitsdauer nach" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "überfällig" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Menge ist erforderlich" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Gültiges Teil muss angegeben werden" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Der angegebene Lieferantenartikel existiert nicht" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Das Zulieferteil hat eine Packungsgröße definiert, aber das Kennzeichen use_pack_size ist nicht gesetzt" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Seriennummern können für nicht verfolgbare Teile nicht angegeben werden" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Lagerstandort Typ" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Lagerstandorte Typen" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Standardsymbol für alle Orte, die kein Icon gesetzt haben (optional)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Bestand-Lagerort" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Bestand-Lagerorte" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Besitzer" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Besitzer auswählen" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Lagerartikel können nicht direkt an einen strukturellen Lagerort verlegt werden, können aber an einen untergeordneten Lagerort verlegt werden." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Extern" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Dies ist ein externer Lagerort" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Standorttyp" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Standortart dieses Standortes" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Sie können diesen Lagerort nicht als strukturell markieren, da sich bereits Lagerartikel darin befinden!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Lagerartikel können nicht in strukturelle Lagerorte abgelegt werden!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Für virtuelle Teile können keine Lagerartikel erstellt werden" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Artikeltyp ('{self.supplier_part.part}') muss {self.part} sein" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Anzahl muss für Objekte mit Seriennummer 1 sein" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Seriennummer kann nicht gesetzt werden wenn die Anzahl größer als 1 ist" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Teil kann nicht zu sich selbst gehören" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Teil muss eine Referenz haben wenn is_building wahr ist" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Referenz verweist nicht auf das gleiche Teil" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Eltern-Lagerartikel" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Basis-Teil" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Passendes Zuliefererteil für diesen Lagerartikel auswählen" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Verpackung, in der dieser Lagerartikel gelagert ist" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "verbaut in" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Ist dieses Teil in einem anderen verbaut?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Seriennummer für dieses Teil" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Losnummer für diesen Lagerartikel" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Bestand" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Quellbau" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Bauauftrag für diesen Lagerartikel" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Verbraucht von" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Bauauftrag der diesen Lagerartikel verbrauchte" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Quelle Bestellung" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Bestellung für diesen Lagerartikel" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Ziel-Auftrag" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Ablaufdatum für Lagerartikel. Bestand wird danach als abgelaufen gekennzeichnet" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Löschen wenn leer" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Diesen Lagerartikel löschen wenn der Bestand aufgebraucht ist" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Preis für eine Einheit bei Einkauf" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "In Teil umgewandelt" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Teil ist nicht verfolgbar" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Anzahl muss eine Ganzzahl sein" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Menge darf die verfügbare Lagermenge ({self.quantity}) nicht überschreiten" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Anzahl stimmt nicht mit den Seriennummern überein" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Testvorlage existiert nicht" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Artikel wurde einem Kundenauftrag zugewiesen" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Lagerartikel ist in anderem Element verbaut" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Lagerartikel enthält andere Artikel" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Artikel wurde einem Kunden zugewiesen" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Lagerartikel wird aktuell produziert" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Nachverfolgbare Lagerartikel können nicht zusammengeführt werden" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Artikel duplizeren" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Lagerartikel müssen auf dasselbe Teil verweisen" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Lagerartikel müssen auf dasselbe Lieferantenteil verweisen" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Status-Codes müssen zusammenpassen" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Lagerartikel kann nicht bewegt werden, da kein Bestand vorhanden ist" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Eintrags-Notizen" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Wert muss für diesen Test angegeben werden" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Anhang muss für diesen Test hochgeladen werden" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Testergebnis" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Test Ausgabe Wert" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Test Ergebnis Anhang" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Test Notizen" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Teststation" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "Der Bezeichner der Teststation, in der der Test durchgeführt wurde" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Gestartet" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Der Zeitstempel des Teststarts" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Fertiggestellt" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Der Zeitstempel der Test-Beendigung" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Testvorlage für dieses Ergebnis" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "Vorlagen-ID oder Testname muss angegeben werden" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "Die Test-Endzeit kann nicht früher als die Startzeit des Tests sein" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Elternposition" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Packungsgröße beim Hinzufügen verwenden: Die definierte Menge ist die Anzahl der Pakete" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Seriennummern für neue Teile eingeben" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "abgelaufen" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Untergeordnete Objekte" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Einkaufspreis dieses Lagerartikels, pro Einheit oder Verpackungseinheit" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Anzahl der zu serialisierenden Lagerartikel eingeben" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Anzahl darf nicht die verfügbare Menge überschreiten ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Ziel-Bestand" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Seriennummern können diesem Teil nicht zugewiesen werden" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Seriennummern existieren bereits" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Lagerartikel für Installation auswählen" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Zu installierende Menge" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Anzahl der zu verwendenden Artikel eingeben" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr " Transaktionsnotizen hinzufügen (optional)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Die zu verwendende Menge muss mindestens 1 sein" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Lagerartikel ist nicht verfügbar" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Ausgewähltes Teil ist nicht in der Stückliste" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Die zu verwendende Menge darf die verfügbare Menge nicht überschreiten" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Ziel Lagerort für unverbautes Objekt" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Wählen Sie einen Teil aus, zu dem dieser Lagerartikel geändert werden soll" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Das ausgewählte Teil ist keine gültige Option für die Umwandlung" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Lagerartikel konnte nicht mit Zulieferteil zugewiesen werden" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Lagerartikel Status-Code" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Wählen Sie einen Teil aus, zu dem dieser Lagerartikel geändert werden soll" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Das ausgewählte Teil ist keine gültige Option für die Umwandlung" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Lagerartikel konnte nicht mit Zulieferteil zugewiesen werden" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Lagerartikel auswählen, um den Status zu ändern" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Keine Lagerartikel ausgewählt" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Unter-Lagerorte" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Übergeordneter Lagerort" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Teil muss verkaufbar sein" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Artikel ist einem Kundenauftrag zugeordnet" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Artikel ist einem Fertigungsauftrag zugeordnet" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Kunde zum Zuweisen von Lagerartikel" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Ausgewählte Firma ist kein Kunde" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Notizen zur Lagerzuordnung" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Eine Liste der Lagerbestände muss angegeben werden" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Notizen zur Lagerartikelzusammenführung" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Unterschiedliche Lieferanten erlauben" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Zusammenführen von Lagerartikeln mit unterschiedlichen Lieferanten erlauben" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Unterschiedliche Status erlauben" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Zusammenführen von Lagerartikeln mit unterschiedlichen Status-Codes erlauben" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Mindestens zwei Lagerartikel müssen angegeben werden" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Keine Änderung" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Primärschlüssel Lagerelement" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Bestandsbewegungsnotizen" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Bestandsbewegungsnotizen" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Nächste Seriennummer" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Vorherige Seriennummer" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Lagerartikel zusammengeführt" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "In Variante umgewandelt" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Endprodukt erstellt" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Endprodukt fertiggestellt" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Endprodukt abgelehnt" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Durch Bauauftrag verbraucht" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Versandt gegen Verkaufsauftrag" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Gegen Bestellung empfangen" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Zurückgeschickt gegen Rücksendeauftrag" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Zum Kunden geschickt" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Rücksendung vom Kunden" @@ -9527,19 +10124,19 @@ msgstr "Benutzer" msgid "Select which users are assigned to this group" msgstr "Welche Benutzer gehören zu dieser Gruppe" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Persöhnliche Informationen" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Berechtigungen" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "wichtige Daten" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Token wurde widerrufen" @@ -9547,279 +10144,283 @@ msgstr "Token wurde widerrufen" msgid "Token has expired" msgstr "Token ist abgelaufen" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API Token" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API-Tokens" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Tokenname" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Benutzerdefinierter Tokenname" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Token Ablaufdatum" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Zuletzt gesehen" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Das letzte Mal, wo das Token verwendet wurde" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Widerrufen" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Berechtigung geändert" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Ansicht" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Berechtigung Einträge anzuzeigen" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Hinzufügen" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Berechtigung Einträge zu erstellen" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Ändern" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Berechtigungen Einträge zu ändern" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Löschen" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Berechtigung Einträge zu löschen" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Interne" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Gast" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Sprache" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Bevorzugte Sprache für diesen Benutzer" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Name anzeigen" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organisation" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Bestellungen" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Aufträge" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Rücksendeaufträge" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Benutzername" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Vorname" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Vorname des Benutzers" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Nachname" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Nachname des Benutzers" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "E-Mailadresse des Benutzers" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Administrator" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Ist dieser Benutzer ein Administrator" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Ist dieses Benutzerkonto aktiv" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Passwort" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Ihr Konto wurde erstellt." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Bitte benutzen Sie die Passwort-zurücksetzen-Funktion, um sich anzumelden" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Willkommen bei InvenTree" diff --git a/src/backend/InvenTree/locale/el/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/el/LC_MESSAGES/django.po index e09355a9ea..1ba6e75029 100644 --- a/src/backend/InvenTree/locale/el/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/el/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Greek\n" "Language: el_GR\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Το API endpoint δε βρέθηκε" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Τα Προϊόντα πρέπει να δοθούν ως λίστα" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Η λίστα Προϊόντων που δόθηκε δεν είναι έγκυρη" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Το φίλτρο all πρέπει να χρησιμοποιείται μόνο με τιμή true" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Κανένα Aντικείμενο δεν ταιριάζει στα κριτήρια που δόθηκαν" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Δεν δόθηκαν δεδομένα" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Αυτό το πεδίο πρέπει να είναι μοναδικό." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Δεν έχετε δικαιώματα να το δείτε αυτό" @@ -65,150 +69,155 @@ msgstr "Επιβεβαίωση διεύθυνσης email" msgid "You must type the same email each time." msgstr "Πρέπει να πληκτρολογήσετε το ίδιο email κάθε φορά." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Η παρεχόμενη κύρια διεύθυνση ηλεκτρονικού ταχυδρομείου δεν είναι έγκυρη." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Ο παρεχόμενος τομέας ηλεκτρονικού ταχυδρομείου δεν έχει εγκριθεί." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Η μονάδα μέτρησης δεν είναι έγκυρη ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Δεν εισήχθη τιμή" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Δεν ήταν δυνατή η μετατροπή από {original} σε {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Μη έγκυρη ποσότητα" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Μπορείτε να βρείτε λεπτομέρειες σφάλματος στον πίνακα διαχείρισης" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Εισάγετε ημερομηνία" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Μη έγκυρη δεκαδική τιμή" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Σημειώσεις" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Η τιμή '{name}' δεν εμφανίζεται σε μορφή μοτίβου" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Η παρεχόμενη τιμή δεν ταιριάζει με το απαιτούμενο απαραραίητη μοτίβο: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Δεν είναι δυνατή η σειριοποίηση περισσότερων από 1000 Προϊόντων ταυτόχρονα" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Κενό σειριακό αριθμό συμβολοσειράς" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Διπλότυπο ArialTTumblr" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Μη έγκυρη ομάδα: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Το εύρος της ομάδας {group} υπερβαίνει την επιτρεπόμενη ποσότητα ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Δεν βρέθηκαν σειριακοί αριθμοί" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Ο αριθμός μοναδικών σειριακών αριθμών ({n}) πρέπει να αντιστοιχεί στην ποσότητα ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Αφαιρέστε τα HTML tags από την τιμή που εισάγατε" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Τα δεδομένα περιέχουν απαγορευμένο περιεχόμενο markdown" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Σφάλμα σύνδεσης" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Ο διακομιστής απάντησε με μη έγκυρο κωδικό κατάστασης" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Προέκυψε σφάλμα" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Ο διακομιστής ανταποκρίθηκε με \"Invalid Content-Length value\"" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Η εικόνα είναι πολύ μεγάλη σε μέγεθος" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Η λήψη εικόνας ξεπέρασε το μέγιστο μέγεθος" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Ο διακομιστής επέστρεψε σφάλμα %1$d %2$s" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Το URL δεν είναι έγκυρο αρχείο εικόνας" @@ -216,159 +225,203 @@ msgstr "Το URL δεν είναι έγκυρο αρχείο εικόνας" msgid "Log in to the app" msgstr "Σύνδεση στην εφαρμογή" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Πρέπει να ενεργοποιήσετε τον έλεγχο ταυτότητας δύο παραγόντων πριν κάνετε οτιδήποτε άλλο." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Σφάλμα κατά την εκτέλεση επικύρωσης προσθέτου" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Τα μεταδεδομένα πρέπει να είναι ένα αντικείμενο dict python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Μεταδεδομένα Πρόσθετου" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON πεδίο μεταδεδομένων, για χρήση από εξωτερικά πρόσθετα" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Λανθασμένο μοτίβο" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Δώσατε λάθος μορφή κλειδιού" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Λείπει το απαραίτητο κλειδί" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Το πεδίο δεν μπορεί να είναι άδειο" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Η αναφορά πρέπει να ταιριάζει με το απαιτούμενο μοτίβο" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Ο αριθμός αναφοράς είναι πολύ μεγάλος" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Μη έγκυρη επιλογή" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Όνομα" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Περιγραφή" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Περιγραφή (προαιρετική)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Μονοπάτι" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Διπλότυπα ονόματα δεν μπορούν να υπάρχουν στον ίδιο γονέα" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Σημειώσεις Markdown (προαιρετικό)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Στοιχεία Barcode" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Δεδομένα barcode τρίτων" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash barcode" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Μοναδικό hash δεδομένων barcode" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Βρέθηκε υπάρχων barcode" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Σφάλμα διακομιστή" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Ένα σφάλμα έχει καταγραφεί από το διακομιστή." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Εικόνα" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Πρέπει να είναι αριθμός" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Νόμισμα" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Επιλέξτε νόμισμα από τις διαθέσιμες επιλογές" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Μη έγκυρη τιμή" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Αντιγραφή παραμέτρων" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Αντιγραφή γραμμών" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Αντιγραφή γραμμών από την αρχική παραγγελία" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Αντιγραφή επιπλέον γραμμών" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Αντιγραφή επιπλέον γραμμών από την αρχική παραγγελία" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Αραβικά" @@ -521,46 +574,48 @@ msgstr "Κινέζικα (απλοποιημένα)" msgid "Chinese (Traditional)" msgstr "Κινέζικα (Παραδοσιακά)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Διαθέσιμη ενημέρωση" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Μια ενημέρωση για το InvenTree είναι διαθέσιμη" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Μη έγκυρη φυσική μονάδα" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Μη έγκυρος κωδικός συναλλάγματος" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Κατάσταση παραγγελίας" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Γονική Κατασκευή" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Συμπερίληψη παραλλαγών" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Συμπερίληψη παραλλαγών" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Συμπερίληψη παραλλαγών" msgid "Part" msgstr "Εξάρτημα" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Κατηγορία" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Πρόγονος κατασκευής" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Ανατεθειμένες σε εμένα" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Ανατεθεί σε" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Δημιουργήθηκε πριν από" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Δημιουργήθηκε μετά από" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Με ημερομηνία έναρξης" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Ημερομηνία έναρξης πριν από" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Ημερομηνία έναρξης μετά από" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Με ημερομηνία στόχο" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Ημερομηνία στόχος πριν από" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Ημερομηνία στόχος μετά από" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Ολοκληρώθηκε πριν από" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Ολοκληρώθηκε μετά από" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Ελάχιστη ημερομηνία" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Μέγιστη ημερομηνία" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Εξαίρεση δέντρου" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Η έκδοση πρέπει να ακυρωθεί πριν διαγραφεί" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Αναλώσιμο" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Προαιρετικό" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Συναρμολόγηση" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Υπό παρακολούθηση" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Υπό δοκιμή" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Εκκρεμής παραγγελία" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Κατανεμημένο" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Καταναλωμένο" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Διαθέσιμο" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Σε παραγγελία" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Σειρά Κατασκευής" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Τοποθεσία" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Έξοδος" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Φιλτράρισμα με βάση το ID του αποθέματος εξόδου. Χρησιμοποιήστε 'null' για να βρείτε μη εγκατεστημένα στοιχεία κατασκευής" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Δημιουργία Παραγγελιών" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Το BOM της συναρμολόγησης δεν έχει επικυρωθεί" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Δεν μπορεί να δημιουργηθεί εντολή κατασκευής για ανενεργό Aντικειμένου" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Δεν μπορεί να δημιουργηθεί εντολή κατασκευής για μη κλειδωμένο Aντικειμένου" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Οι εντολές κατασκευής μπορούν να εκτελεστούν εξωτερικά μόνο για Προϊόντα που μπορούν να αγοραστούν" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Πρέπει να οριστεί υπεύθυνος χρήστης ή ομάδα" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Εξάρτημα από εντολή κατασκευής δεν μπορεί να αλλάξει" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Η ημερομηνία στόχος πρέπει να είναι μετά την ημερομηνία έναρξης" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Αναφορά Παραγγελίας Κατασκευής" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Αναφορά" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Σύντομη περιγραφή της κατασκευής (προαιρετικό)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Επιλέξτε τμήμα για κατασκευή" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Κωδικός Παραγγελίας Πωλήσεων" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Τοποθεσία Προέλευσης" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Επιλέξτε τοποθεσία από την οποία θα γίνει απόθεμα, για αυτή την κατασκευή (αφήστε κενό για να πάρετε από οποιαδήποτε θέση αποθήκευσης)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Εξωτερική κατασκευή" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Αυτή η εντολή κατασκευής εκτελείται εξωτερικά" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Τοποθεσία Προορισμού" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Επιλέξτε την τοποθεσία όπου θα αποθηκευτούν τα ολοκληρωμένα στοιχεία" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Ποσότητα Κατασκευής" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Αριθμός αντικειμένων για κατασκευή" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Ολοκληρωμένα αντικείμενα" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Αριθμός αντικειμένων αποθέματος που έχουν ολοκληρωθεί" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Κατάσταση Κατασκευής" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Κωδικός κατάστασης κατασκευής" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Κωδικός Παρτίδας" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Κωδικός παρτίδας για αυτήν την κατασκευή" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Ημερομηνία Δημιουργίας" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Ημερομηνία έναρξης κατασκευής" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Προγραμματισμένη ημερομηνία έναρξης για αυτή την εντολή κατασκευής" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Ημερομηνία ολοκλήρωσης στόχου" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Ημερομηνία ολοκλήρωσης της κατασκευής. Η κατασκευή θα καθυστερήσει μετά από αυτή την ημερομηνία." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Ημερομηνία ολοκλήρωσης" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "ολοκληρώθηκε από" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Εκδόθηκε από" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Χρήστης που εξέδωσε αυτήν την παραγγελία κατασκευής" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Υπεύθυνος" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Χρήστης ή ομάδα υπεύθυνη για αυτή την εντολή κατασκευής" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Εξωτερικοί σύνδεσμοι" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Σύνδεσμος προς εξωτερική διεύθυνση URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Προτεραιότητα Κατασκευής" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Προτεραιότητα αυτής της εντολής κατασκευής" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Κωδικός Έργου" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Κωδικός έργου για αυτήν την εντολή κατασκευής" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Δεν είναι δυνατή η ολοκλήρωση της εντολής κατασκευής με ανοιχτές θυγατρικές κατασκευές" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Δεν είναι δυνατή η ολοκλήρωση της εντολής κατασκευής με μη ολοκληρωμένα προϊόντα" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Αποτυχία εκχώρησης εργασίας για την ολοκλήρωση των κατανομών κατασκευής" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Η παραγγελία κατασκευής {build} έχει ολοκληρωθεί" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Η παραγγελία κατασκευής έχει ολοκληρωθεί" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Πρέπει να δοθούν σειριακοί αριθμοί για τα ανιχνεύσιμα Προϊόντα" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Δεν καθορίστηκε έξοδος κατασκευής" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Η παραγγελία κατασκευής έχει ολοκληρωθεί" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Η έξοδος κατασκευής δεν ταιριάζει με την παραγγελία κατασκευής" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Η ποσότητα πρέπει να είναι μεγαλύτερη από 0" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Η ποσότητα δεν μπορεί να είναι μεγαλύτερη από την παραγόμενη ποσότητα" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "Η έξοδος κατασκευής δεν έχει περάσει όλες τις απαιτούμενες δοκιμές" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Το προϊόν κατασκευής {serial} δεν έχει περάσει όλες τις απαιτούμενες δοκιμές" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Δεν είναι δυνατή η μερική ολοκλήρωση προϊόντος κατασκευής με δεσμευμένα στοιχεία" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Η διαθέσιμη ποσότητα ({q}) έχει ξεπεραστεί" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Γραμμή εντολής κατασκευής" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Αντικείμενο κατασκευής" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Αντικείμενο κατασκευής" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Ποσότητα" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Απαιτούμενη ποσότητα για την εντολή κατασκευής" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Ποσότητα καταναλωμένου αποθέματος" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Το στοιχείο κατασκευής πρέπει να ορίζει μια έξοδο κατασκευής, καθώς το κύριο τμήμα επισημαίνεται ως ανιχνεύσιμο" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Το επιλεγμένο στοιχείο αποθέματος δεν ταιριάζει με τη γραμμή ΤΥ" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Η ποσότητα πρέπει να είναι 1 για σειριακό απόθεμα" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Η καταχωρημένη ποσότητα ({q}) δεν πρέπει να υπερβαίνει τη διαθέσιμη ποσότητα αποθέματος ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Στοιχείο αποθέματος είναι υπερ-κατανεμημένο" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Στοιχείο Αποθέματος" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Στοιχείο πηγαίου αποθέματος" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Ποσότητα αποθέματος για διάθεση για κατασκευή" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Εγκατάσταση σε" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Αποθήκη προορισμού" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Επίπεδο κατασκευής" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Όνομα Προϊόντος" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Κατασκευή Εξόδου" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Η έξοδος κατασκευής δεν ταιριάζει με την παραγγελία κατασκευής" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Το εξερχόμενο μέρος δεν ταιριάζει με το μέρος BuildOrder" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Η παραγγελία κατασκευής έχει ολοκληρωθεί" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Αυτή η έξοδος κατασκευής δεν έχει εκχωρηθεί πλήρως" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Εισάγετε ποσότητα για την έξοδο κατασκευής" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Ακέραιη ποσότητα που απαιτείται για ανιχνεύσιμα μέρη" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Ακέραιη ποσότητα που απαιτείται, καθώς ο λογαριασμός των υλικών περιέχει ανιχνεύσιμα μέρη" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Σειριακοί αριθμοί" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Εισάγετε ποσότητα για την έξοδο κατασκευής" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Τοποθεσία αποθέματος για την έξοδο κατασκευής" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Αυτόματη Κατανομή Σειριακών Αριθμών" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Αυτόματη κατανομή των απαιτούμενων στοιχείων με τους αντίστοιχους σειριακούς αριθμούς" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Οι παρακάτω σειριακοί αριθμοί υπάρχουν ήδη ή δεν είναι έγκυροι" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Πρέπει να παρέχεται μια λίστα με τα αποτελέσματα κατασκευής" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Θέση αποθέματος για απορριφθείσες παραγωγές" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Απόρριψη Κατανομών" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Απορρίψτε τυχόν κατανομές αποθέματος για παραγωγές που έχουν απορριφθεί" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Αιτία απόρριψης προϊόντων κατασκευής" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Τοποθεσία για ολοκληρωμένα προϊόντα κατασκευής" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Αποδοχή Ελλιπούς Δέσμευσης" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Ολοκλήρωσε τα προϊόντα εάν το απόθεμα δεν έχει δεσμευτεί πλήρως" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Κατανάλωση δεσμευμένου αποθέματος" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Κατανάλωση οποιουδήποτε αποθέματος έχει ήδη δεσμευτεί για αυτή την κατασκευή" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Αφαίρεση Ατελείωτων Προϊόντων" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Διαγράψτε τυχόν προϊόντα κατασκευής που δεν έχουν ολοκληρωθεί" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Δεν επιτρέπεται" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Αποδοχή ως κατανάλωση για αυτή την παραγγελία κατασκευής" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Αποδέσμευση πριν από την ολοκλήρωση αυτής της παραγγελίας κατασκευής" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Υπερ-δεσμευμένο Απόθεμα" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Πώς θέλετε να χειριστείτε το επιπλέον απόθεμα που έχει δεσμευτεί στην παραγγελία κατασκευής" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Μερικά στοιχεία αποθέματος έχουν υπερ-δεσμευτεί" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Αποδοχή Μη Δεσμευμένων" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Αποδεχτείτε ότι αντικείμενα αποθέματος δεν έχουν δεσμευτεί πλήρως σε αυτή την παραγγελία κατασκευής" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Το απαιτούμενο απόθεμα δεν έχει δεσμευτεί πλήρως" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Αποδοχή Μη Ολοκληρωμένων" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Αποδεχτείτε ότι ο απαιτούμενος αριθμός προϊόντων κατασκευής δεν έχει ολοκληρωθεί" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Ο απαιτούμενος αριθμός προϊόντων δεν έχει ολοκληρωθεί" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Η εντολή κατασκευής έχει ανοιχτές θυγατρικές εντολές κατασκευής" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Η εντολή κατασκευής πρέπει να βρίσκεται σε κατάσταση παραγωγής" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Η παραγγελία κατασκευής έχει ελλιπή προϊόντα" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Γραμμή Κατασκευής" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Προϊόν Κατασκευής" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Το προϊόν κατασκευής πρέπει να δείχνει στην ίδια κατασκευή" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Αντικείμενο Γραμμής Κατασκευής" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part πρέπει να δείχνει στο ίδιο εξάρτημα με τη εντολή κατασκευής" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Το στοιχείο πρέπει να υπάρχει στο απόθεμα" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Η διαθέσιμη ποσότητα ({q}) έχει ξεπεραστεί" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Πρέπει να καθοριστεί έξοδος κατασκευής για την κατανομή ανιχνεύσιμων Προϊόντων" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Δεν μπορεί να καθοριστεί έξοδος κατασκευής για την κατανομή μη ανιχνεύσιμων Προϊόντων" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Πρέπει να δοθούν στοιχεία κατανομής" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Τοποθεσία αποθέματος από την οποία θα ληφθούν τα Προϊόντα (αφήστε κενό για λήψη από οποιαδήποτε τοποθεσία)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Εξαίρεση τοποθεσίας" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Εξαιρέστε στοιχεία αποθέματος από αυτή την επιλεγμένη τοποθεσία" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Εναλλάξιμο απόθεμα" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Στοιχεία αποθέματος σε πολλές τοποθεσίες μπορούν να χρησιμοποιηθούν εναλλάξ" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Εναλλακτικό απόθεμα" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Να επιτρέπεται η κατανομή εναλλακτικών Προϊόντων" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Προαιρετικά στοιχεία" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Κατανομή προαιρετικών στοιχείων BOM στην εντολή κατασκευής" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Αναφορά BOM" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID Προϊόντος BOM" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Όνομα Προϊόντος BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Κατασκευή" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Aντικειμένου προμηθευτή" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Δεσμευμένη ποσότητα" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Αναφορά κατασκευής" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Όνομα κατηγορίας Προϊόντος" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Ανιχνεύσιμο" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Κληρονομημένο" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Να επιτρέπονται παραλλαγές" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Στοιχείο BOM" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "Σε παραγωγή" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Προγραμματισμένο για κατασκευή" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Εξωτερικό απόθεμα" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Διαθέσιμο απόθεμα" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Διαθέσιμο εναλλακτικό απόθεμα" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Διαθέσιμο απόθεμα παραλλαγών" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "Η καταναλωμένη ποσότητα υπερβαίνει τη δεσμευμένη ποσότητα" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Προαιρετικές σημειώσεις για την κατανάλωση αποθέματος" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "Το στοιχείο κατασκευής πρέπει να αντιστοιχεί στη σωστή εντολή κατασκευής" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Διπλή κατανομή στοιχείου κατασκευής" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "Η γραμμή κατασκευής πρέπει να αντιστοιχεί στη σωστή εντολή κατασκευής" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Διπλή κατανομή γραμμής κατασκευής" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Πρέπει να δοθεί τουλάχιστον ένα στοιχείο ή μία γραμμή" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Σε εκκρεμότητα" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Παραγωγή" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Σε αναμονή" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Ακυρώθηκε" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Ολοκληρώθηκε" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Η παραγγελία κατασκευής {build} έχει ολοκληρωθεί" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Η παραγγελία κατασκευής έχει ολοκληρωθεί" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Απαιτείται απόθεμα για την εντολή κατασκευής" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Η εντολή κατασκευής {build} απαιτεί επιπλέον απόθεμα" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Εκπρόθεσμη εντολή κατασκευής" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Η εντολή κατασκευής {bo} είναι πλέον εκπρόθεσμη" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "Είναι σύνδεσμος" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Είναι αρχείο" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Ο χρήστης δεν έχει δικαίωμα να διαγράψει αυτά τα συνημμένα" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Ο χρήστης δεν έχει δικαίωμα να διαγράψει αυτό το συνημμένο" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Η λίστα επιλογών είναι κλειδωμένη" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Μη έγκυρος κωδικός συναλλάγματος" @@ -1539,15 +1641,20 @@ msgstr "Δεν δόθηκαν έγκυροι κωδικοί συναλλάγμα msgid "No plugin" msgstr "Χωρίς πρόσθετο" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Ετικέτα κωδικού έργου" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Ενημερώθηκε" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Χρονική σήμανση τελευταίας ενημέρωσης" @@ -1567,794 +1674,844 @@ msgstr "Μοναδικός κωδικός έργου" msgid "Project description" msgstr "Περιγραφή έργου" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Χρήστης ή ομάδα υπεύθυνη για αυτό το έργο" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Κλειδί ρυθμίσεων" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Τιμή ρυθμίσεων" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Η επιλεγμένη τιμή δεν είναι έγκυρη επιλογή" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Η τιμή πρέπει να είναι boolean" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Η τιμή πρέπει να είναι ακέραιος αριθμός" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Η τιμή πρέπει να είναι έγκυρος αριθμός" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Η τιμή δεν περνά τους ελέγχους εγκυρότητας" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Η συμβολοσειρά κλειδιού πρέπει να είναι μοναδική" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Χρήστης" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Ποσότητα κλιμακωτής τιμής" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Τιμή" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Τιμή μονάδας στη συγκεκριμένη ποσότητα" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Endpoint" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Το endpoint στο οποίο λαμβάνεται αυτό το webhook" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Όνομα για αυτό το webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Ενεργό" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Χρήστης ή ομάδα υπεύθυνη για αυτό το έργο" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Κλειδί ρυθμίσεων" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Τιμή ρυθμίσεων" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Η επιλεγμένη τιμή δεν είναι έγκυρη επιλογή" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Η τιμή πρέπει να είναι boolean" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Η τιμή πρέπει να είναι ακέραιος αριθμός" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Η τιμή πρέπει να είναι έγκυρος αριθμός" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Η τιμή δεν περνά τους ελέγχους εγκυρότητας" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Η συμβολοσειρά κλειδιού πρέπει να είναι μοναδική" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Χρήστης" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Ποσότητα κλιμακωτής τιμής" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Τιμή" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Τιμή μονάδας στη συγκεκριμένη ποσότητα" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Endpoint" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Το endpoint στο οποίο λαμβάνεται αυτό το webhook" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Όνομα για αυτό το webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Είναι αυτό το webhook ενεργό" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token πρόσβασης" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Μυστικό" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Κοινόχρηστο μυστικό για HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID μηνύματος" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Μοναδικό αναγνωριστικό για αυτό το μήνυμα" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Host" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Host από τον οποίο παραλήφθηκε αυτό το μήνυμα" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Κεφαλίδα" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Κεφαλίδα αυτού του μηνύματος" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Κείμενο" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Κείμενο αυτού του μηνύματος" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Endpoint στο οποίο παραλήφθηκε αυτό το μήνυμα" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Επεξεργάστηκε" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Ολοκληρώθηκε η εργασία σε αυτό το μήνυμα;" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "ID" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Τίτλος" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Σύνδεσμος" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Δημοσιεύθηκε" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Συντάκτης" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Περίληψη" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Αναγνωσμένο" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Διαβάστηκε αυτό το νέο;" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Αρχείο εικόνας" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Τύπος μοντέλου-στόχου για αυτή την εικόνα" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "ID μοντέλου-στόχου για αυτή την εικόνα" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Προσαρμοσμένη μονάδα" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Το σύμβολο μονάδας πρέπει να είναι μοναδικό" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Το όνομα μονάδας πρέπει να είναι έγκυρο αναγνωριστικό" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Όνομα μονάδας" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Σύμβολο" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Προαιρετικό σύμβολο μονάδας" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Ορισμός" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Ορισμός μονάδας" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Συνημμένο" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Το αρχείο λείπει" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Λείπει ο εξωτερικός σύνδεσμος" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Τύπος μοντέλου" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Τύπος μοντέλου-στόχου για την εικόνα" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Επιλέξτε αρχείο για επισύναψη" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Σχόλιο" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Σχόλιο συνημμένου" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Ημερομηνία μεταφόρτωσης" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Ημερομηνία μεταφόρτωσης του αρχείου" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Μέγεθος αρχείου" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Μέγεθος αρχείου σε bytes" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Μη έγκυρος τύπος μοντέλου που ορίστηκε για το συνημμένο" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Προσαρμοσμένη κατάσταση" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Προσαρμοσμένες καταστάσεις" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Σετ κατάστασης αναφοράς" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Σετ καταστάσεων που επεκτείνεται με αυτή την προσαρμοσμένη κατάσταση" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Λογικό κλειδί" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Λογικό κλειδί κατάστασης που είναι ισοδύναμο με αυτή την προσαρμοσμένη κατάσταση στη λογική της εφαρμογής" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Τιμή" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Αριθμητική τιμή που θα αποθηκευτεί στη βάση δεδομένων των μοντέλων" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Όνομα της κατάστασης" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Ετικέτα" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Ετικέτα που θα εμφανίζεται στο frontend" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Χρώμα" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Χρώμα που θα εμφανίζεται στο frontend" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Μοντέλο" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Μοντέλο με το οποίο συσχετίζεται αυτή η κατάσταση" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Πρέπει να επιλεγεί μοντέλο" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Πρέπει να επιλεγεί κλειδί" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Πρέπει να επιλεγεί λογικό κλειδί" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "Το κλειδί πρέπει να είναι διαφορετικό από το λογικό κλειδί" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Πρέπει να δοθεί έγκυρη κλάση κατάστασης αναφοράς" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "Το κλειδί πρέπει να είναι διαφορετικό από τα λογικά κλειδιά της κατάστασης αναφοράς" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "Το λογικό κλειδί πρέπει να ανήκει στα λογικά κλειδιά της κατάστασης αναφοράς" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Το όνομα πρέπει να είναι διαφορετικό από τα ονόματα της κατάστασης αναφοράς" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Λίστα επιλογών" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Λίστες επιλογών" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Όνομα της λίστας επιλογών" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Περιγραφή της λίστας επιλογών" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Κλειδωμένο" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Είναι αυτή η λίστα επιλογών κλειδωμένη;" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Μπορεί να χρησιμοποιηθεί αυτή η λίστα επιλογών;" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Πρόσθετο πηγής" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Πρόσθετο που παρέχει τη λίστα επιλογών" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Συμβολοσειρά πηγής" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Προαιρετική συμβολοσειρά που ταυτοποιεί την πηγή που χρησιμοποιείται για αυτή τη λίστα" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Προεπιλεγμένη καταχώρηση" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Προεπιλεγμένη καταχώρηση για αυτή τη λίστα επιλογών" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Δημιουργήθηκε" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Ημερομηνία και ώρα δημιουργίας της λίστας επιλογών" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Τελευταία ενημέρωση" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Ημερομηνία και ώρα της τελευταίας ενημέρωσης της λίστας επιλογών" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Καταχώρηση λίστας επιλογών" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Καταχωρήσεις λίστας επιλογών" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Λίστα επιλογών στην οποία ανήκει αυτή η καταχώρηση" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Τιμή της καταχώρησης λίστας επιλογών" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Ετικέτα για την καταχώρηση λίστας επιλογών" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Περιγραφή της καταχώρησης λίστας επιλογών" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Είναι ενεργή αυτή η καταχώρηση λίστας επιλογών;" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Πρότυπο παραμέτρου" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Οι παράμετροι τύπου checkbox δεν μπορούν να έχουν μονάδες" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Οι παράμετροι τύπου checkbox δεν μπορούν να έχουν επιλογές" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Οι επιλογές πρέπει να είναι μοναδικές" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Το όνομα προτύπου παραμέτρου πρέπει να είναι μοναδικό" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Όνομα παραμέτρου" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Μονάδες" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Φυσικές μονάδες για αυτή την παράμετρο" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Περιγραφή παραμέτρου" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Checkbox" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Είναι αυτή η παράμετρος τύπου checkbox;" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Επιλογές" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Έγκυρες επιλογές για αυτή την παράμετρο (διαχωρισμένες με κόμμα)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Λίστα επιλογών για αυτή την παράμετρο" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Ενεργό" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Μη έγκυρη επιλογή για την τιμή παραμέτρου" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Πρότυπο" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Δεδομένα" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Τιμή παραμέτρου" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Σημείωση" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Προαιρετικό πεδίο σημείωσης" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Σάρωση barcode" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Δεδομένα barcode" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Χρήστης που σάρωσε το barcode" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Χρονική σήμανση" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Ημερομηνία και ώρα της σάρωσης barcode" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "URL endpoint που επεξεργάστηκε το barcode" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Πλαίσιο" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Δεδομένα πλαισίου για τη σάρωση barcode" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Απόκριση" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Δεδομένα απόκρισης από τη σάρωση barcode" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Αποτέλεσμα" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Ήταν επιτυχημένη η σάρωση barcode;" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Παρουσιάστηκε σφάλμα" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: Η διαγραφή του log email προστατεύεται. Ορίστε το INVENTREE_PROTECT_EMAIL_LOG σε False για να επιτραπεί η διαγραφή." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "Μήνυμα email" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "Μηνύματα email" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Ανακοινώθηκε" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Εστάλη" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Απέτυχε" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Παραδόθηκε" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Επιβεβαιώθηκε" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Εισερχόμενο" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Εξερχόμενο" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Χωρίς απάντηση" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Παρακολούθηση παράδοσης" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Παρακολούθηση ανάγνωσης" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Παρακολούθηση κλικ" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "Global ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Αναγνωριστικό για αυτό το μήνυμα (ενδέχεται να παρέχεται από εξωτερικό σύστημα)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "ID νήματος" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Αναγνωριστικό για αυτό το νήμα μηνυμάτων (ενδέχεται να παρέχεται από εξωτερικό σύστημα)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Νήμα" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Συνδεδεμένο νήμα για αυτό το μήνυμα" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "Νήμα email" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "Νήματα email" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Κλειδί" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Μοναδικό κλειδί για αυτό το νήμα (χρησιμοποιείται για την ταυτοποίησή του)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Μοναδικό αναγνωριστικό για αυτό το νήμα" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Ξεκίνησε εσωτερικά" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Ξεκίνησε αυτό το νήμα εσωτερικά;" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Ημερομηνία και ώρα δημιουργίας του νήματος" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Ημερομηνία και ώρα της τελευταίας ενημέρωσης του νήματος" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} ακυρώθηκε" msgid "A order that is assigned to you was canceled" msgstr "Μια παραγγελία που σας είχε ανατεθεί ακυρώθηκε" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Είδη που παραλήφθηκαν" @@ -2388,104 +2545,100 @@ msgstr "Είδη έχουν παραληφθεί έναντι εντολής α msgid "Items have been received against a return order" msgstr "Είδη έχουν παραληφθεί έναντι εντολής επιστροφής" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Δείχνει αν η ρύθμιση παρακάμπτεται από μεταβλητή περιβάλλοντος" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Παράκαμψη" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Εκτελείται" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Εργασίες σε αναμονή" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Προγραμματισμένες εργασίες" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Αποτυχημένες εργασίες" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID εργασίας" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Μοναδικό ID εργασίας" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Κλείδωμα" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Χρόνος κλειδώματος" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Όνομα εργασίας" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Συνάρτηση" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Όνομα συνάρτησης" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Ορίσματα" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Ορίσματα εργασίας" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Ορίσματα λέξεων-κλειδιών" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Ορίσματα λέξεων-κλειδιών της εργασίας" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Όνομα αρχείου" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Τύπος μοντέλου" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Ο χρήστης δεν έχει δικαίωμα να δημιουργήσει ή να επεξεργαστεί συνημμένα για αυτό το μοντέλο" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Η λίστα επιλογών είναι κλειδωμένη" - #: common/setting/system.py:97 msgid "No group" msgstr "Χωρίς ομάδα" @@ -2614,13 +2767,13 @@ msgstr "Διάστημα ενημέρωσης νομισμάτων" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Κάθε πότε θα ενημερώνονται οι συναλλαγματικές ισοτιμίες (0 για απενεργοποίηση)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "ημέρες" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Πρόσθετο ενημέρωσης νομισμάτων που θα χρησιμοποιηθεί" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Αυστηρή επικύρωση URL" @@ -2760,947 +2921,1017 @@ msgstr "Πρόσθετο δημιουργίας barcode" msgid "Plugin to use for internal barcode data generation" msgstr "Πρόσθετο που θα χρησιμοποιείται για εσωτερική δημιουργία δεδομένων barcode" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Εκδόσεις Προϊόντων" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Ενεργοποίηση πεδίου έκδοσης για Aντικειμένου" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Μόνο εκδόσεις συναρμολογήσεων" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Να επιτρέπονται εκδόσεις μόνο για Προϊόντα συναρμολόγησης" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Να επιτρέπεται διαγραφή από συναρμολόγηση" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Να επιτρέπεται η διαγραφή Προϊόντων που χρησιμοποιούνται σε συναρμολόγηση" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Πρότυπο regular expression για αντιστοίχιση IPN Προϊόντος" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Να επιτρέπονται διπλά IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Να επιτρέπεται σε πολλαπλά Προϊόντα να μοιράζονται το ίδιο IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Να επιτρέπεται η επεξεργασία IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Να επιτρέπεται η αλλαγή της τιμής IPN κατά την επεξεργασία ενός Προϊόντος" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Αντιγραφή δεδομένων BOM Προϊόντος" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Αντιγραφή δεδομένων BOM από προεπιλογή κατά τον διπλασιασμό ενός Προϊόντος" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Αντιγραφή δεδομένων παραμέτρων Προϊόντος" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Αντιγραφή δεδομένων παραμέτρων από προεπιλογή κατά τον διπλασιασμό ενός Προϊόντος" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Αντιγραφή δεδομένων δοκιμών Προϊόντος" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Αντιγραφή δεδομένων δοκιμών από προεπιλογή κατά τον διπλασιασμό ενός Προϊόντος" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Αντιγραφή προτύπων παραμέτρων κατηγορίας" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Αντιγραφή προτύπων παραμέτρων κατηγορίας κατά τη δημιουργία Προϊόντος" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Τα Προϊόντα είναι πρότυπα από προεπιλογή" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Τα Προϊόντα μπορούν να συναρμολογούνται από άλλα συστατικά από προεπιλογή" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Συστατικό" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Τα Προϊόντα μπορούν να χρησιμοποιούνται ως υποσυστατικά από προεπιλογή" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Αγοράσιμο" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Τα Προϊόντα είναι αγοράσιμα από προεπιλογή" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Πωλήσιμο" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Τα Προϊόντα είναι πωλήσιμα από προεπιλογή" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Τα Προϊόντα είναι ανιχνεύσιμα από προεπιλογή" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Εικονικό" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Τα Προϊόντα είναι εικονικά από προεπιλογή" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Εμφάνιση σχετικών Προϊόντων" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Εμφάνιση σχετικών Προϊόντων για ένα Aντικειμένου" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Αρχικά δεδομένα αποθέματος" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Να επιτρέπεται η δημιουργία αρχικού αποθέματος κατά την προσθήκη νέου Προϊόντος" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Αρχικά δεδομένα προμηθευτή" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Να επιτρέπεται η δημιουργία αρχικών δεδομένων προμηθευτή κατά την προσθήκη νέου Προϊόντος" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Μορφή εμφάνισης ονόματος Προϊόντος" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Μορφή με την οποία εμφανίζεται το όνομα του Προϊόντος" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Προεπιλεγμένο εικονίδιο κατηγορίας Προϊόντος" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Προεπιλεγμένο εικονίδιο κατηγορίας Προϊόντος (κενό σημαίνει χωρίς εικονίδιο)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Ελάχιστα δεκαδικά ψηφία τιμολόγησης" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Ελάχιστος αριθμός δεκαδικών ψηφίων που θα εμφανίζονται στα δεδομένα τιμολόγησης" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Μέγιστα δεκαδικά ψηφία τιμολόγησης" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Μέγιστος αριθμός δεκαδικών ψηφίων που θα εμφανίζονται στα δεδομένα τιμολόγησης" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Χρήση τιμών προμηθευτή" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Συμπερίληψη κλιμακωτών τιμών προμηθευτή στους συνολικούς υπολογισμούς τιμών" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Υπέρβαση μέσω ιστορικού αγορών" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Οι ιστορικές τιμές εντολών αγοράς υπερισχύουν των κλιμακωτών τιμών προμηθευτή" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Χρήση τιμολόγησης στοιχείου αποθέματος" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Χρήση τιμών από χειροκίνητα καταχωρημένα δεδομένα αποθέματος για τους υπολογισμούς τιμών" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Ηλικία τιμολόγησης στοιχείου αποθέματος" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Εξαίρεση στοιχείων αποθέματος παλαιότερων από αυτόν τον αριθμό ημερών από τους υπολογισμούς τιμών" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Χρήση τιμολόγησης παραλλαγών" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Συμπερίληψη τιμών παραλλαγών στους συνολικούς υπολογισμούς τιμών" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Μόνο ενεργές παραλλαγές" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Χρήση μόνο ενεργών Προϊόντων παραλλαγών για τον υπολογισμό τιμών παραλλαγών" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Αυτόματη ενημέρωση τιμών" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Αυτόματη ενημέρωση τιμών Προϊόντων όταν αλλάζουν τα εσωτερικά δεδομένα" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Διάστημα επαναυπολογισμού τιμών" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Αριθμός ημερών πριν ενημερωθούν αυτόματα οι τιμές των Προϊόντων" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Εσωτερικές τιμές" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Ενεργοποίηση εσωτερικών τιμών για Προϊόντα" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Υπέρβαση μέσω εσωτερικής τιμής" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Όταν υπάρχουν, οι εσωτερικές τιμές υπερισχύουν των υπολογισμών εύρους τιμών" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Ενεργοποίηση εκτύπωσης ετικετών" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Ενεργοποίηση εκτύπωσης ετικετών από το web interface" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "DPI εικόνας ετικέτας" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Ανάλυση DPI κατά τη δημιουργία αρχείων εικόνας για πρόσθετα εκτύπωσης ετικετών" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Ενεργοποίηση αναφορών" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Ενεργοποίηση δημιουργίας αναφορών" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Λειτουργία αποσφαλμάτωσης" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Δημιουργία αναφορών σε λειτουργία αποσφαλμάτωσης (έξοδος HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Καταγραφή σφαλμάτων αναφορών" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Καταγραφή σφαλμάτων που προκύπτουν κατά τη δημιουργία αναφορών" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Μέγεθος σελίδας" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Προεπιλεγμένο μέγεθος σελίδας για PDF αναφορές" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Επιβολή μονάδων παραμέτρων" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Αν δοθούν μονάδες, οι τιμές των παραμέτρων πρέπει να αντιστοιχούν στις καθορισμένες μονάδες" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Καθολικά μοναδικοί σειριακοί αριθμοί" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Οι σειριακοί αριθμοί των στοιχείων αποθέματος πρέπει να είναι καθολικά μοναδικοί" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Διαγραφή εξαντλημένου αποθέματος" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Καθορίζει την προεπιλεγμένη συμπεριφορά όταν ένα στοιχείο αποθέματος εξαντλείται" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Πρότυπο κωδικού παρτίδας" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Πρότυπο για τη δημιουργία προεπιλεγμένων κωδικών παρτίδας για στοιχεία αποθέματος" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Λήξη αποθέματος" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Ενεργοποίηση λειτουργίας λήξης αποθέματος" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Πώληση ληγμένου αποθέματος" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Να επιτρέπεται η πώληση ληγμένου αποθέματος" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Χρόνος απαρχαίωσης αποθέματος" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Αριθμός ημερών που τα στοιχεία αποθέματος θεωρούνται παλαιωμένα πριν λήξουν" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Κατασκευή με ληγμένο απόθεμα" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Να επιτρέπεται η κατασκευή με ληγμένο απόθεμα" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Έλεγχος ιδιοκτησίας αποθέματος" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Ενεργοποίηση ελέγχου ιδιοκτησίας σε τοποθεσίες και στοιχεία αποθέματος" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Προεπιλεγμένο εικονίδιο τοποθεσίας αποθέματος" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Προεπιλεγμένο εικονίδιο τοποθεσίας αποθέματος (κενό σημαίνει χωρίς εικονίδιο)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Εμφάνιση εγκατεστημένων στοιχείων αποθέματος" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Εμφάνιση εγκατεστημένων στοιχείων αποθέματος στους πίνακες αποθέματος" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Έλεγχος BOM κατά την εγκατάσταση στοιχείων" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Τα εγκατεστημένα στοιχεία αποθέματος πρέπει να υπάρχουν στο BOM του γονικού Προϊόντος" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Να επιτρέπεται μεταφορά εκτός αποθέματος" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Να επιτρέπεται η μεταφορά στοιχείων αποθέματος που δεν είναι διαθέσιμα μεταξύ τοποθεσιών αποθέματος" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Πρότυπο αναφοράς εντολής κατασκευής" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Απαιτούμενο πρότυπο για τη δημιουργία του πεδίου αναφοράς εντολής κατασκευής" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Απαίτηση υπεύθυνου κατόχου" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Πρέπει να οριστεί υπεύθυνος ιδιοκτήτης για κάθε παραγγελία" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Απαίτηση ενεργού προϊόντος" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Αποτροπή δημιουργίας εντολής παραγωγής για ανενεργά προϊόντα" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Απαίτηση κλειδωμένου προϊόντος" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Αποτροπή δημιουργίας εντολής παραγωγής για ξεκλείδωτα προϊόντα" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Απαίτηση έγκυρης BOM" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Αποτροπή δημιουργίας εντολής παραγωγής αν δεν έχει επικυρωθεί η BOM" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Απαίτηση κλειστών θυγατρικών εντολών" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Αποτροπή ολοκλήρωσης εντολής παραγωγής μέχρι να κλείσουν όλες οι θυγατρικές εντολές" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Εξωτερικές εντολές παραγωγής" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Ενεργοποίηση λειτουργίας εξωτερικών εντολών παραγωγής" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Φραγή έως ότου περάσουν τα τεστ" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Αποτροπή ολοκλήρωσης εξόδων παραγωγής μέχρι να περάσουν όλα τα απαιτούμενα τεστ" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Ενεργοποίηση εντολών επιστροφής" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Ενεργοποίηση λειτουργίας εντολών επιστροφής στη διεπαφή χρήστη" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Μοτίβο αναφοράς εντολής επιστροφής" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Απαιτούμενο μοτίβο για τη δημιουργία του πεδίου αναφοράς εντολής επιστροφής" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Επεξεργασία ολοκληρωμένων εντολών επιστροφής" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Επιτρέπει την επεξεργασία εντολών επιστροφής μετά την ολοκλήρωσή τους" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Μοτίβο αναφοράς εντολής πώλησης" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Απαιτούμενο μοτίβο για τη δημιουργία του πεδίου αναφοράς εντολής πώλησης" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Προεπιλεγμένη αποστολή εντολής πώλησης" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Ενεργοποίηση δημιουργίας προεπιλεγμένης αποστολής με τις εντολές πώλησης" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Επεξεργασία ολοκληρωμένων εντολών πώλησης" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Επιτρέπει την επεξεργασία εντολών πώλησης μετά την αποστολή ή ολοκλήρωσή τους" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "Η αποστολή απαιτεί έλεγχο" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Αποτροπή ολοκλήρωσης αποστολών μέχρι να ελεγχθούν τα είδη" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Σήμανση αποσταλμένων εντολών ως ολοκληρωμένων" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Οι εντολές πώλησης που επισημαίνονται ως αποσταλμένες ολοκληρώνονται αυτόματα, παρακάμπτοντας την κατάσταση «απεσταλμένο»" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Μοτίβο αναφοράς εντολής αγοράς" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Απαιτούμενο μοτίβο για τη δημιουργία του πεδίου αναφοράς εντολής αγοράς" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Επεξεργασία ολοκληρωμένων εντολών αγοράς" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Επιτρέπει την επεξεργασία εντολών αγοράς μετά την αποστολή ή ολοκλήρωσή τους" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Μετατροπή νομίσματος" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Μετατροπή της αξίας είδους στο βασικό νόμισμα κατά την παραλαβή αποθέματος" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Αυτόματη ολοκλήρωση εντολών αγοράς" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Αυτόματη σήμανση εντολών αγοράς ως ολοκληρωμένων όταν έχουν παραληφθεί όλα τα είδη" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Ενεργοποίηση υπενθύμισης κωδικού" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Ενεργοποίηση λειτουργίας υπενθύμισης κωδικού στις σελίδες σύνδεσης" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Ενεργοποίηση εγγραφής" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Ενεργοποίηση αυτοεγγραφής χρηστών στις σελίδες σύνδεσης" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "Ενεργοποίηση SSO" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Ενεργοποίηση SSO στις σελίδες σύνδεσης" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Ενεργοποίηση εγγραφής μέσω SSO" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Ενεργοποίηση αυτοεγγραφής μέσω SSO στις σελίδες σύνδεσης" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Ενεργοποίηση συγχρονισμού ομάδων SSO" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Ενεργοποίηση συγχρονισμού ομάδων InvenTree με ομάδες από τον IdP" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "Κλειδί ομάδας SSO" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Το όνομα του πεδίου ομάδων που παρέχεται από τον IdP" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "Χάρτης ομάδων SSO" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Χαρτογράφηση ομάδων SSO σε τοπικές ομάδες InvenTree. Αν η ομάδα δεν υπάρχει, θα δημιουργηθεί." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Αφαίρεση ομάδων εκτός SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Αν πρέπει να αφαιρούνται ομάδες από τον χρήστη όταν δεν παρέχονται από τον IdP. Η απενεργοποίηση μπορεί να προκαλέσει προβλήματα ασφαλείας" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "Απαίτηση email" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Απαίτηση συμπλήρωσης email κατά την εγγραφή" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Αυτόματη συμπλήρωση χρηστών SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Αυτόματη συμπλήρωση στοιχείων χρήστη από τα δεδομένα SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Email δύο φορές" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Κατά την εγγραφή ζητείται το email δύο φορές" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Κωδικός δύο φορές" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Κατά την εγγραφή ζητείται ο κωδικός δύο φορές" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Επιτρεπόμενοι τομείς" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Περιορισμός εγγραφής σε συγκεκριμένους τομείς (χωρισμένοι με κόμμα, ξεκινούν με @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Ομάδα κατά την εγγραφή" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Ομάδα στην οποία εκχωρούνται οι νέοι χρήστες κατά την εγγραφή. Με ενεργό SSO sync, χρησιμοποιείται μόνο όταν δεν μπορεί να δοθεί ομάδα από τον IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Επιβολή MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Οι χρήστες πρέπει να χρησιμοποιούν πολυπαραγοντική ασφάλεια" -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Έλεγχος plugins κατά την εκκίνηση" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Έλεγχος ότι όλα τα plugins είναι εγκατεστημένα κατά την εκκίνηση – χρήσιμο σε container περιβάλλοντα" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Έλεγχος για ενημερώσεις plugin" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Ενεργοποίηση περιοδικών ελέγχων για ενημερώσεις εγκατεστημένων plugins" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Ενεργοποίηση URL integration" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Ενεργοποίηση προσθήκης URL routes από plugins" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Ενεργοποίηση ενσωμάτωσης στην πλοήγηση" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Ενεργοποίηση ενσωμάτωσης των plugins στην πλοήγηση" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Ενεργοποίηση ενσωμάτωσης εφαρμογών" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Ενεργοποίηση προσθήκης εφαρμογών από plugins" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Ενεργοποίηση ενσωμάτωσης χρονοπρογραμματισμού" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Ενεργοποίηση εκτέλεσης χρονοπρογραμματισμένων εργασιών από plugins" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Ενεργοποίηση ενσωμάτωσης γεγονότων" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Ενεργοποίηση απόκρισης plugins σε εσωτερικά γεγονότα" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Ενεργοποίηση ενσωμάτωσης διεπαφής" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Ενεργοποίηση ενσωμάτωσης plugins στη διεπαφή χρήστη" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Ενεργοποίηση ενσωμάτωσης email" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Ενεργοποίηση επεξεργασίας εισερχόμενων/εξερχόμενων emails από plugins" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Ενεργοποίηση κωδικών έργου" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Ενεργοποίηση κωδικών έργου για την παρακολούθηση projects" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Ενεργοποίηση καταγραφής ιστορικών επιπέδων και αξιών αποθέματος" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Εξαίρεση εξωτερικών τοποθεσιών" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Περίοδος αυτόματης απογραφής" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Εμφάνιση πλήρους ονόματος χρηστών" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Εμφάνιση του πλήρους ονόματος των χρηστών αντί για το όνομα χρήστη" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Εμφάνιση προφίλ χρηστών" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Εμφάνιση προφίλ χρηστών στη σελίδα προφίλ τους" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Ενεργοποίηση δεδομένων σταθμού δοκιμών" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Ενεργοποίηση συλλογής δεδομένων σταθμού δοκιμών για τα αποτελέσματα δοκιμών" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "Ενεργοποίηση ping μηχανημάτων" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Ενεργοποίηση περιοδικού ping των καταχωρημένων μηχανημάτων για έλεγχο της κατάστασής τους" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Αριθμός αποτελεσμάτων που εμφανίζονται σε κάθε ενότητα του παραθύρου προεπισκόπησης αναζήτησης" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Αναζήτηση με regex" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Ενεργοποίηση κανονικών εκφράσεων (regex) στα ερωτήματα αναζήτησης" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Αναζήτηση ολόκληρης λέξης" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Τα ερωτήματα αναζήτησης επιστρέφουν αποτελέσματα μόνο για πλήρη ταίριασμα λέξης" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Αναζήτηση σημειώσεων" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Τα ερωτήματα αναζήτησης επιστρέφουν αποτελέσματα που ταιριάζουν με τις σημειώσεις του είδους" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Το πλήκτρο Escape κλείνει φόρμες" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Χρήση του πλήκτρου Escape για κλείσιμο αναδυόμενων φορμών" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Σταθερή γραμμή πλοήγησης" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Η γραμμή πλοήγησης παραμένει σταθερή στο επάνω μέρος της οθόνης" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "Σταθερές κεφαλίδες πινάκων" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Οι κεφαλίδες πινάκων παραμένουν σταθερές στο επάνω μέρος του πίνακα" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Εμφάνιση Spotlight" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Ενεργοποίηση λειτουργίας πλοήγησης Spotlight" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Εικονίδια πλοήγησης" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Εμφάνιση εικονιδίων στη γραμμή πλοήγησης" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Μορφή ημερομηνίας" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Προτιμώμενη μορφή εμφάνισης ημερομηνιών" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Εμφάνιση ιστορικού αποθέματος" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Εμφάνιση πληροφοριών ιστορικού αποθέματος στη σελίδα λεπτομερειών προϊόντος" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Εμφάνιση τελευταίου breadcrumb" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Εμφάνιση της τρέχουσας σελίδας στα breadcrumbs" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Εμφάνιση πλήρους τοποθεσίας αποθέματος σε πίνακες" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Ανενεργό: Η πλήρης διαδρομή τοποθεσίας εμφανίζεται ως tooltip κατά το πέρασμα του δείκτη. Ενεργό: Η πλήρης διαδρομή τοποθεσίας εμφανίζεται ως απλό κείμενο" -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Εμφάνιση πλήρους κατηγορίας προϊόντων σε πίνακες" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Ανενεργό: Η πλήρης διαδρομή κατηγορίας εμφανίζεται ως tooltip κατά το πέρασμα του δείκτη. Ενεργό: Η πλήρης διαδρομή κατηγορίας εμφανίζεται ως απλό κείμενο" -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Λήψη αναφορών σφαλμάτων" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Λήψη ειδοποιήσεων για σφάλματα συστήματος" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Τελευταίες χρησιμοποιημένες εκτυπωτικές μηχανές" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Αποθήκευση των τελευταίων εκτυπωτικών μηχανών που χρησιμοποίησε ο χρήστης" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Δεν δόθηκε τύπος μοντέλου συνημμένου" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Μη έγκυρος τύπος μοντέλου συνημμένου" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Οι ελάχιστες θέσεις δεν μπορούν να είναι περισσότερες από τις μέγιστες" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Οι μέγιστες θέσεις δεν μπορούν να είναι λιγότερες από τις ελάχιστες" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Δεν επιτρέπεται κενός τομέας." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Μη έγκυρο όνομα τομέα: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Η τιμή πρέπει να είναι με κεφαλαία" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Η τιμή πρέπει να είναι έγκυρο όνομα μεταβλητής" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Το προϊόν είναι ενεργό" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Ο κατασκευαστής είναι ενεργός" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Το προϊόν προμηθευτή είναι ενεργό" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Το εσωτερικό προϊόν είναι ενεργό" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Ο προμηθευτής είναι ενεργός" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Κατασκευαστής" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Εταιρεία" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Διαθέτει απόθεμα" @@ -4123,8 +4387,8 @@ msgstr "Τηλέφωνο επικοινωνίας" msgid "Contact email address" msgstr "Email επικοινωνίας" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Επαφή" @@ -4176,283 +4440,283 @@ msgstr "ΑΦΜ" msgid "Company Tax ID" msgstr "ΑΦΜ εταιρείας" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Διεύθυνση" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Διευθύνσεις" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Επιλογή εταιρείας" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Τίτλος διεύθυνσης" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Τίτλος που περιγράφει την εγγραφή διεύθυνσης" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Κύρια διεύθυνση" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Ορισμός ως κύριας διεύθυνσης" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Γραμμή 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Γραμμή διεύθυνσης 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Γραμμή 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Γραμμή διεύθυνσης 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Ταχυδρομικός κώδικας" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Πόλη/Περιοχή" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Πόλη/περιοχή ταχυδρομικού κώδικα" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Πολιτεία/Επαρχία" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Πολιτεία ή επαρχία" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Χώρα" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Χώρα διεύθυνσης" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Σημειώσεις αποστολής για courier" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Σημειώσεις για την αποστολή με courier" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Εσωτερικές σημειώσεις αποστολής" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Σημειώσεις αποστολής για εσωτερική χρήση" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Σύνδεσμος σε πληροφορίες διεύθυνσης (εξωτερικό)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Προϊόν κατασκευαστή" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Βασικό προϊόν" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Επιλογή προϊόντος" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Επιλογή κατασκευαστή" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Κωδικός προϊόντος κατασκευαστή" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL εξωτερικού συνδέσμου προϊόντος κατασκευαστή" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Περιγραφή προϊόντος κατασκευαστή" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Οι μονάδες συσκευασίας πρέπει να είναι συμβατές με τις μονάδες του βασικού προϊόντος" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Οι μονάδες συσκευασίας πρέπει να είναι μεγαλύτερες από το μηδέν" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Το συνδεδεμένο προϊόν κατασκευαστή πρέπει να αναφέρεται στο ίδιο βασικό προϊόν" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Προμηθευτής" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Επιλογή προμηθευτή" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Κωδικός αποθέματος προμηθευτή" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Είναι αυτό το προϊόν προμηθευτή ενεργό;" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Επιλογή προϊόντος κατασκευαστή" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL εξωτερικού συνδέσμου προϊόντος προμηθευτή" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Περιγραφή προϊόντος προμηθευτή" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "βασικό κόστος" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Ελάχιστη χρέωση (π.χ. χρέωση αποθήκευσης)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Συσκευασία" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Συσκευασία προϊόντος" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Ποσότητα ανά συσκευασία" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Συνολική ποσότητα που παρέχεται σε μία συσκευασία. Αφήστε κενό για μεμονωμένα είδη." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "πολλαπλάσιο" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Πολλαπλάσιο παραγγελίας" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Ποσότητα διαθέσιμη από τον προμηθευτή" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Η διαθεσιμότητα ενημερώθηκε" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Ημερομηνία τελευταίας ενημέρωσης δεδομένων διαθεσιμότητας" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Κλιμακωτή τιμή προμηθευτή" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Προεπιλεγμένο νόμισμα που χρησιμοποιείται για αυτόν τον προμηθευτή" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Όνομα εταιρείας" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Σε απόθεμα" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Κλιμακωτές τιμές" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Προέκυψε σφάλμα κατά την εξαγωγή δεδομένων" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Το plugin εξαγωγής δεδομένων επέστρεψε λανθασμένη μορφή δεδομένων" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Μορφή εξαγωγής" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Επιλογή μορφής αρχείου εξαγωγής" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Plugin εξαγωγής" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Επιλογή plugin εξαγωγής" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Πρόσθετες πληροφορίες κατάστασης για αυτό το στοιχείο" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Προσαρμοσμένο κλειδί κατάστασης" @@ -4476,123 +4740,152 @@ msgstr "Τοποθετήθηκε" msgid "Invalid status code" msgstr "Μη έγκυρος κωδικός κατάστασης" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Αρχείο Δεδομένων" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Αρχείο δεδομένων για εισαγωγή" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Στήλες" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Τύπος μοντέλου στόχου για αυτή τη συνεδρία εισαγωγής" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Κατάσταση εισαγωγής" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Προεπιλεγμένες τιμές πεδίων" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Υπερισχύσεις πεδίων" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Φίλτρα πεδίων" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Ενημέρωση υπαρχόντων εγγραφών" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Αν είναι ενεργό, οι υπάρχουσες εγγραφές θα ενημερωθούν με νέα δεδομένα" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Κάποια απαιτούμενα πεδία δεν έχουν αντιστοιχιστεί" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Υπάρχον αναγνωριστικό βάσης δεδομένων για την εγγραφή" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "Η στήλη έχει ήδη αντιστοιχιστεί σε πεδίο της βάσης δεδομένων" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Το πεδίο έχει ήδη αντιστοιχιστεί σε στήλη δεδομένων" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Η αντιστοίχιση στήλης πρέπει να συνδέεται με έγκυρη συνεδρία εισαγωγής" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Η στήλη δεν υπάρχει στο αρχείο δεδομένων" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Το πεδίο δεν υπάρχει στο μοντέλο προορισμού" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Το επιλεγμένο πεδίο είναι μόνο για ανάγνωση" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Συνεδρία εισαγωγής" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Πεδίο" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Στήλη" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Δείκτης γραμμής" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Αρχικά δεδομένα γραμμής" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Σφάλματα" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Έγκυρο" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "Απαιτείται ID για την ενημέρωση υπαρχόντων εγγραφών." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Δεν βρέθηκε εγγραφή με το παρεχόμενο ID" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Δόθηκε μη έγκυρη μορφή ID" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "Απαιτείται ID για την ενημέρωση υπαρχόντων εγγραφών." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Μη υποστηριζόμενη μορφή αρχείου δεδομένων" @@ -4600,43 +4893,47 @@ msgstr "Μη υποστηριζόμενη μορφή αρχείου δεδομέ msgid "Failed to open data file" msgstr "Αποτυχία ανοίγματος αρχείου δεδομένων" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Μη έγκυρες διαστάσεις αρχείου δεδομένων" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Μη έγκυρες προεπιλεγμένες τιμές πεδίων" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Μη έγκυρες υπερισχύσεις πεδίων" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Μη έγκυρα φίλτρα πεδίων" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Γραμμές" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Λίστα ID γραμμών προς αποδοχή" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Δεν δόθηκαν γραμμές" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "Η γραμμή δεν ανήκει σε αυτή τη συνεδρία" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "Η γραμμή περιέχει μη έγκυρα δεδομένα" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "Η γραμμή έχει ήδη ολοκληρωθεί" @@ -4672,115 +4969,115 @@ msgstr "Το αρχείο δεδομένων περιέχει υπερβολικ msgid "Data file contains too many rows" msgstr "Το αρχείο δεδομένων περιέχει υπερβολικά πολλές γραμμές" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Η τιμή πρέπει να είναι έγκυρο Aντικειμένου λεξικού" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Αντίτυπα" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Αριθμός αντιτύπων προς εκτύπωση για κάθε ετικέτα" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Συνδεδεμένος" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Άγνωστο" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Εκτύπωση" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Προειδοποίηση" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Χωρίς μέσο" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Μπλοκάρισμα χαρτιού" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Αποσυνδεδεμένος" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Σφάλμα" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Εκτυπωτής ετικετών" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Άμεση εκτύπωση ετικετών για διάφορα είδη." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Τοποθεσία εκτυπωτή" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Περιορισμός του εκτυπωτή σε συγκεκριμένη τοποθεσία" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Όνομα μηχανήματος" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Τύπος μηχανήματος" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Τύπος μηχανήματος" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Driver" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Driver που χρησιμοποιείται για το μηχάνημα" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Τα μηχανήματα μπορούν να απενεργοποιούνται" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Ο driver είναι διαθέσιμος" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Χωρίς σφάλματα" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Αρχικοποιήθηκε" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Κατάσταση μηχανήματος" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Μηχάνημα" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Ρύθμιση μηχανήματος" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Τύπος ρύθμισης" @@ -4792,7 +5089,7 @@ msgstr "Κλειδί ιδιότητας" msgid "Value of the property" msgstr "Τιμή ιδιότητας" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Ομάδα" @@ -4816,117 +5113,118 @@ msgstr "Μέγιστη πρόοδος" msgid "Maximum value for progress type, required if type=progress" msgstr "Μέγιστη τιμή για τύπο προόδου, απαιτείται αν type=progress" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Αναφορά παραγγελίας" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Σε εκκρεμότητα" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Έχει κωδικό έργου" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Δημιουργήθηκε από" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Δημιουργήθηκε πριν" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Δημιουργήθηκε μετά" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Έχει ημερομηνία έναρξης" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Ημερομηνία έναρξης πριν" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Ημερομηνία έναρξης μετά" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Έχει ημερομηνία στόχο" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Ημερομηνία στόχος πριν" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Ημερομηνία στόχος μετά" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Έχει τιμολόγηση" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Ολοκληρώθηκε πριν" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Ολοκληρώθηκε μετά" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Εξωτερική εντολή παραγωγής" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Παραγγελία" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Η παραγγελία ολοκληρώθηκε" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Εσωτερικό προϊόν" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Η παραγγελία είναι σε εκκρεμότητα" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Ολοκληρώθηκε" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Έχει αποστολή" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Εντολή αγοράς" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Εντολή αγοράς" msgid "Sales Order" msgstr "Εντολές Πώλησης" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Εντολή επιστροφής" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Συνολική τιμή" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Συνολική τιμή για αυτή την παραγγελία" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Νόμισμα παραγγελίας" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Νόμισμα για αυτή την παραγγελία (αφήστε κενό για χρήση της προεπιλογής εταιρείας)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Αυτή η παραγγελία είναι κλειδωμένη και δεν μπορεί να τροποποιηθεί" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Η επαφή δεν αντιστοιχεί στην επιλεγμένη εταιρεία" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "Η ημερομηνία έναρξης πρέπει να είναι πριν από την ημερομηνία στόχο" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "Η διεύθυνση δεν αντιστοιχεί στην επιλεγμένη εταιρεία" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Περιγραφή παραγγελίας (προαιρετικά)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Επιλογή κωδικού έργου για αυτή την παραγγελία" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Σύνδεσμος σε εξωτερική σελίδα" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Ημερομηνία έναρξης" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Προγραμματισμένη ημερομηνία έναρξης για αυτή την παραγγελία" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Επιθυμητή Προθεσμία" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Αναμενόμενη ημερομηνία παράδοσης παραγγελίας. Η παραγγελία θα θεωρείται εκπρόθεσμη μετά από αυτή την ημερομηνία." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Ημερομηνία έκδοσης" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Ημερομηνία έκδοσης της παραγγελίας" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Χρήστης ή ομάδα υπεύθυνη για αυτή την παραγγελία" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Σημείο επαφής για αυτή την παραγγελία" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Διεύθυνση εταιρείας για αυτή την παραγγελία" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Αναφορά παραγγελίας" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Κατάσταση" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Κατάσταση εντολής αγοράς" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Εταιρεία από την οποία παραγγέλνονται τα είδη" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Αναφορά προμηθευτή" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Κωδικός αναφοράς παραγγελίας προμηθευτή" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "παραλήφθηκε από" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Ημερομηνία ολοκλήρωσης της παραγγελίας" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Προορισμός" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Προορισμός για τα παραληφθέντα είδη" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Ο προμηθευτής προϊόντος πρέπει να ταιριάζει με τον προμηθευτή της εντολής αγοράς" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Η γραμμή δεν αντιστοιχεί στην εντολή αγοράς" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "Στη γραμμή λείπει συνδεδεμένο προϊόν" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Η ποσότητα πρέπει να είναι θετικός αριθμός" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Πελάτης" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Εταιρεία στην οποία πωλούνται τα είδη" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Κατάσταση εντολής πώλησης" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Αναφορά πελάτη " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Κωδικός αναφοράς παραγγελίας πελάτη" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Ημερομηνία αποστολής" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "απεστάλη από" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Η γραμμή δεν συνδέεται με αυτή την παραγγελία" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Δεν βρέθηκε αντιστοίχιση για τους παρακάτω σειριακούς αριθμούς" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Οι παρακάτω σειριακοί αριθμοί δεν είναι διαθέσιμοι" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Η παραγγελία είναι ήδη ολοκληρωμένη" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Η παραγγελία είναι ήδη ακυρωμένη" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Μόνο μια ανοικτή παραγγελία μπορεί να σημειωθεί ως ολοκληρωμένη" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Η παραγγελία δεν μπορεί να ολοκληρωθεί καθώς υπάρχουν μη ολοκληρωμένες αποστολές" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Η παραγγελία δεν μπορεί να ολοκληρωθεί καθώς υπάρχουν μη ολοκληρωμένες δεσμεύσεις αποθέματος" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Η παραγγελία δεν μπορεί να ολοκληρωθεί καθώς υπάρχουν μη ολοκληρωμένες γραμμές" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "Η παραγγελία είναι κλειδωμένη και δεν μπορεί να τροποποιηθεί" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Ποσότητα είδους" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Αναφορά γραμμής" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Σημειώσεις γραμμής" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Ημερομηνία στόχος για αυτή τη γραμμή (αφήστε κενό για χρήση της ημερομηνίας στόχου από την παραγγελία)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Περιγραφή γραμμής (προαιρετικά)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Πρόσθετο πλαίσιο για αυτή τη γραμμή" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Τιμή μονάδας" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Γραμμή εντολής αγοράς" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Το προϊόν προμηθευτή πρέπει να ταιριάζει με τον προμηθευτή" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "Η εντολή παραγωγής πρέπει να έχει σημειωθεί ως εξωτερική" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Οι εντολές παραγωγής μπορούν να συνδεθούν μόνο με προϊόντα συναρμολόγησης" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "Το προϊόν της εντολής παραγωγής πρέπει να ταιριάζει με το προϊόν της γραμμής" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Προϊόν προμηθευτή" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Παραλήφθηκε" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Αριθμός ειδών που παραλήφθηκαν" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Τιμή αγοράς" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Τιμή μονάδας αγοράς" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Εξωτερική εντολή παραγωγής που θα καλυφθεί από αυτή τη γραμμή" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Επιπλέον γραμμή εντολής αγοράς" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Γραμμή εντολής πώλησης" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Μόνο πωλήσιμα προϊόντα μπορούν να αντιστοιχιστούν σε εντολή πώλησης" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Τιμή πώλησης" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Τιμή μονάδας πώλησης" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Αποστάλθηκε" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Ποσότητα που αποστάλθηκε" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Αποστολή εντολής πώλησης" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "Η διεύθυνση αποστολής πρέπει να αντιστοιχεί στον πελάτη" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Διεύθυνση αποστολής για αυτή την αποστολή" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Ημερομηνία αποστολής" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Ημερομηνία παράδοσης" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Ημερομηνία παράδοσης της αποστολής" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Έλεγχος από" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Χρήστης που έλεγξε αυτή την αποστολή" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Αποστολή" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Αριθμός αποστολής" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Αριθμός παρακολούθησης" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Πληροφορίες παρακολούθησης αποστολής" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Αριθμός τιμολογίου" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Αριθμός αναφοράς του σχετικού τιμολογίου" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Η αποστολή έχει ήδη σταλεί" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Η αποστολή δεν έχει δεσμευμένα είδη αποθέματος" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "Η αποστολή πρέπει να ελεγχθεί πριν μπορέσει να ολοκληρωθεί" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Επιπλέον γραμμή εντολής πώλησης" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Δέσμευση αποθέματος εντολής πώλησης" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Δεν έχει αντιστοιχιστεί είδος αποθέματος" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Δεν είναι δυνατή η δέσμευση είδους αποθέματος σε γραμμή με διαφορετικό προϊόν" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Δεν είναι δυνατή η δέσμευση αποθέματος σε γραμμή χωρίς προϊόν" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Η ποσότητα δέσμευσης δεν μπορεί να υπερβαίνει την ποσότητα αποθέματος" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Η ποσότητα πρέπει να είναι μεγαλύτερη από 0" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Η ποσότητα πρέπει να είναι 1 για σειριοποιημένο είδος αποθέματος" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Η εντολή πώλησης δεν αντιστοιχεί στην αποστολή" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Η αποστολή δεν αντιστοιχεί στην εντολή πώλησης" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Γραμμή" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Αναφορά αποστολής εντολής πώλησης" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Είδος" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Επιλογή είδους αποθέματος προς δέσμευση" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Εισαγωγή ποσότητας δέσμευσης αποθέματος" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Αναφορά εντολής επιστροφής" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Εταιρεία από την οποία επιστρέφονται τα είδη" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Κατάσταση εντολής επιστροφής" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Γραμμή εντολής επιστροφής" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Πρέπει να καθοριστεί είδος αποθέματος" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Η ποσότητα επιστροφής υπερβαίνει την ποσότητα αποθέματος" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "Η ποσότητα επιστροφής πρέπει να είναι μεγαλύτερη από το μηδέν" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Μη έγκυρη ποσότητα για σειριοποιημένο είδος αποθέματος" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Επιλογή είδους προς επιστροφή από τον πελάτη" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Ημερομηνία παραλαβής" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Έκβαση" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Έκβαση για αυτή τη γραμμή" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Κόστος που σχετίζεται με την επιστροφή ή επισκευή για αυτή τη γραμμή" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Επιπλέον γραμμή εντολής επιστροφής" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID παραγγελίας" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID της παραγγελίας προς αντιγραφή" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Αντιγραφή γραμμών" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Αντιγραφή γραμμών από την αρχική παραγγελία" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Αντιγραφή επιπλέον γραμμών" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Αντιγραφή επιπλέον γραμμών από την αρχική παραγγελία" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Αντιγραφή παραμέτρων" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Γραμμές" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Ολοκληρωμένες γραμμές" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Αντιγραφή παραγγελίας" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Καθορίστε επιλογές για την αντιγραφή αυτής της παραγγελίας" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Μη έγκυρο ID παραγγελίας" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Όνομα προμηθευτή" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Η παραγγελία δεν μπορεί να ακυρωθεί" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Να επιτρέπεται το κλείσιμο της παραγγελίας με μη ολοκληρωμένες γραμμές" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Η παραγγελία έχει μη ολοκληρωμένες γραμμές" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Η παραγγελία δεν είναι ανοικτή" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Αυτόματη τιμολόγηση" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Αυτόματος υπολογισμός τιμής αγοράς βάσει των δεδομένων προϊόντος προμηθευτή" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Νόμισμα τιμής αγοράς" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Συγχώνευση ειδών" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Συγχώνευση ειδών με το ίδιο προϊόν, προορισμό και ημερομηνία στόχο σε μία γραμμή" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Εσωτερικός κωδικός προϊόντος" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Εσωτερική ονομασία προϊόντος" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Πρέπει να καθοριστεί προϊόν προμηθευτή" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Πρέπει να καθοριστεί εντολή αγοράς" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Ο προμηθευτής πρέπει να ταιριάζει με την εντολή αγοράς" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Η εντολή αγοράς πρέπει να ταιριάζει με τον προμηθευτή" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Γραμμή" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Επιλογή τοποθεσίας προορισμού για τα παραληφθέντα είδη" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Εισαγάγετε κωδικό παρτίδας για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Ημερομηνία λήξης" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Εισαγάγετε ημερομηνία λήξης για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Εισαγάγετε σειριακούς αριθμούς για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Παράκαμψη πληροφοριών συσκευασίας για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Πρόσθετη σημείωση για τα εισερχόμενα είδη αποθέματος" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Barcode" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Σαρωμένο barcode" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Το barcode χρησιμοποιείται ήδη" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Πρέπει να δοθούν γραμμές" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Πρέπει να καθοριστεί τοποθεσία προορισμού" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Οι δοθείσες τιμές barcode πρέπει να είναι μοναδικές" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Αποστολές" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Ολοκληρωμένες αποστολές" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Νόμισμα τιμής πώλησης" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Δεσμευμένα είδη" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Δεν δόθηκαν λεπτομέρειες αποστολής" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Η γραμμή δεν συνδέεται με αυτή την παραγγελία" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Η ποσότητα πρέπει να είναι θετική" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Εισαγάγετε σειριακούς αριθμούς προς δέσμευση" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Η αποστολή έχει ήδη σταλεί" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Η αποστολή δεν συνδέεται με αυτή την παραγγελία" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Δεν βρέθηκε αντιστοίχιση για τους παρακάτω σειριακούς αριθμούς" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Οι παρακάτω σειριακοί αριθμοί δεν είναι διαθέσιμοι" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Γραμμή εντολής επιστροφής" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Η γραμμή δεν αντιστοιχεί στην εντολή επιστροφής" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Η γραμμή έχει ήδη παραληφθεί" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Είδη μπορούν να παραληφθούν μόνο για παραγγελίες που είναι σε εξέλιξη" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Ποσότητα προς επιστροφή" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Νόμισμα τιμής γραμμής" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Χάθηκε" @@ -5718,1279 +6125,1312 @@ msgstr "Χάθηκε" msgid "Returned" msgstr "Επιστράφηκε" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Σε Εξέλιξη" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Επιστροφή" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Επισκευή" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Αντικατάσταση" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Επιστροφή χρημάτων" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Απόρριψη" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Εκδόθηκε" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Εκπρόθεσμη εντολή αγοράς" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Η εντολή αγοράς {po} είναι πλέον εκπρόθεσμη" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Εκπρόθεσμη εντολή πώλησης" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Η εντολή πώλησης {so} είναι πλέον εκπρόθεσμη" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Εκπρόθεσμη εντολή επιστροφής" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Η εντολή επιστροφής {ro} είναι πλέον εκπρόθεσμη" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Με αστέρι" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Φιλτράρισμα κατά κατηγορίες με αστέρι" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Βάθος" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Φιλτράρισμα κατά βάθος κατηγορίας" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Ανώτατο επίπεδο" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Φιλτράρισμα κατά κατηγορίες ανώτατου επιπέδου" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Κατά κληρονομικότητα" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Συμπερίληψη υποκατηγοριών στα φιλτραρισμένα αποτελέσματα" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Γονική" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Φιλτράρισμα κατά γονική κατηγορία" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Εξαίρεση υποκατηγοριών κάτω από την καθορισμένη κατηγορία" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Έχει αποτελέσματα" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Είναι παραλλαγή" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Είναι αναθεώρηση" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Έχει αναθεωρήσεις" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "Έγκυρο BOM" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Κατηγορίες κατά κληρονομικότητα" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Αν είναι αληθές, συμπεριλαμβάνονται είδη σε θυγατρικές κατηγορίες της δοσμένης κατηγορίας" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Φιλτράρισμα κατά αριθμητικό ID κατηγορίας ή τη λέξη 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Το προϊόν συναρμολόγησης είναι υπό δοκιμή" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Το προϊόν Προϊόντος είναι υπό δοκιμή" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Χρήσεις" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Κατηγορία προϊόντος" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Κατηγορίες προϊόντων" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Προεπιλεγμένη τοποθεσία" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Προεπιλεγμένη τοποθεσία για προϊόντα σε αυτή την κατηγορία" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Δομική" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Τα προϊόντα δεν μπορούν να αντιστοιχιστούν απευθείας σε δομική κατηγορία, αλλά μπορούν να αντιστοιχιστούν σε θυγατρικές κατηγορίες." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Προεπιλεγμένες λέξεις-κλειδιά" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Προεπιλεγμένες λέξεις-κλειδιά για προϊόντα σε αυτή την κατηγορία" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Εικονίδιο" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Εικονίδιο (προαιρετικό)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Δεν μπορείτε να κάνετε αυτή την κατηγορία προϊόντων δομική επειδή κάποια προϊόντα έχουν ήδη αντιστοιχιστεί σε αυτή!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Πρότυπο παραμέτρου κατηγορίας προϊόντος" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Προεπιλεγμένη τιμή" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Προεπιλεγμένη τιμή παραμέτρου" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Προϊόντα" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Δεν είναι δυνατή η διαγραφή αυτού του προϊόντος επειδή είναι κλειδωμένο" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Δεν είναι δυνατή η διαγραφή αυτού του προϊόντος επειδή είναι ακόμη ενεργό" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Δεν είναι δυνατή η διαγραφή αυτού του προϊόντος επειδή χρησιμοποιείται σε συναρμολόγηση" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Το προϊόν '{self}' δεν μπορεί να χρησιμοποιηθεί στο BOM για '{parent}' (αναδρομικά)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Το προϊόν '{parent}' χρησιμοποιείται στο BOM για '{self}' (αναδρομικά)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "Το IPN πρέπει να ταιριάζει με το πρότυπο regex {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Το προϊόν δεν μπορεί να είναι αναθεώρηση του εαυτού του" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Οι αναθεωρήσεις επιτρέπονται μόνο για προϊόντα συναρμολόγησης" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Δεν μπορεί να γίνει αναθεώρηση προϊόντος προτύπου" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "Το γονικό προϊόν πρέπει να αντιστοιχεί στο ίδιο πρότυπο" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Υπάρχει ήδη είδος αποθέματος με αυτόν τον σειριακό αριθμό" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Δεν επιτρέπεται διπλό IPN στις ρυθμίσεις προϊόντος" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Υπάρχει ήδη διπλή αναθεώρηση προϊόντος." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Υπάρχει ήδη προϊόν με αυτό το όνομα, IPN και αναθεώρηση." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Τα προϊόντα δεν μπορούν να αντιστοιχιστούν σε δομικές κατηγορίες προϊόντων!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Όνομα προϊόντος" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Είναι πρότυπο" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Είναι αυτό το προϊόν προϊόν προτύπου;" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Είναι αυτό το προϊόν παραλλαγή άλλου προϊόντος;" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Παραλλαγή του" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Περιγραφή προϊόντος (προαιρετικά)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Λέξεις-κλειδιά" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Λέξεις-κλειδιά προϊόντος για βελτίωση της ορατότητας στα αποτελέσματα αναζήτησης" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Κατηγορία προϊόντος" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Αριθμός αναθεώρησης ή έκδοσης προϊόντος" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Αναθεώρηση" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Είναι αυτό το προϊόν αναθεώρηση άλλου προϊόντος;" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Αναθεώρηση του" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Πού αποθηκεύεται συνήθως αυτό το είδος;" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Προεπιλεγμένη λήξη" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Χρόνος λήξης (σε ημέρες) για είδη αποθέματος αυτού του προϊόντος" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Ελάχιστο απόθεμα" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Ελάχιστο επιτρεπτό επίπεδο αποθέματος" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Μονάδες μέτρησης για αυτό το προϊόν" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Μπορεί αυτό το προϊόν να κατασκευαστεί από άλλα προϊόντα;" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Μπορεί αυτό το προϊόν να χρησιμοποιηθεί για την κατασκευή άλλων προϊόντων;" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Έχει αυτό το προϊόν ιχνηλάτηση για μοναδικά είδη;" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Μπορούν να καταχωρηθούν αποτελέσματα δοκιμών για αυτό το προϊόν;" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Μπορεί αυτό το προϊόν να αγοραστεί από εξωτερικούς προμηθευτές;" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Μπορεί αυτό το προϊόν να πωληθεί σε πελάτες;" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Είναι αυτό το προϊόν ενεργό;" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Κλειδωμένα προϊόντα δεν μπορούν να τροποποιηθούν" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Είναι αυτό ένα εικονικό προϊόν, όπως προϊόν λογισμικού ή άδεια;" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "Το BOM έχει επικυρωθεί" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Είναι το BOM για αυτό το προϊόν έγκυρο;" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Άθροισμα ελέγχου BOM" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Αποθηκευμένο άθροισμα ελέγχου BOM" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Έλεγχος BOM από" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Ημερομηνία ελέγχου BOM" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Χρήστης δημιουργίας" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Ιδιοκτήτης υπεύθυνος για αυτό το προϊόν" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Πώληση πολλαπλάσιων" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Νόμισμα που χρησιμοποιείται για την προσωρινή αποθήκευση υπολογισμών τιμολόγησης" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Ελάχιστο κόστος BOM" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Ελάχιστο κόστος προϊόντων Προϊόντων" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Μέγιστο κόστος BOM" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Μέγιστο κόστος προϊόντων Προϊόντων" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Ελάχιστο κόστος αγοράς" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Ελάχιστο ιστορικό κόστος αγοράς" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Μέγιστο κόστος αγοράς" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Μέγιστο ιστορικό κόστος αγοράς" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Ελάχιστη εσωτερική τιμή" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Ελάχιστο κόστος βάσει εσωτερικών κλιμακωτών τιμών" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Μέγιστη εσωτερική τιμή" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Μέγιστο κόστος βάσει εσωτερικών κλιμακωτών τιμών" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Ελάχιστη τιμή προμηθευτή" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Ελάχιστη τιμή προϊόντος από εξωτερικούς προμηθευτές" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Μέγιστη τιμή προμηθευτή" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Μέγιστη τιμή προϊόντος από εξωτερικούς προμηθευτές" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Ελάχιστο κόστος παραλλαγής" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Υπολογισμένο ελάχιστο κόστος προϊόντων παραλλαγών" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Μέγιστο κόστος παραλλαγής" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Υπολογισμένο μέγιστο κόστος προϊόντων παραλλαγών" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Ελάχιστο κόστος" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Παράκαμψη ελάχιστου κόστους" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Μέγιστο κόστος" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Παράκαμψη μέγιστου κόστους" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Υπολογισμένο συνολικό ελάχιστο κόστος" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Υπολογισμένο συνολικό μέγιστο κόστος" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Ελάχιστη τιμή πώλησης" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Ελάχιστη τιμή πώλησης βάσει κλιμακωτών τιμών" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Μέγιστη τιμή πώλησης" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Μέγιστη τιμή πώλησης βάσει κλιμακωτών τιμών" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Ελάχιστο κόστος πώλησης" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Ελάχιστη ιστορική τιμή πώλησης" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Μέγιστο κόστος πώλησης" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Μέγιστη ιστορική τιμή πώλησης" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Προϊόν για απογραφή" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Αριθμός ειδών" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Αριθμός μεμονωμένων εγγραφών αποθέματος κατά τον χρόνο απογραφής" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Συνολικό διαθέσιμο απόθεμα κατά τον χρόνο απογραφής" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Ημερομηνία" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Ημερομηνία που πραγματοποιήθηκε η απογραφή" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Ελάχιστο κόστος αποθέματος" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Εκτιμώμενο ελάχιστο κόστος αποθέματος σε διαθεσιμότητα" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Μέγιστο κόστος αποθέματος" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Εκτιμώμενο μέγιστο κόστος αποθέματος σε διαθεσιμότητα" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Κλιμακωτή τιμή πώλησης προϊόντος" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Πρότυπο δοκιμής προϊόντος" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Μη έγκυρο όνομα προτύπου - πρέπει να περιλαμβάνει τουλάχιστον έναν αλφαριθμητικό χαρακτήρα" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Πρότυπα δοκιμών μπορούν να δημιουργηθούν μόνο για προϊόντα που είναι υπό δοκιμή" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Υπάρχει ήδη πρότυπο δοκιμής με το ίδιο κλειδί για το προϊόν" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Όνομα δοκιμής" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Εισαγάγετε όνομα για τη δοκιμή" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Κλειδί δοκιμής" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Απλοποιημένο κλειδί για τη δοκιμή" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Περιγραφή δοκιμής" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Εισαγάγετε περιγραφή για αυτή τη δοκιμή" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Είναι αυτή η δοκιμή ενεργή;" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Απαραίτητη" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Απαιτείται η επιτυχής ολοκλήρωση αυτής της δοκιμής;" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Απαιτεί τιμή" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Απαιτεί αυτή η δοκιμή τιμή κατά την προσθήκη αποτελέσματος δοκιμής;" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Απαιτεί συνημμένο" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Απαιτεί αυτή η δοκιμή συνημμένο αρχείο κατά την προσθήκη αποτελέσματος δοκιμής;" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Έγκυρες επιλογές για αυτή τη δοκιμή (διαχωρισμένες με κόμμα)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "Το στοιχείο BOM δεν μπορεί να τροποποιηθεί - η συναρμολόγηση είναι κλειδωμένη" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Το στοιχείο BOM δεν μπορεί να τροποποιηθεί - η συναρμολόγηση παραλλαγής είναι κλειδωμένη" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Επιλέξτε γονικό προϊόν" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Υποπροϊόν" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Επιλέξτε προϊόν που θα χρησιμοποιηθεί στο BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Ποσότητα BOM για αυτό το στοιχείο BOM" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Αυτό το στοιχείο BOM είναι προαιρετικό" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Αυτό το στοιχείο BOM είναι αναλώσιμο (δεν παρακολουθείται στις εντολές παραγωγής)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Ποσότητα ρύθμισης" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Επιπλέον απαιτούμενη ποσότητα για μια παραγωγή, για να ληφθούν υπόψη οι απώλειες ρύθμισης" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Φθορά" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Εκτιμώμενη φθορά για μια παραγωγή, εκφρασμένη ως ποσοστό (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Πολλαπλάσιο στρογγυλοποίησης" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Στρογγυλοποίηση προς τα πάνω της απαιτούμενης ποσότητας παραγωγής στο πλησιέστερο πολλαπλάσιο αυτής της τιμής" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Αναφορά στοιχείου BOM" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Σημειώσεις στοιχείου BOM" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Άθροισμα ελέγχου" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Άθροισμα ελέγχου γραμμής BOM" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Επικυρωμένο" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Αυτό το στοιχείο BOM έχει επικυρωθεί" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Κληρονομείται" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Αυτό το στοιχείο BOM κληρονομείται από τα BOM για προϊόντα παραλλαγών" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Είδη αποθέματος για προϊόντα παραλλαγών μπορούν να χρησιμοποιηθούν για αυτό το στοιχείο BOM" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Η ποσότητα πρέπει να είναι ακέραια τιμή για προϊόντα με ιχνηλάτηση" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Πρέπει να καθοριστεί υποπροϊόν" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Εναλλακτικό στοιχείο BOM" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Το εναλλακτικό προϊόν δεν μπορεί να είναι το ίδιο με το κύριο προϊόν" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Γονικό στοιχείο BOM" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Εναλλακτικό προϊόν" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Προϊόν 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Προϊόν 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Επιλέξτε σχετικό προϊόν" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Σημείωση για αυτή τη σχέση" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Δεν μπορεί να δημιουργηθεί σχέση προϊόντος μεταξύ ενός προϊόντος και του εαυτού του" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Υπάρχει ήδη διπλή σχέση" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Γονική κατηγορία" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Γονική κατηγορία προϊόντος" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Υποκατηγορίες" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Αποτελέσματα" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Αριθμός αποτελεσμάτων που έχουν καταγραφεί για αυτό το πρότυπο" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Νόμισμα αγοράς για αυτό το είδος αποθέματος" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Το αρχείο δεν είναι εικόνα" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Αρχικό προϊόν" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Επιλέξτε αρχικό προϊόν για αντιγραφή" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Αντιγραφή εικόνας" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Αντιγραφή εικόνας από το αρχικό προϊόν" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Αντιγραφή BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Αντιγραφή λίστας υλικών (BOM) από το αρχικό προϊόν" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Αντιγραφή δεδομένων παραμέτρων από το αρχικό προϊόν" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Αντιγραφή σημειώσεων" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Αντιγραφή σημειώσεων από το αρχικό προϊόν" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Αντιγραφή δοκιμών" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "Αντιγραφή προτύπων δοκιμών από το αρχικό προϊόν" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Αρχική ποσότητα αποθέματος" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Καθορίστε αρχική ποσότητα αποθέματος για αυτό το προϊόν. Αν η ποσότητα είναι μηδέν, δεν προστίθεται απόθεμα" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Αρχική τοποθεσία αποθέματος" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Καθορίστε αρχική τοποθεσία αποθέματος για αυτό το προϊόν" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Επιλέξτε προμηθευτή (ή αφήστε κενό για παράλειψη)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Επιλέξτε κατασκευαστή (ή αφήστε κενό για παράλειψη)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Κωδικός προϊόντος κατασκευαστή" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Η επιλεγμένη εταιρεία δεν είναι έγκυρος προμηθευτής" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Η επιλεγμένη εταιρεία δεν είναι έγκυρος κατασκευαστής" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Υπάρχει ήδη προϊόν κατασκευαστή με αυτό το MPN" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Υπάρχει ήδη προϊόν προμηθευτή με αυτό το SKU" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Όνομα κατηγορίας" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Σε παραγωγή" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Ποσότητα αυτού του προϊόντος που βρίσκεται αυτή τη στιγμή σε παραγωγή" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Εκκρεμής ποσότητα αυτού του προϊόντος που έχει προγραμματιστεί για παραγωγή" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Είδη αποθέματος" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Αναθεωρήσεις" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Συνολικό απόθεμα" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Μη δεσμευμένο απόθεμα" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Απόθεμα παραλλαγών" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Αντιγραφή προϊόντος" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Αντιγραφή αρχικών δεδομένων από άλλο προϊόν" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Αντιγραφή εικόνας" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Αντιγραφή εικόνας από το αρχικό προϊόν" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Αντιγραφή BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Αντιγραφή λίστας υλικών (BOM) από το αρχικό προϊόν" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Αντιγραφή σημειώσεων" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Αντιγραφή σημειώσεων από το αρχικό προϊόν" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Αντιγραφή δοκιμών" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Αντιγραφή προτύπων δοκιμών από το αρχικό προϊόν" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Αρχικό απόθεμα" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Δημιουργία προϊόντος με αρχική ποσότητα αποθέματος" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Πληροφορίες προμηθευτή" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Προσθήκη αρχικών πληροφοριών προμηθευτή για αυτό το προϊόν" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Αντιγραφή παραμέτρων κατηγορίας" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Αντιγραφή προτύπων παραμέτρων από την επιλεγμένη κατηγορία προϊόντος" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Υπάρχουσα εικόνα" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Όνομα αρχείου υπάρχουσας εικόνας προϊόντος" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Το αρχείο εικόνας δεν υπάρχει" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Επικύρωση ολόκληρης της λίστας υλικών (BOM)" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Μπορεί να παραχθεί" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Απαιτείται για εντολές παραγωγής" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Δεσμευμένο σε εντολές παραγωγής" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Απαιτείται για εντολές πώλησης" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Δεσμευμένο σε εντολές πώλησης" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Ελάχιστη τιμή" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Παράκαμψη υπολογισμένης τιμής για την ελάχιστη τιμή" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Νόμισμα ελάχιστης τιμής" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Μέγιστη τιμή" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Παράκαμψη υπολογισμένης τιμής για τη μέγιστη τιμή" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Νόμισμα μέγιστης τιμής" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Ενημέρωση" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Ενημέρωση τιμολόγησης για αυτό το προϊόν" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Δεν ήταν δυνατή η μετατροπή από τα δοθέντα νομίσματα σε {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Η ελάχιστη τιμή δεν πρέπει να είναι μεγαλύτερη από τη μέγιστη τιμή" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Η μέγιστη τιμή δεν πρέπει να είναι μικρότερη από την ελάχιστη τιμή" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Επιλέξτε τη γονική συναρμολόγηση" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Επιλέξτε το προϊόν Προϊόντος" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Επιλέξτε προϊόν από το οποίο θα αντιγραφεί το BOM" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Αφαίρεση υπαρχόντων δεδομένων" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Αφαίρεση υπαρχόντων στοιχείων BOM πριν την αντιγραφή" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Συμπερίληψη κληρονομημένων" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Συμπερίληψη στοιχείων BOM που κληρονομούνται από προϊόντα προτύπων" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Παράλειψη μη έγκυρων γραμμών" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Ενεργοποιήστε αυτή την επιλογή για να παραλείπονται οι μη έγκυρες γραμμές" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Αντιγραφή εναλλακτικών προϊόντων" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Αντιγραφή εναλλακτικών προϊόντων κατά την αντιγραφή στοιχείων BOM" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Ειδοποίηση χαμηλού αποθέματος" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Το διαθέσιμο απόθεμα για το {part.name} έχει πέσει κάτω από το καθορισμένο ελάχιστο επίπεδο" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "Ειδοποίηση παλαιού αποθέματος" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "Έχετε 1 είδος αποθέματος που πλησιάζει την ημερομηνία λήξης του" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "Έχετε {item_count} είδη αποθέματος που πλησιάζουν την ημερομηνία λήξης τους" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "Χωρίς ημερομηνία λήξης" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "Έληξε πριν από {abs(days_diff)} ημέρες" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Λήγει σήμερα" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} ημέρες" @@ -7011,7 +7451,7 @@ msgstr "Δείγμα" msgid "Installed" msgstr "Εγκατεστημένο" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Το πρόσθετο δεν μπορεί να διαγραφεί καθώς είναι ενεργό" @@ -7023,23 +7463,23 @@ msgstr "Δεν έχει καθοριστεί ενέργεια" msgid "No matching action found" msgstr "Δεν βρέθηκε αντίστοιχη ενέργεια" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Δεν βρέθηκε αντιστοίχιση για τα δεδομένα barcode" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Βρέθηκε αντιστοίχιση για τα δεδομένα barcode" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Το μοντέλο δεν υποστηρίζεται" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Δεν βρέθηκε η συγκεκριμένη εγγραφή του μοντέλου" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Το barcode αντιστοιχεί σε υπάρχον είδος" @@ -7055,51 +7495,67 @@ msgstr "Δεν βρέθηκαν αντίστοιχα προϊόντα προμη msgid "Multiple matching supplier parts found" msgstr "Βρέθηκαν πολλαπλά αντίστοιχα προϊόντα προμηθευτή" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Δεν βρέθηκε αντίστοιχο πρόσθετο για τα δεδομένα barcode" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Αντίστοιχο προϊόν προμηθευτή" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Το είδος έχει ήδη παραληφθεί" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Δεν υπάρχει πρόσθετο που να ταιριάζει για το barcode προμηθευτή" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Βρέθηκαν πολλαπλές αντίστοιχες γραμμές" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Δεν βρέθηκε αντίστοιχη γραμμή" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Δεν δόθηκε εντολή πώλησης" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Το barcode δεν αντιστοιχεί σε υπάρχον είδος αποθέματος" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Το είδος αποθέματος δεν ταιριάζει με τη γραμμή" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Μη επαρκές διαθέσιμο απόθεμα" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Το είδος αποθέματος δεσμεύτηκε στην εντολή πώλησης" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Μη επαρκείς πληροφορίες" @@ -7108,23 +7564,23 @@ msgstr "Μη επαρκείς πληροφορίες" msgid "Found matching item" msgstr "Βρέθηκε αντίστοιχο είδος" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Το προϊόν προμηθευτή δεν ταιριάζει με τη γραμμή" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Η γραμμή είναι ήδη ολοκληρωμένη" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Απαιτούνται επιπλέον πληροφορίες για την παραλαβή της γραμμής" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Παραλήφθηκε η γραμμή εντολής αγοράς" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Αποτυχία παραλαβής γραμμής" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Παρέχει εγγενή υποστήριξη για barcodes" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Πρόθεμα σύντομου barcode" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Προσαρμόστε το πρόθεμα που χρησιμοποιείται για σύντομα barcodes, χρήσιμο σε περιβάλλοντα με πολλαπλά InvenTree instances" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "Αυτόματη δημιουργία παραγωγών" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "Αυτόματη δημιουργία εντολών παραγωγής για συναρμολογήσεις" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "Συμπερίληψη ειδών παραλλαγών" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "Συμπερίληψη αποθέματος παραλλαγών προϊόντος στους υπολογισμούς τιμής" +msgid "Include part variant stock in stocktake data" +msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "Εξαγωγέας απογραφής προϊόντος" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "Εξαγωγέας για δεδομένα απογραφής προϊόντος" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "Ελάχιστο μοναδιαίο κόστος" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "Μέγιστο μοναδιαίο κόστος" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "Ελάχιστο συνολικό κόστος" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "Μέγιστο συνολικό κόστος" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "Ειδοποιήσεις διεπαφής InvenTree" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "Ενσωματωμένες μέθοδοι ειδοποιήσεων διεπαφής" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "Ειδοποιήσεις email InvenTree" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "Ενσωματωμένες μέθοδοι ειδοποιήσεων email" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "Επιτρέπονται ειδοποιήσεις email" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "Επιτρέπεται η αποστολή ειδοποιήσεων email σε αυτόν τον χρήστη" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "Ειδοποιήσεις Slack InvenTree" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "Ενσωματωμένες μεθόδοι ειδοποιήσεων Slack" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL που χρησιμοποιείται για την αποστολή μηνυμάτων σε κανάλι Slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Άνοιγμα συνδέσμου" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Παρέχει εγγενή υποστήριξη για εκτύπωση ετικετών PDF" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Λειτουργία αποσφαλμάτωσης" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Ενεργοποίηση λειτουργίας αποσφαλμάτωσης - επιστρέφει ακατέργαστο HTML αντί για PDF" @@ -7653,55 +8117,55 @@ msgstr "τελευταία χρήση" msgid "Options" msgstr "Επιλογές" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Μέγεθος σελίδας για το φύλλο ετικετών" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Παράλειψη ετικετών" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Παράλειψη αυτού του αριθμού ετικετών κατά την εκτύπωση φύλλων ετικετών" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Περίγραμμα" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Εκτύπωση περιγράμματος γύρω από κάθε ετικέτα" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Οριζόντιος προσανατολισμός" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Εκτύπωση του φύλλου ετικετών σε οριζόντιο προσανατολισμό" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Περιθώριο σελίδας" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Περιθώριο γύρω από τη σελίδα σε χιλιοστά" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "Εκτυπωτής φύλλου ετικετών InvenTree" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Τοποθετεί πολλαπλές ετικέτες σε ένα μόνο φύλλο" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Η ετικέτα είναι πολύ μεγάλη για το μέγεθος σελίδας" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Δεν δημιουργήθηκαν ετικέτες" @@ -7753,77 +8217,85 @@ msgstr "Παρέχει υποστήριξη για σάρωση barcodes TME" msgid "The Supplier which acts as 'TME'" msgstr "Ο προμηθευτής που λειτουργεί ως 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Η εγκατάσταση πρόσθετων είναι απενεργοποιημένη" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Το πρόσθετο εγκαταστάθηκε με επιτυχία" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Το πρόσθετο εγκαταστάθηκε στο {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Το πρόσθετο δεν βρέθηκε στο μητρώο" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Το πρόσθετο δεν είναι πακεταρισμένο πρόσθετο" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Δεν βρέθηκε όνομα πακέτου πρόσθετου" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Μόνο οι χρήστες προσωπικού μπορούν να διαχειρίζονται πρόσθετα" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Η απεγκατάσταση προσθέτων είναι απενεργοποιημένη" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι αυτή τη στιγμή ενεργό" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι υποχρεωτικό" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι δείγμα πρόσθετου" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "Το πρόσθετο δεν μπορεί να απεγκατασταθεί καθώς είναι ενσωματωμένο πρόσθετο" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Το πρόσθετο δεν είναι εγκατεστημένο" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Η εγκατάσταση του πρόσθετου δεν βρέθηκε" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Το πρόσθετο απεγκαταστάθηκε με επιτυχία" @@ -7871,25 +8343,25 @@ msgstr "Υποχρεωτικό πρόσθετο" msgid "Package Plugin" msgstr "Πρόσθετο πακέτου" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Πρόσθετο" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Δεν βρέθηκε δημιουργός" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Το πρόσθετο '{p}' δεν είναι συμβατό με την τρέχουσα έκδοση InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Το πρόσθετο απαιτεί τουλάχιστον την έκδοση {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Το πρόσθετο απαιτεί το πολύ την έκδοση {v}" @@ -8114,176 +8586,184 @@ msgstr "Διαγραφή ρύθμισης" msgid "Delete the plugin configuration from the database" msgstr "Διαγραφή της ρύθμισης του πρόσθετου από τη βάση δεδομένων" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "Ο χρήστης στον οποίο εφαρμόζεται αυτή η ρύθμιση" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Είδη" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Το πρόσθετο δεν βρέθηκε" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Το πρόσθετο δεν υποστηρίζει εκτύπωση ετικετών" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Μη έγκυρες διαστάσεις ετικέτας" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Δεν δόθηκαν έγκυρα είδη στο πρότυπο" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Letter" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Υπάρχει ήδη αρχείο προτύπου με αυτό το όνομα" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Όνομα προτύπου" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Περιγραφή προτύπου" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Αριθμός αναθεώρησης (αυτόματη αύξηση)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Συσχέτιση με μοντέλο κατά την εκτύπωση" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Αποθήκευση του παραγόμενου αναφοράς ως συνημμένου στην συνδεδεμένη εγγραφή μοντέλου κατά την εκτύπωση" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Μοτίβο ονόματος αρχείου" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Μοτίβο για τη δημιουργία ονομάτων αρχείων" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Το πρότυπο είναι ενεργό" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Τύπος μοντέλου-στόχου για το πρότυπο" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Φίλτρα" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Φίλτρα ερωτημάτων προτύπου (λίστα ζευγών key=value χωρισμένων με κόμμα)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Αρχείο προτύπου" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Μέγεθος σελίδας για αναφορές PDF" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Απόδοση αναφοράς σε οριζόντιο προσανατολισμό" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "Συγχώνευση" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "Απόδοση μίας ενιαίας αναφοράς για τα επιλεγμένα είδη" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Αναφορά που δημιουργήθηκε από το πρότυπο {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "Σφάλμα σύνταξης προτύπου" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "Σφάλμα κατά την απόδοση της αναφοράς" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Σφάλμα κατά τη δημιουργία της αναφοράς" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "Σφάλμα κατά τη συγχώνευση των αποτελεσμάτων αναφοράς" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Πλάτος [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Πλάτος ετικέτας, σε mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Ύψος [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Ύψος ετικέτας, σε mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Σφάλμα κατά την εκτύπωση ετικετών" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Απόσπασμα" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Αρχείο αποσπάσματος αναφοράς" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Περιγραφή αρχείου αποσπάσματος" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Πόρος" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Αρχείο πόρου αναφοράς" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Περιγραφή αρχείου πόρου" @@ -8291,23 +8771,23 @@ msgstr "Περιγραφή αρχείου πόρου" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Επιλέξτε πρότυπο αναφοράς" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Λίστα από πρωτεύοντα κλειδιά ειδών που θα συμπεριληφθούν στην αναφορά" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Επιλέξτε πρότυπο ετικέτας" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Πρόσθετο εκτύπωσης" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Επιλέξτε πρόσθετο που θα χρησιμοποιηθεί για την εκτύπωση ετικετών" @@ -8338,13 +8818,10 @@ msgstr "Απαιτούμενα υλικά" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Εικόνα προϊόντος" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Εκδόθηκε" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Απαιτείται για" @@ -8380,8 +8857,8 @@ msgstr "Σύνολο" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Σειριακός αριθμός" @@ -8405,7 +8882,7 @@ msgstr "Αναφορά δοκιμών είδους αποθέματος" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Εγκατεστημένα είδη" @@ -8438,810 +8915,922 @@ msgstr "Χωρίς αποτέλεσμα (υποχρεωτικό)" msgid "No result" msgstr "Χωρίς αποτέλεσμα" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Το αρχείο εικόνας δεν βρέθηκε" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "Το tag part_image απαιτεί μία παρουσία Aντικειμένου" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "Το tag company_image απαιτεί ένα Aντικειμένου Company" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Φιλτράρισμα ανά βάθος τοποθεσίας" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Φιλτράρισμα κατά τοποθεσίες ανώτατου επιπέδου" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Συμπερίληψη υποτοποθεσιών στα φιλτραρισμένα αποτελέσματα" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Γονική τοποθεσία" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Φιλτράρισμα βάσει γονικής τοποθεσίας" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Όνομα προϊόντος (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Το όνομα προϊόντος περιέχει (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Όνομα προϊόντος (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "IPN προϊόντος (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "Το IPN προϊόντος περιέχει (χωρίς διάκριση πεζών/κεφαλαίων)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "IPN προϊόντος (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Ελάχιστο απόθεμα" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Μέγιστο απόθεμα" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Κωδικός κατάστασης" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Εξωτερική τοποθεσία" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Αναλωμένο από εντολή παραγωγής" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Εγκατεστημένο σε άλλο είδος αποθέματος" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Δέντρο προϊόντος" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Ενημερώθηκε πριν από" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Ενημερώθηκε μετά από" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Απογραφή πριν από" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Απογραφή μετά από" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Ημερομηνία λήξης πριν από" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Ημερομηνία λήξης μετά από" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Παλαιωμένο" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "Δώστε ένα PK είδους αποθέματος για να εξαιρεθεί αυτό και όλοι οι απόγονοί του" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "Διαδοχικές τοποθεσίες" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "Αν είναι true, περιλαμβάνει είδη σε θυγατρικές τοποθεσίες της δεδομένης τοποθεσίας" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Φιλτράρισμα κατά αριθμητικό ID τοποθεσίας ή τη λέξη 'null'" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Απαιτείται ποσότητα" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Πρέπει να δοθεί έγκυρο προϊόν" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Το δοθέν προϊόν προμηθευτή δεν υπάρχει" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Το προϊόν προμηθευτή έχει ορισμένο μέγεθος συσκευασίας, αλλά η σημαία use_pack_size δεν έχει τεθεί" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Δεν μπορούν να δοθούν σειριακοί αριθμοί για μη ιχνηλάσιμο προϊόν" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "Συμπερίληψη εγκατεστημένων" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Αν είναι true, περιλαμβάνει αποτελέσματα δοκιμών για είδη που είναι εγκατεστημένα κάτω από το συγκεκριμένο είδος αποθέματος" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "Φιλτράρισμα κατά αριθμητικό ID είδους αποθέματος" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Είδος αποθέματος με ID {id} δεν υπάρχει" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Τύπος τοποθεσίας αποθέματος" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Τύποι τοποθεσίας αποθέματος" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Προεπιλεγμένο εικονίδιο για όλες τις τοποθεσίες που δεν έχουν ορισμένο εικονίδιο (προαιρετικό)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Τοποθεσία αποθέματος" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Τοποθεσίες αποθέματος" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Ιδιοκτήτης" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Επιλέξτε ιδιοκτήτη" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Τα είδη αποθέματος δεν μπορούν να τοποθετηθούν απευθείας σε δομικές τοποθεσίες αποθέματος, αλλά μπορούν να τοποθετηθούν σε θυγατρικές τοποθεσίες." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Εξωτερικό" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Πρόκειται για εξωτερική τοποθεσία αποθέματος" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Τύπος τοποθεσίας" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Ο τύπος τοποθεσίας αποθέματος για αυτή την τοποθεσία" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Δεν μπορείτε να κάνετε αυτή την τοποθεσία αποθέματος δομική, επειδή κάποια είδη αποθέματος είναι ήδη τοποθετημένα σε αυτή!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "Το {field} δεν υπάρχει" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Πρέπει να καθοριστεί προϊόν" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Τα είδη αποθέματος δεν μπορούν να τοποθετηθούν σε δομικές τοποθεσίες αποθέματος!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Δεν μπορεί να δημιουργηθεί είδος αποθέματος για εικονικά προϊόντα" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Ο τύπος προϊόντος ('{self.supplier_part.part}') πρέπει να είναι {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Η ποσότητα πρέπει να είναι 1 για είδος με σειριακό αριθμό" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Δεν μπορεί να οριστεί σειριακός αριθμός αν η ποσότητα είναι μεγαλύτερη από 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Το είδος δεν μπορεί να ανήκει στον εαυτό του" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Το είδος πρέπει να έχει αναφορά παραγωγής αν is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Η αναφορά παραγωγής δεν αντιστοιχεί στο ίδιο προϊόν" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Γονικό είδος αποθέματος" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Βασικό προϊόν" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Επιλέξτε αντίστοιχο προϊόν προμηθευτή για αυτό το είδος αποθέματος" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Πού βρίσκεται αυτό το είδος αποθέματος;" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Συσκευασία στην οποία αποθηκεύεται αυτό το είδος αποθέματος" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Εγκατεστημένο σε" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Είναι αυτό το είδος εγκατεστημένο σε άλλο είδος;" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Σειριακός αριθμός για αυτό το είδος" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Κωδικός παρτίδας για αυτό το είδος αποθέματος" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Ποσότητα αποθέματος" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Πηγή παραγωγής" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Εντολή παραγωγής για αυτό το είδος αποθέματος" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Έχει αναλωθεί από" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Εντολή παραγωγής που κατανάλωσε αυτό το είδος αποθέματος" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Πηγή εντολής αγοράς" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Εντολή αγοράς για αυτό το είδος αποθέματος" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Εντολή πώλησης προορισμού" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Ημερομηνία λήξης για το είδος αποθέματος. Το απόθεμα θα θεωρείται ληγμένο μετά από αυτή την ημερομηνία" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Διαγραφή κατά την εξάντληση" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Διαγραφή αυτού του είδους αποθέματος όταν εξαντληθεί" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Τιμή αγοράς ανά μονάδα κατά τον χρόνο αγοράς" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Μετατράπηκε σε προϊόν" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "Η ποσότητα υπερβαίνει το διαθέσιμο απόθεμα" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Το προϊόν δεν έχει οριστεί ως ιχνηλάσιμο" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Η ποσότητα πρέπει να είναι ακέραιος αριθμός" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Η ποσότητα δεν πρέπει να υπερβαίνει το διαθέσιμο απόθεμα ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Οι σειριακοί αριθμοί πρέπει να δοθούν ως λίστα" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Η ποσότητα δεν αντιστοιχεί στους σειριακούς αριθμούς" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Το πρότυπο δοκιμής δεν υπάρχει" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Το είδος αποθέματος έχει αντιστοιχιστεί σε εντολή πώλησης" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Το είδος αποθέματος είναι εγκατεστημένο σε άλλο είδος" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Το είδος αποθέματος περιέχει άλλα είδη" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Το είδος αποθέματος έχει αντιστοιχιστεί σε πελάτη" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Το είδος αποθέματος βρίσκεται αυτή τη στιγμή σε παραγωγή" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Σειριακό απόθεμα δεν μπορεί να συγχωνευθεί" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Διπλότυπα είδη αποθέματος" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Τα είδη αποθέματος πρέπει να αναφέρονται στο ίδιο προϊόν" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Τα είδη αποθέματος πρέπει να αναφέρονται στο ίδιο προϊόν προμηθευτή" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Οι κωδικοί κατάστασης αποθέματος πρέπει να ταιριάζουν" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Το StockItem δεν μπορεί να μετακινηθεί καθώς δεν βρίσκεται σε απόθεμα" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Ιχνηλάτηση είδους αποθέματος" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Σημειώσεις καταχώρησης" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Αποτέλεσμα δοκιμής είδους αποθέματος" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Πρέπει να δοθεί τιμή για αυτή τη δοκιμή" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Πρέπει να μεταφορτωθεί συνημμένο για αυτή τη δοκιμή" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "Μη έγκυρη τιμή για αυτή τη δοκιμή" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Αποτέλεσμα δοκιμής" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Τιμή αποτελέσματος δοκιμής" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Συνημμένο αποτελέσματος δοκιμής" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Σημειώσεις δοκιμής" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Σταθμός δοκιμής" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "Ο αναγνωριστικός κωδικός του σταθμού δοκιμής όπου πραγματοποιήθηκε η δοκιμή" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Έναρξη" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Χρονική σήμανση έναρξης της δοκιμής" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Ολοκλήρωση" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Χρονική σήμανση λήξης της δοκιμής" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Παραγόμενος κωδικός παρτίδας" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Επιλέξτε εντολή παραγωγής" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Επιλέξτε είδος αποθέματος για το οποίο θα δημιουργηθεί κωδικός παρτίδας" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Επιλέξτε τοποθεσία για την οποία θα δημιουργηθεί κωδικός παρτίδας" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Επιλέξτε προϊόν για το οποίο θα δημιουργηθεί κωδικός παρτίδας" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Επιλέξτε εντολή αγοράς" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Εισαγάγετε ποσότητα για τον κωδικό παρτίδας" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Παραγόμενος σειριακός αριθμός" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Επιλέξτε προϊόν για το οποίο θα δημιουργηθεί σειριακός αριθμός" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Ποσότητα σειριακών αριθμών προς δημιουργία" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Πρότυπο δοκιμής για αυτό το αποτέλεσμα" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "Δεν βρέθηκε αντίστοιχη δοκιμή για αυτό το προϊόν" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "Πρέπει να δοθεί Template ID ή όνομα δοκιμής" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "Η ώρα λήξης της δοκιμής δεν μπορεί να είναι προγενέστερη της ώρας έναρξης" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Γονικό είδος" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Γονικό είδος αποθέματος" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Χρήση μεγέθους συσκευασίας κατά την προσθήκη: η καθορισμένη ποσότητα είναι ο αριθμός των συσκευασιών" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "Χρήση μεγέθους συσκευασίας" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Εισαγάγετε σειριακούς αριθμούς για νέα είδη" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Κωδικός προϊόντος προμηθευτή" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Ληγμένο" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Θυγατρικά είδη" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Εγγραφές ιχνηλάτησης" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Τιμή αγοράς αυτού του είδους αποθέματος, ανά μονάδα ή συσκευασία" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Εισαγάγετε τον αριθμό ειδών αποθέματος για σειριοποίηση" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "Δεν δόθηκε είδος αποθέματος" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Η ποσότητα δεν πρέπει να υπερβαίνει το διαθέσιμο απόθεμα ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Τοποθεσία προορισμού αποθέματος" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Δεν μπορούν να εκχωρηθούν σειριακοί αριθμοί σε αυτό το προϊόν" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Οι σειριακοί αριθμοί υπάρχουν ήδη" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Επιλέξτε είδος αποθέματος προς εγκατάσταση" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Ποσότητα προς εγκατάσταση" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Εισαγάγετε την ποσότητα των ειδών προς εγκατάσταση" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Προσθέστε σημείωση συναλλαγής (προαιρετικά)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Η ποσότητα προς εγκατάσταση πρέπει να είναι τουλάχιστον 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Το είδος αποθέματος δεν είναι διαθέσιμο" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Το επιλεγμένο προϊόν δεν βρίσκεται στο Δελτίο Υλικών (BOM)" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Η ποσότητα προς εγκατάσταση δεν πρέπει να υπερβαίνει τη διαθέσιμη ποσότητα" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Τοποθεσία προορισμού για το απεγκατεστημένο είδος" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Επιλέξτε προϊόν στο οποίο θα μετατραπεί το είδος αποθέματος" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Το επιλεγμένο προϊόν δεν είναι έγκυρη επιλογή για μετατροπή" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Δεν είναι δυνατή η μετατροπή είδους αποθέματος με εκχωρημένο SupplierPart" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Κωδικός κατάστασης είδους αποθέματος" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Επιλέξτε προϊόν στο οποίο θα μετατραπεί το είδος αποθέματος" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Το επιλεγμένο προϊόν δεν είναι έγκυρη επιλογή για μετατροπή" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Δεν είναι δυνατή η μετατροπή είδους αποθέματος με εκχωρημένο SupplierPart" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Επιλέξτε είδη αποθέματος για αλλαγή κατάστασης" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Δεν επιλέχθηκαν είδη αποθέματος" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Υποτοποθεσίες" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Γονική τοποθεσία αποθέματος" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Το προϊόν πρέπει να είναι διαθέσιμο για πώληση" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Το είδος έχει δεσμευτεί σε εντολή πώλησης" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Το είδος έχει δεσμευτεί σε εντολή παραγωγής" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Πελάτης στον οποίο θα αποδοθούν τα είδη αποθέματος" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Η επιλεγμένη εταιρεία δεν είναι πελάτης" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Σημειώσεις απόδοσης αποθέματος" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Πρέπει να δοθεί λίστα ειδών αποθέματος" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Σημειώσεις συγχώνευσης αποθέματος" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Να επιτρέπονται διαφορετικοί προμηθευτές" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Να επιτρέπεται η συγχώνευση ειδών αποθέματος με διαφορετικά προϊόντα προμηθευτή" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Να επιτρέπεται διαφορετική κατάσταση" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Να επιτρέπεται η συγχώνευση ειδών αποθέματος με διαφορετικούς κωδικούς κατάστασης" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Πρέπει να δοθούν τουλάχιστον δύο είδη αποθέματος" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Καμία αλλαγή" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Τιμή πρωτεύοντος κλειδιού StockItem" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Το είδος δεν βρίσκεται σε απόθεμα" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "Το είδος βρίσκεται ήδη σε απόθεμα" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "Η ποσότητα δεν πρέπει να είναι αρνητική" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Σημειώσεις συναλλαγής αποθέματος" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "Συγχώνευση με υπάρχον απόθεμα" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Σημειώσεις συναλλαγής αποθέματος" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "Συγχώνευση επιστρεφόμενων ειδών με υπάρχοντα είδη αποθέματος, όπου είναι δυνατό" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Επόμενος σειριακός αριθμός" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Προηγούμενος σειριακός αριθμός" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Έγινε συγχώνευση αποθεμάτων" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Μετατράπηκε σε παραλλαγή" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Δημιουργήθηκε η έξοδος παραγγελίας" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Η έξοδος της σειράς κατασκευής ολοκληρώθηκε" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Η εντολή κατασκευής απορρίφθηκε" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Κατανάλωση με εντολή κατασκευής" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Αποστολή έναντι Εντολής Πώλησης" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Λήφθηκε έναντι Εντολής Αγοράς" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Επιστράφηκε έναντι Εντολής Αγοράς" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Απεστάλη στον πελάτη" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Επιστράφηκε από πελάτη" @@ -9527,19 +10124,19 @@ msgstr "Χρήστες" msgid "Select which users are assigned to this group" msgstr "Επιλέξτε ποιους χρήστες θα αντιστοιχίσετε σε αυτή την ομάδα" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Προσωπικές πληροφορίες" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Δικαιώματα" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Σημαντικές ημερομηνίες" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Το διακριτικό έχει ανακληθεί" @@ -9547,279 +10144,283 @@ msgstr "Το διακριτικό έχει ανακληθεί" msgid "Token has expired" msgstr "Το διακριτικό έχει λήξει" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "Διακριτικό API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Διακριτικά API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Όνομα διακριτικού" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Προσαρμοσμένο όνομα διακριτικού" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Ημερομηνία λήξης διακριτικού" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Τελευταία δραστηριότητα" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Τελευταία φορά που χρησιμοποιήθηκε το διακριτικό" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Έχει ανακληθεί" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Σύνολο δικαιωμάτων" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Προβολή" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Δικαίωμα προβολής Προϊόντων" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Προσθήκη" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Δικαίωμα προσθήκης Προϊόντων" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Τροποποίηση" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Δικαίωμα επεξεργασίας Προϊόντων" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Διαγραφή" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Δικαίωμα διαγραφής Προϊόντων" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Bot" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Εσωτερικός" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Επισκέπτης" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Γλώσσα" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Προτιμώμενη γλώσσα χρήστη" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Θέμα" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Ρυθμίσεις για το web UI σε μορφή JSON - μην τις επεξεργάζεστε χειροκίνητα!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Μικροεφαρμογές" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Ρυθμίσεις για τα widgets του πίνακα ελέγχου σε μορφή JSON - μην τις επεξεργάζεστε χειροκίνητα!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Προβαλλόμενο όνομα" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Επιλεγμένο προβαλλόμενο όνομα χρήστη" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Θέση" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Κύριος επαγγελματικός τίτλος ή θέση" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Μήνυμα κατάστασης χρήστη" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Πληροφορίες τοποθεσίας χρήστη" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "Ο χρήστης χρησιμοποιεί ενεργά το σύστημα" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Προτιμώμενα στοιχεία επικοινωνίας χρήστη" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Τύπος χρήστη" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "Τι τύπος χρήστη είναι;" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Οργανισμός" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Κύριος οργανισμός/φορέας του χρήστη" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Κύρια ομάδα" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Κύρια ομάδα του χρήστη" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Διαχειριστής" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Εντολές Αγοράς" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Εντολές Πώλησης" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Εντολές Επιστροφής" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Όνομα χρήστη" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Όνομα" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Το όνομα του χρήστη" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Επώνυμο" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Το επώνυμο του χρήστη" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Διεύθυνση email του χρήστη" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Υπερχρήστης" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Είναι ο χρήστης υπερχρήστης;" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Είναι ο λογαριασμός χρήστη ενεργός;" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Μόνο υπερχρήστης μπορεί να τροποποιήσει αυτό το πεδίο" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Κωδικός πρόσβασης" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Κωδικός πρόσβασης του χρήστη" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "Παράβλεψη προειδοποίησης" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Παράβλεψη της προειδοποίησης σχετικά με τους κανόνες κωδικού πρόσβασης" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Δεν έχετε δικαίωμα δημιουργίας χρηστών" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Ο λογαριασμός σας δημιουργήθηκε." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Παρακαλούμε χρησιμοποιήστε τη λειτουργία επαναφοράς κωδικού πρόσβασης για να συνδεθείτε" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Καλώς ήρθατε στο InvenTree" diff --git a/src/backend/InvenTree/locale/en/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/en/LC_MESSAGES/django.po index 08d5437435..28b5f1dfb5 100644 --- a/src/backend/InvenTree/locale/en/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,39 +18,43 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "" @@ -66,150 +70,155 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -217,159 +226,203 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -522,46 +575,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -570,9 +625,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -581,432 +637,440 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1018,451 +1082,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "" @@ -1471,59 +1556,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1540,15 +1642,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1568,794 +1675,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2377,7 +2534,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2389,104 +2546,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2615,13 +2768,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2634,6 +2787,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2761,947 +2922,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3882,213 +4113,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4124,8 +4388,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4177,283 +4441,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4477,123 +4741,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4601,43 +4894,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4673,115 +4970,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4793,7 +5090,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4817,117 +5114,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4935,782 +5233,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5719,1279 +6126,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7012,7 +7452,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7024,23 +7464,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7056,51 +7496,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7109,23 +7565,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7262,21 +7718,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7306,11 +7762,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7508,74 +7964,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7629,12 +8093,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7654,55 +8118,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7754,77 +8218,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7872,25 +8344,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8115,176 +8587,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8292,23 +8772,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8339,13 +8819,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8381,8 +8858,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8406,7 +8883,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8439,810 +8916,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9343,42 +9932,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9528,19 +10125,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9548,278 +10145,282 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/es/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/es/LC_MESSAGES/django.po index e84d13b24b..51ded5172c 100644 --- a/src/backend/InvenTree/locale/es/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/es/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "endpoint API no encontrado" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "Se debe proporcionar una lista de elementos para la operación por lotes" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Los artículos deben ser proporcionados como una lista" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Lista de artículos no válida" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Todos los filtros tienen que ser usados con verdadero" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Ningún artículo coincide con el criterio proporcionado" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Sin datos proporcionados" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Este campo debe ser único." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "El usuario no tiene permiso para ver este modelo" @@ -65,150 +69,155 @@ msgstr "Confirmación de dirección de email" msgid "You must type the same email each time." msgstr "Debe escribir el mismo correo electrónico cada vez." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "La dirección de correo electrónico principal proporcionada no es válida." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "El dominio de correo electrónico proporcionado no está aprobado." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Unidad proporcionada no válida ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Ningún valor proporcionado" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "No se pudo convertir {original} a {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Cantidad proporcionada no válida" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Detalles del error pueden encontrarse en el panel de administración" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Ingrese la fecha" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Número decimal no válido" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Notas" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "El valor '{name}' no aparece en formato de patrón" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "El valor proporcionado no coincide con el patrón requerido: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "No se puede serializar más de 1000 elementos a la vez" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "No se ha proporcionado un número de serie" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Serie duplicada" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Grupo no válido {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Rango del grupo {group} supera la cantidad permitida ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Numeros de serie no encontrados" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "El número de números de serie únicos ({n}) tiene que coincidir con la cantidad ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Eliminar etiquetas HTML de este valor" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Los datos contienen contenido de marcado prohibido" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "URL no válida: falta el nombre de host" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "URL no válida: no se pudo resolver el nombre de host" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "La URL apunta a una dirección IP privada o reservada" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "Demasiadas redirecciones" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Error de conexión" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "El servidor respondió con código de estado no válido" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Se ha producido una excepción" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "El servidor respondió con un valor de longitud de contenido inválido" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "El tamaño de la imagen es demasiado grande" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "La descarga de imagen excedió el tamaño máximo" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "El servidor remoto devolvió una respuesta vacía" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "La URL proporcionada no es un archivo de imagen válido" @@ -216,159 +225,203 @@ msgstr "La URL proporcionada no es un archivo de imagen válido" msgid "Log in to the app" msgstr "Iniciar sesión en la aplicación" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Correo electrónico" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Debe habilitar la autenticación de doble factor antes de continuar." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Error al ejecutar la validación del plug-in" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Los metadatos deben ser un objeto diccionario de python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metadatos del complemento" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Campo de metadatos JSON, para uso por complementos externos" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Patrón con formato incorrecto" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Clave de formato especificado desconocida" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Falta la clave de formato necesaria" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "El campo de servidor no puede estar vacío" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "La referencia debe coincidir con la expresión regular {pattern}" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "El número de referencia es demasiado grande" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Selección no válida" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nombre" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Descripción" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Descripción (opcional)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Ruta" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Los nombres duplicados no pueden existir bajo el mismo padre" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Notas de Markdown (opcional)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Datos de código de barras" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Datos de código de barras de terceros" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash del Código de barras" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hash único de datos de código de barras" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Error de servidor" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Se ha registrado un error por el servidor." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Imágen" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Debe ser un número válido" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Moneda" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Seleccionar moneda de las opciones disponibles" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Copiar Parámetros" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Copiar líneas" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Copiar elementos de línea del pedido original" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Copiar líneas adicionales" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Copiar elementos extra de la línea del pedido original" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Árabe" @@ -521,46 +574,48 @@ msgstr "Chino (Simplificado)" msgid "Chinese (Traditional)" msgstr "Chino (Tradicional)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Actualización disponible" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Una actualización para InvenTree está disponible" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Unidad física inválida" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "No es un código de moneda válido" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Estado del pedido" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Construcción o Armado Superior" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Incluye Variantes" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Incluye Variantes" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Incluye Variantes" msgid "Part" msgstr "Parte" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Categoría" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Asignado a mí" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Asignadas a" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Creado antes" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Creado despues" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Tiene fecha inicial" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Fecha de inicio anterior" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Fecha de inicio después" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Tiene fecha límite" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Fecha objetivo antes" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Fecha objetivo después" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Completado antes" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Completado después" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Fecha Mínima" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Fecha Máxima" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Excluir Árbol" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "La compilación debe cancelarse antes de poder ser eliminada" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Consumible" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opcional" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Montaje" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Rastreado" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Comprobable" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Pedido pendiente" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Asignadas" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Agotado" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Disponible" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "En pedido" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Construir órden" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Ubicación" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Salida" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Construir órdenes" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "BOM de ensamblado no ha sido validado" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "La orden de construcción no puede ser creado para una parte inactiva" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "La orden de construcción no puede ser creada para una parte desbloqueada" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Se debe especificar un usuario o grupo responsable" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "La parte del pedido de construcción no puede ser modificada" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "La fecha límite debe ser posterior a la fecha de inicio" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Número de orden de construcción o armado" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referencia" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Breve descripción de la construcción (opcional)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Seleccionar parte a construir o armar" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referencia de orden de venta" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Ubicación de la fuente" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Seleccione la ubicación de donde tomar stock para esta construcción o armado (deje en blanco para tomar desde cualquier ubicación)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Ubicación de destino" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Seleccione la ubicación donde se almacenarán los artículos completados" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Cantidad a crear" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Número de objetos existentes a construir" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Elementos completados" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Número de productos en stock que se han completado" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Estado de la construcción" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Código de estado de construcción" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Numero de lote" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Número de lote de este producto final" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Fecha de Creación" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Crear fecha de inicio" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Fecha de inicio programada para este pedido" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Fecha límite de finalización" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Fecha límite para la finalización de la construcción. La construcción estará vencida después de esta fecha." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Fecha de finalización" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "terminado por" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "El usuario que emitió esta orden" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsable" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Usuario o grupo responsable de esta orden de construcción" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Link externo" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Enlace a URL externa" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Prioridad de construcción" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Prioridad de esta orden de construcción" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Código del proyecto" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Código de proyecto para esta orden de ensamble" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "No se pudo descargar la tarea para completar las asignaciones de construcción" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "El pedido {build} ha sido procesado" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Pedido #[order] ha sido procesado" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Los números de serie deben ser proporcionados para las partes rastreables" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "No se ha especificado salida de construcción" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "La construcción de la salida ya está completa" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "La salida de la construcción no coincide con el orden de construcción" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "La cantidad debe ser mayor que cero" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "La cantidad no puede ser mayor que la cantidad de salida" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "La construcción {serial} no ha pasado todas las pruebas requeridas" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Cantidad disponible ({q}) excedida" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Construir línea de pedido" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Ensamblar equipo" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Ensamblar equipo" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Cantidad" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Cantidad requerida para orden de ensamble" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Item de construcción o armado debe especificar un resultado o salida, ya que la parte maestra está marcada como rastreable" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "El artículo de almacén selelccionado no coincide con la línea BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "La cantidad debe ser 1 para el stock serializado" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Cantidad asignada ({q}) no debe exceder la cantidad disponible de stock ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Artículo de stock sobreasignado" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Artículo de stock" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Producto original de stock" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Cantidad de stock a asignar para construir" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Instalar en" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Artículo de stock de destino" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Nivel de construcción" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Nombre de parte" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "La salida de construcción no coincide con la construcción padre" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "La parte de salida no coincide con la parte de la Orden de Construcción" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Esta salida de construcción ya ha sido completada" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Esta salida de construcción no está completamente asignada" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Ingrese la cantidad para la producción de la construcción" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Cantidad entera requerida para partes rastreables" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Cantidad entera requerida, ya que la factura de materiales contiene partes rastreables" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Números de serie" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Introduzca los números de serie de salidas de construcción" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Ubicación de stock para objetos construidos" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Autoasignar Números de Serie" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Asignar automáticamente los artículos requeridos con números de serie coincidentes" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Los siguientes números seriales ya existen o son inválidos" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Debe proporcionarse una lista de salidas de construcción" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Ubicación de almacén para salidas descartadas" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Descartar asignaciones" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar cualquier asignación de existencias para las salidas descartadas" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Razón para descartar la salida de ensamble(s)" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Ubicación para las salidas de construcción completadas" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Aceptar Asignación Incompleta" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Completar salidas si el inventario no se ha asignado completamente" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Consumir Stock Asignado" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Consume cualquier stock que ya ha sido asignado a esta construcción" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Eliminar salidas incompletas" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Eliminar cualquier salida de construcción que no se haya completado" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "No permitido" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Aceptar como consumido por este pedido de construcción" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Liberar antes de completar esta orden de construcción" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Stock sobreasignado" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Cómo quieres manejar los artículos extra de inventario asignados a la orden de construcción" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Algunos artículos de inventario han sido sobreasignados" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Aceptar no asignado" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Aceptar que los artículos de stock no se han asignado completamente a este pedido de construcción" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "El stock requerido no ha sido completamente asignado" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Aceptar incompleto" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Aceptar que el número requerido de salidas de construcción no se han completado" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "La cantidad de construcción requerida aún no se ha completado" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "La orden de construcción tiene órdenes hijas de construcción abiertas" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Orden de construcción debe estar en estado de producción" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "El orden de construcción tiene salidas incompletas" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Linea de ensamble" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "La salida de la construcción debe apuntar a la misma construcción" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Crear partida" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part debe apuntar a la misma parte que la orden de construcción" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "El artículo debe estar en stock" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Cantidad disponible ({q}) excedida" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "La salida de la construcción debe especificarse para la asignación de partes rastreadas" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "La salida de construcción no se puede especificar para la asignación de partes no rastreadas" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Debe proporcionarse la adjudicación de artículos" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Ubicación de inventario donde las partes deben ser obtenidas (dejar en blanco para tomar de cualquier ubicación)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Excluir ubicación" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Excluir artículos de stock de esta ubicación seleccionada" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Stock intercambiable" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Los artículos de inventario en múltiples ubicaciones se pueden utilizar de forma intercambiable" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Sustituir stock" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Permitir la asignación de partes sustitutas" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Elementos opcionales" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Asignar artículos de la BOM opcionales para construir la orden" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Referencia BOM" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID de la parte BOM" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Nombre de parte la BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Parte del proveedor" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Cantidad Asignada" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Referencia de orden de Ensamblado" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Nombre de la categoría por pieza" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Rastreable" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Heredado" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Permitir variantes" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Item de Lista de Materiales" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "En producción" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Stock externo" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Stock Disponible" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Stock sustituto disponible" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Stock variable disponible" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Pendiente" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Producción" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "En espera" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Terminado" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "El pedido {build} ha sido procesado" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Pedido #[order] ha sido procesado" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Stock requerido para la orden de construcción" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Orden de construcción atrasada" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "El pedido de construcción {bo} está atrasado" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "¿Es enlace?" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "¿Es archivo?" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "El usuario no tiene permiso para eliminar estos adjuntos" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "El usuario no tiene permiso para eliminar este adjunto" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Lista de selección bloqueada" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Código de divisa inválido" @@ -1539,15 +1641,20 @@ msgstr "No se han proporcionado códigos de divisa válidos" msgid "No plugin" msgstr "Sin plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Etiqueta del código del proyecto" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Actualizado" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Fecha y hora de la última actualización" @@ -1567,794 +1674,844 @@ msgstr "Código único del proyecto" msgid "Project description" msgstr "Descripción del proyecto" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Usuario o grupo responsable de este projecto" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Tecla de ajustes" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Valor de ajuste" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "El valor elegido no es una opción válida" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "El valor debe ser un valor booleano" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "El valor debe ser un entero" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "El valor debe ser un número válido" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "El valor no pasa las comprobaciones de validación" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Cadena de clave debe ser única" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Usuario" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Cantidad de salto de precio" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Precio" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Precio unitario a la cantidad especificada" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Endpoint" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Punto final en el que se recibe este webhook" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Nombre para este webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Activo" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Usuario o grupo responsable de este projecto" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Tecla de ajustes" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Valor de ajuste" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "El valor elegido no es una opción válida" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "El valor debe ser un valor booleano" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "El valor debe ser un entero" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "El valor debe ser un número válido" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "El valor no pasa las comprobaciones de validación" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Cadena de clave debe ser única" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Usuario" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Cantidad de salto de precio" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Precio" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Precio unitario a la cantidad especificada" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Endpoint" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Punto final en el que se recibe este webhook" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Nombre para este webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Está activo este webhook" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token para el acceso" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Clave" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Secreto compartido para HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID de mensaje" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Identificador único para este mensaje" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Servidor" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Servidor desde el cual se recibió este mensaje" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Encabezado" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Encabezado del mensaje" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Cuerpo" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Cuerpo de este mensaje" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Endpoint en el que se recibió este mensaje" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Trabajado en" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "¿El trabajo en este mensaje ha terminado?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Título" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Enlace" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publicado" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Resumen" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Leer" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "¿Esta noticia ya fue leída?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Archivo de imagen" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Unidad personalizada" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "El símbolo de la unidad debe ser único" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Nombre de unidad debe ser un identificador válido" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Nombre de unidad" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Símbolo de unidad opcional" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definición" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definición de unidad" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Archivo adjunto" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Archivo no encontrado" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Falta enlace externo" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Seleccionar archivo para adjuntar" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Comentario" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Comentario de archivo adjunto" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Fecha de carga" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Fecha de carga del archivo" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Tamaño del archivo" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Tamaño del archivo en bytes" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Tipo de modelo no válido especificado para el archivo adjunto" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Estado personalizado" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Estados personalizados" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Llave lógica" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Valor" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Nombre del estado" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etiqueta" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Etiqueta que se mostrará en el frontend" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Color" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Color que se mostrará en el frontend" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Modelo" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "El modelo debe ser seleccionado" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "La clave debe ser seleccionada" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "La clave lógica debe ser seleccionada" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Lista de selección" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Listas de Selección" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Nombre de la lista de selección" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Descripción de la lista de selección" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Bloqueado" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "¿Está bloqueada esta lista de selección?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "¿Se puede utilizar esta lista de selección?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Complemento de origen" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Complemento que proporciona la lista de selección" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Cadena de origen" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Cadena opcional que identifica la fuente usada para esta lista" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Entrada por defecto" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Entrada predeterminada para esta lista de selección" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Creado" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Fecha y hora en la que se creó la lista de selección" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Última actualización" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Fecha y hora en que la lista de selección fue actualizada por última vez" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Entrada de lista de selección" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Entradas de la lista de selección" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Lista de selección a la que pertenece esta entrada" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Valor del elemento de la lista de selección" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Etiqueta para la entrada de lista de selección" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Descripción de la entrada de lista de selección" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "¿Está activa esta entrada de la lista de selección?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Plantilla de parámetro" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "El nombre de parámetro en la plantilla tiene que ser único" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Nombre de Parámetro" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Unidades" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Casilla de verificación" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "¿Es este parámetro una casilla de verificación?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Opciones" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Opciones válidas para este parámetro (separados por comas)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Lista de selección para este parámetro" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Opción inválida para el valor del parámetro" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Plantilla" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Datos" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Valor del parámetro" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Nota" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Campo de nota opcional" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Escanear código de barras" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Datos de código de barras" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Usuario que escaneó el código de barras" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Fecha y hora del escaneo de código de barras" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Dispositivo URL que procesó el código de barras" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Datos de contexto para el escaneo de código de barras" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Respuesta" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Respuesta de datos del escaneo de código de barras" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Resultado" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "¿El escaneo de código de barras fue exitoso?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Clave" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} cancelado" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Artículos Recibidos" @@ -2388,104 +2545,100 @@ msgstr "Los artículos han sido recibidos contra una orden de compra" msgid "Items have been received against a return order" msgstr "Los artículos han sido recibidos contra una orden de devolución" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Está en ejecución" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Tareas pendientes" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Tareas Programadas" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Tareas fallidas" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Identificación de Tarea" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Identificación de tarea única" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Bloquear hora" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Nombre de la tarea" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Función" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nombre de la Función" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argumentos de la tarea" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Argumentos de palabra clave" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Argumentos de palabra clave de tarea" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nombre de Archivo" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "El usuario no tiene permiso para crear o editar archivos adjuntos para este modelo" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Lista de selección bloqueada" - #: common/setting/system.py:97 msgid "No group" msgstr "Sin grupo" @@ -2614,13 +2767,13 @@ msgstr "Intervalo de actualización de moneda" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Con qué frecuencia actualizar los tipos de cambio (establecer a cero para desactivar)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "días" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Plugin de actualización de moneda a usar" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validación estricta de URL" @@ -2760,947 +2921,1017 @@ msgstr "Complemento para generar códigos de barra" msgid "Plugin to use for internal barcode data generation" msgstr "Complemento a usar para la generación de datos de códigos de barra internos" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "Revisiones de partes" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "Habilitar campo de revisión para parte" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 +msgid "Part Revisions" +msgstr "Revisiones de partes" + +#: common/setting/system.py:413 +msgid "Enable revision field for Part" +msgstr "Habilitar campo de revisión para parte" + +#: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Patrón de expresión regular para IPN de la parte coincidente" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Permitir IPN duplicado" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que varias partes compartan el mismo IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Permitir editar IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Permite cambiar el valor de IPN mientras se edita una parte" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Copiar parte de datos BOM" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Copiar datos BOM por defecto al duplicar una parte" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Copiar parámetros de parte" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Copiar datos de parámetro por defecto al duplicar una parte" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Copiar parte de datos de prueba" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Copiar datos de parámetro por defecto al duplicar una parte" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Copiar plantillas de parámetros de categoría" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Copiar plantillas de parámetros de categoría al crear una parte" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Las partes son plantillas por defecto" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Las partes pueden ser ensambladas desde otros componentes por defecto" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Componente" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Las partes pueden ser usadas como subcomponentes por defecto" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Comprable" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Las partes son comprables por defecto" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Vendible" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Las partes se pueden vender por defecto" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Las partes son rastreables por defecto" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Las partes son virtuales por defecto" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Mostrar partes relacionadas" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Mostrar partes relacionadas para una parte" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Datos iniciales de existencias" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Permitir la creación del stock inicial al añadir una nueva parte" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Datos iniciales del proveedor" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Permitir la creación de datos iniciales del proveedor al agregar una nueva parte" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Formato de visualización de Nombre de Parte" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formato para mostrar el nombre de la parte" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Icono por defecto de la categoría de parte" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Icono por defecto de la categoría de parte (vacío significa que no hay icono)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Mínimo de lugares decimales en el precio" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Número mínimo de decimales a mostrar al procesar los datos de precios" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Máximo de lugares decimales en el precio" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Número máximo de decimales a mostrar al procesar los datos de precios" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Usar precios de proveedor" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Incluir descuentos de precios del proveedor en los cálculos generales de precios" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Anulación del historial de compra" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "El precio histórico de compra anula los descuentos de precios del proveedor" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Usar precio del artículo de almacén" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Usar los precios de los datos de inventario introducidos manualmente para los cálculos de precios" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Edad del precio del artículo de almacén" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Excluir artículos de almacén anteriores a este número de días de los cálculos de precios" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Usar precios variantes" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir variantes de precios en los cálculos generales de precios" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Solo variantes activas" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Usar solo partes de variantes activas para calcular los precios de variantes" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Intervalo de reconstrucción de precios" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Número de días antes de que el precio de la parte se actualice automáticamente" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Precios internos" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Habilitar precios internos para partes" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Anulación del precio interno" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Si está disponible, los precios internos anulan los cálculos del rango de precios" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Habilitar impresión de etiquetas" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Habilitar impresión de etiquetas desde la interfaz web" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "PPP de la imagen de etiqueta" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Resolución DPI al generar archivos de imagen que suministrar para etiquetar complementos de impresión" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Habilitar informes" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Habilitar generación de informes" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Modo de depuración" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Generar informes en modo de depuración (salida HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Registrar errores de reportes" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Registrar errores ocurridos al generar reportes" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Tamaño de página" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Tamaño de página predeterminado para informes PDF" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Forzar unidades de parámetro" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Si se proporcionan unidades, los valores de parámetro deben coincidir con las unidades especificadas" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Seriales únicos globalmente" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Los números de serie para los artículos de inventario deben ser únicos globalmente" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Eliminar existencias agotadas" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Determina el comportamiento por defecto al agotarse un artículo del inventario" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Plantilla de código de lote" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Plantilla para generar códigos de lote por defecto para artículos de almacén" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Expiración de stock" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Habilitar la funcionalidad de expiración de stock" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Vender existencias caducadas" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Permitir venta de existencias caducadas" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Tiempo histórico de Stock" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Número de días de artículos de stock se consideran obsoletos antes de caducar" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Crear Stock Caducado" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Permitir crear con stock caducado" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Control de Stock" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Habilitar control de propiedad sobre ubicaciones de stock y artículos" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Icono por defecto de ubicación de almacén" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Icono por defecto de ubicación de almacén (vacío significa que no hay icono)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Mostrar Articulos de Stock Instalados" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Mostrar los artículos de stock instalados en las tablas de stock" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Permitir transferencia Sin Existencias" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Permitir que artículos del inventario sin existencias puedan ser transferidos entre ubicaciones de inventario" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Armado" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Patrón requerido para generar el campo de referencia de la Orden de Ensamblado" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Requerir Dueño Responsable" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Se debe asignar un dueño responsable a cada orden" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Requerir Parte Activa" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Impedir la creación de órdenes de fabricación para partes inactivas" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Requerir Parte Bloqueada" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Impedir la creación de órdenes de fabricación para partes bloqueadas" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Impedir la creación de órdenes de fabricación a menos que se haya validado la lista de materiales" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Prevenir la finalización de la orden de construcción hasta que todas las órdenes hijas estén cerradas" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Bloquear hasta que los Tests pasen" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Evitar que las construcciones sean completadas hasta que todas las pruebas requeridas pasen" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Habilitar órdenes de devolución" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Habilitar la funcionalidad de orden de devolución en la interfaz de usuario" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Patrón de referencia de orden de devolución" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Patrón requerido para generar el campo de referencia de devolución de la orden" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Editar ordenes de devolución completadas" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Permitir la edición de ordenes de devolución después de que hayan sido completados" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Venta" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Patrón requerido para generar el campo de referencia de la orden de venta" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Envío Predeterminado de Ordenes de Venta" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Habilitar la creación de envío predeterminado con ordenes de entrega" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Editar Ordenes de Venta Completados" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Permitir la edición de ordenes de venta después de que hayan sido enviados o completados" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Marcar pedidos enviados como completados" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Los pedidos marcados como enviados se completarán automáticamente, evitando el estado de \"envío\"" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Patrón de Referencia de Orden de Compra" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Patrón requerido para generar el campo de referencia de la Orden de Compra" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Editar Ordenes de Compra Completados" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Permitir la edición de órdenes de venta después de que hayan sido enviados o completados" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Convertir moneda" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Autocompletar Ordenes de compra" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Marcar automáticamente las órdenes de compra como completas cuando se reciben todos los artículos de línea" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Habilitar función de contraseña olvidada" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Activar la función olvido de contraseña en las páginas de inicio de sesión" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Habilitar registro" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "Activar auto-registro para usuarios en las páginas de inicio de sesión" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Habilitar SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "Habilitar SSO en las páginas de inicio de sesión" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "Habilitar registro SSO" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Activar autoregistro a través de SSO para usuarios en las páginas de inicio de sesión" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "Habilitar sincronización de grupo SSO" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "Habilitar la sincronización de grupos de Inventree con grupos proporcionados por el IdP" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "Clave de grupo SSO" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "El nombre del atributo reclamado por el grupo proporcionado por el IdP" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "Mapa del grupo SSO" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "Un mapeo de grupos SSO a grupos de Inventree locales. Si el grupo local no existe, se creará." - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "Eliminar grupos fuera de SSO" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Habilitar función de contraseña olvidada" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Activar la función olvido de contraseña en las páginas de inicio de sesión" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Habilitar registro" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "Activar auto-registro para usuarios en las páginas de inicio de sesión" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "Habilitar SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "Habilitar SSO en las páginas de inicio de sesión" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "Habilitar registro SSO" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "Activar autoregistro a través de SSO para usuarios en las páginas de inicio de sesión" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "Habilitar sincronización de grupo SSO" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "Habilitar la sincronización de grupos de Inventree con grupos proporcionados por el IdP" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "Clave de grupo SSO" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "El nombre del atributo reclamado por el grupo proporcionado por el IdP" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "Mapa del grupo SSO" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "Un mapeo de grupos SSO a grupos de Inventree locales. Si el grupo local no existe, se creará." + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "Eliminar grupos fuera de SSO" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email requerido" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Requiere usuario para suministrar correo al registrarse" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Auto-rellenar usuarios SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Rellenar automáticamente los datos de usuario de la cuenta SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Correo dos veces" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Al registrarse pregunte dos veces a los usuarios por su correo" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Contraseña dos veces" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Al registrarse, preguntar dos veces a los usuarios por su contraseña" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Dominios permitidos" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Restringir el registro a ciertos dominios (separados por comas, comenzando por @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grupo al registrarse" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Grupo al que se asignan nuevos usuarios al registrarse. Si la sincronización de grupo SSO está activada, este grupo sólo se establece si no se puede asignar ningún grupo desde el IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Forzar MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Los usuarios deben utilizar seguridad multifactor." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Comprobar complementos al iniciar" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Comprobar que todos los complementos están instalados en el arranque - habilitar en entornos de contenedores" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Revisar actualizaciones del plugin" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Habilitar comprobaciones periódicas para actualizaciones de plugins instalados" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Habilitar integración de URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Habilitar plugins para añadir rutas de URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Habilitar integración de navegación" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Habilitar plugins para integrar en la navegación" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Habilitar integración de la aplicación" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Habilitar plugins para añadir aplicaciones" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Habilitar integración de programación" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Habilitar plugins para ejecutar tareas programadas" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Habilitar integración de eventos" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Habilitar plugins para responder a eventos internos" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Habilitar integración de interfaz" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Habilitar complementos para integrar en la interfaz de usuario" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Habilitar códigos de proyecto para rastrear proyectos" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Excluir Ubicaciones Externas" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Periodo de inventario automático" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Mostrar nombres completos de los usuarios" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Mostrar nombres completos de usuarios en lugar de nombres de usuario" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Habilitar datos de estación de prueba" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Habilitar la recolección de datos de estaciones de prueba para resultados de prueba" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Número de resultados a mostrar en cada sección de la ventana de vista previa" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Búsqueda usando una expresión regular" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Habilitar expresiones regulares en las consultas de búsqueda" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Búsqueda por palabra completa" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Las consultas de búsqueda devuelven resultados para palabras enteras coincidentes" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Formularios de cierre de teclas de escape" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Usa la clave de escape para cerrar formularios modales" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Barra de navegación fija" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "La posición de la barra de navegación se fija en la parte superior de la pantalla" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Formato de Fecha" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Formato preferido para mostrar fechas" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Recibir reportes de error" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Recibir notificación de errores del sistema" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Últimas impresoras usadas" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Un dominio vacío no está permitido." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Nombre de dominio inválido: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "La parte está activa" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "El fabricante está activo" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Empresa" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Tiene Stock" @@ -4123,8 +4387,8 @@ msgstr "Teléfono de contacto" msgid "Contact email address" msgstr "Correo electrónico de contacto" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Contacto" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Dirección" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Direcciones" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Seleccionar empresa" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Título de dirección" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Título que describe la entrada de dirección" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Dirección principal" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Establecer como dirección principal" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Línea 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Dirección línea 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Línea 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Dirección línea 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Código postal" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Ciudad/región" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Código postal de ciudad/región" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Estado/provincia" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Estado o provincia" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "País" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Dirección de país" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Notas de envío de mensajería" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Notas para el mensajero de envío" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Notas de envío internas" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Notas de envío para uso interno" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Enlace a información de dirección (externa)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Parte del fabricante" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Parte base" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Seleccionar parte" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Seleccionar fabricante" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Número de parte de fabricante" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL para el enlace de parte del fabricante externo" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Descripción de la parte del fabricante" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Las unidades de paquete deben ser compatibles con las unidades de partes de base" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Las unidades de paquete deben ser mayor que cero" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "La parte vinculada del fabricante debe hacer referencia a la misma parte base" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Proveedor" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Seleccionar proveedor" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Unidad de mantenimiento de stock de proveedores" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Seleccionar parte del fabricante" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL del enlace de parte del proveedor externo" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Descripción de la parte del proveedor" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "costo base" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Cargo mínimo (p. ej., cuota de almacenamiento)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Paquetes" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Embalaje de partes" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Cantidad de paquete" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Cantidad total suministrada en un solo paquete. Dejar vacío para artículos individuales." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "múltiple" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Pedido múltiple" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Cantidad disponible del proveedor" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Disponibilidad actualizada" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Fecha de última actualización de los datos de disponibilidad" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Moneda predeterminada utilizada para este proveedor" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Nombre de la empresa" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "En Stock" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Información adicional de estado para este artículo" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Clave personalizada de estado" @@ -4476,123 +4740,152 @@ msgstr "Colocado" msgid "Invalid status code" msgstr "Código de estado no válido" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Archivo de datos" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Archivo de datos a importar" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Columnas" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Valores predeterminados del campo" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Filtros del campo" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Algunos campos requeridos no han sido mapeados" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "La columna ya fue mapeada a un campo de la base de datos" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "La columna no existe en el archivo de datos" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "El campo no existe en el modelo destino" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "El campo seleccionado es de solo lectura" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Sesión de importación" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Campo" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Columna" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Número de fila" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Datos de la fila original" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Errores" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Válido" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Formato de archivo de datos no soportado" @@ -4600,43 +4893,47 @@ msgstr "Formato de archivo de datos no soportado" msgid "Failed to open data file" msgstr "Error al abrir el archivo de datos" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Dimensiones del archivo de datos inválidas" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Valores predeterminados del campo inválidos" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Filtros del campo inválidos" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Filas" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Listado de IDs de fila a aceptar" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "No hay filas" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "La fila no pertenece a esta sesión" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "La fila contiene datos inválidos" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "La fila ya se ha completado" @@ -4672,115 +4969,115 @@ msgstr "El archivo de datos tiene demasiadas columnas" msgid "Data file contains too many rows" msgstr "El archivo de datos tiene demasiadas filas" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Copias" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Número de copias a imprimir para cada etiqueta" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Conectado" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Desconocido" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Impresión" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Sin archivos multimedia" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Atascamiento de papel" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Desconectado" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Impresora de Etiquetas" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Imprime directamente etiquetas para varios artículos." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Ubicación de la Impresora" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Nombre de la máquina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Tipo de Máquina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Tipo de máquina" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Controlador" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Controlador usado para la máquina" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Las máquinas pueden ser desactivadas" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Controlador disponible" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Sin errores" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Inicializado" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Estado de máquina" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Máquina" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Tipo de configuración" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupo" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Referencia del pedido" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Destacado" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Tiene Código de Proyecto" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Creado por" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Creado antes de" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Creado después de" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Tiene fecha inicial" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Fecha de inicio anterior" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Fecha de inicio después" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Tiene fecha límite" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Fecha objetivo antes" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Fecha objetivo después" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Tiene Precio" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Completado antes de" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Completado después de" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Orden" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Orden completada" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Componente interno" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Orden pendiente" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Completados" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Tiene envío" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Orden de compra" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Orden de compra" msgid "Sales Order" msgstr "Orden de Venta" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Orden de devolución" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Precio Total" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Precio total para este pedido" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Moneda de pedido" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Moneda para este pedido (dejar en blanco para utilizar el valor predeterminado de la empresa)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Este pedido está bloqueado y no puede ser modificado" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "El contacto no coincide con la empresa seleccionada" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "La fecha de inicio debe ser anterior a la fecha de límite" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Descripción del pedido (opcional)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Seleccione el código del proyecto para este pedido" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Enlace a Url externa" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Fecha de inicio" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Fecha de inicio programada para este pedido" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Fecha objetivo" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Fecha esperada para la entrega del pedido. El pedido se retrasará después de esta fecha." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Fecha de emisión" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Fecha de expedición del pedido" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Usuario o grupo responsable de este pedido" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Punto de contacto para este pedido" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Dirección de la empresa para este pedido" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Referencia del pedido" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Estado" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Estado de la orden de compra" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Empresa de la cual se están encargando los artículos" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Referencia del proveedor" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Código de referencia de pedido del proveedor" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "recibido por" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "La fecha de pedido fue completada" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Destinación" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Destino para los artículos recibidos" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "El proveedor de la parte debe coincidir con el proveedor de PO" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "La partida no coincide con la orden de compra" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "La cantidad debe ser un número positivo" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Empresa a la que se venden los artículos" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Estado de la orden de venta" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Referencia del cliente " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Código de referencia de pedido del cliente" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Fecha de envío" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "enviado por" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "La partida no está asociada con este pedido" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "No se han encontrado coincidencias para los siguientes números de serie" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Los siguientes números de serie no están disponibles" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "La orden ya fue completada" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "La orden ya fue cancelada" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Sólo una orden abierta puede ser marcada como completa" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "El pedido no se puede completar porque hay envíos incompletos" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "El pedido no se puede completar ya que hay asignaciones incompletas" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "El pedido no se puede completar porque hay partidas incompletas" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "Este pedido está bloqueado y no puede ser modificado" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Cantidad del artículo" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Referencia de partida" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Notas de partida" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Fecha objetivo para esta partida (dejar en blanco para usar la fecha de destino de la orden)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Descripción de partida (opcional)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Contexto adicional para esta línea" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Precio unitario" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "La parte del proveedor debe coincidir con el proveedor" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Parte del proveedor" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Recibido" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Número de artículos recibidos" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Precio de Compra" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Precio de compra unitario" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Sólo las partes vendibles pueden ser asignadas a un pedido de venta" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Precio de Venta" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Precio de venta unitario" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Cantidad enviada" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Fecha del envío" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Fecha de entrega" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Fecha de entrega del envío" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Revisado por" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Usuario que revisó este envío" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envío" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Número de envío" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Número de Seguimiento" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Información de seguimiento del envío" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Número de factura" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Número de referencia para la factura asociada" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "El envío ya ha sido enviado" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "El envío no tiene artículos de stock asignados" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "El artículo de stock no ha sido asignado" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "No se puede asignar el artículo de stock a una línea con una parte diferente" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "No se puede asignar stock a una línea sin una parte" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La cantidad de asignación no puede exceder la cantidad de stock" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Cantidad asignada debe ser mayor que cero" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "La cantidad debe ser 1 para el stock serializado" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "La orden de venta no coincide con el envío" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "El envío no coincide con el pedido de venta" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Línea" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Referencia del envío del pedido de venta" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Ítem" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Seleccionar artículo de stock para asignar" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Especificar la cantidad de asignación de stock" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Referencia de la orden de devolución" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Empresa de la cual se están devolviendo los artículos" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Estado de la orden de devolución" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Seleccionar el artículo a devolver del cliente" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Fecha de recepción" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Resultado" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Salida para esta partida" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Costo asociado con la devolución o reparación para esta partida" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID del Pedido" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID del pedido a duplicar" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Copiar líneas" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Copiar elementos de línea del pedido original" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Copiar líneas adicionales" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Copiar elementos extra de la línea del pedido original" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Copiar Parámetros" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Partidas" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Líneas completadas" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Duplicar pedido" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Especificar opciones para duplicar este pedido" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "ID de pedido no válido" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Nombre del proveedor" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "El pedido no puede ser cancelado" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Permitir cerrar el pedido con partidas incompletas" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "El pedido tiene partidas incompletas" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "El pedido no está abierto" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Precio automático" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Calcular precio de compra automáticamente con base en los datos del proveedor" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Moneda del precio de compra" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Combinar artículos" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Número de parte interna" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Nombre interno de parte" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Debe especificar la parte del proveedor" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "La orden de compra debe especificarse" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "El proveedor debe coincidir con la orden de compra" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "La orden de compra debe coincidir con el proveedor" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Partida" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Seleccione la ubicación de destino para los artículos recibidos" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Introduzca el código de lote para los artículos de almacén entrantes" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Fecha de Expiración" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Introduzca números de serie para artículos de almacén entrantes" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Código de barras escaneado" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Código de barras en uso" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Se deben proporcionar las partidas" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Se requiere ubicación de destino" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Los valores del código de barras deben ser únicos" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Envíos" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Envíos completados" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Moneda del precio de venta" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Elementos asignados" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "No se proporcionaron detalles de envío" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "La partida no está asociada con este pedido" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "La cantidad debe ser positiva" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Introduzca números de serie para asignar" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "El envío ya ha sido enviado" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "El envío no está asociado con este pedido" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "No se han encontrado coincidencias para los siguientes números de serie" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Los siguientes números de serie no están disponibles" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Partida de orden de devolución" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "La partida no coincide con la orden de devolución" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "La partida ya ha sido recibida" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Los artículos sólo pueden ser recibidos contra pedidos en curso" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Cantidad a devolver" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Moneda de precio de línea" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Perdida" @@ -5718,1279 +6125,1312 @@ msgstr "Perdida" msgid "Returned" msgstr "Devuelto" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "En progreso" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Devolución" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Reparación" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Reemplazo" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Reembolso" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Rechazo" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Emitido" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Orden de compra atrasada" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "La orden de compra {po} está atrasada" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Orden de venta atrasada" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "La orden de venta {so} está atrasada" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Favoritos" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Profundidad" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filtrar por profundidad de categoría" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Nivel superior" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filtrar por categorías de nivel superior" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "En cascada" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Tiene resultados" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Categoría de parte" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Categorías de parte" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Ubicación Predeterminada" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Ubicación predeterminada para partes de esta categoría" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Estructural" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Las partes no pueden asignarse directamente a una categoría estructural, pero pueden asignarse a categorías hijas." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Palabras clave predeterminadas" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Palabras clave por defecto para partes en esta categoría" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Icono" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Icono (opcional)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "¡No puedes hacer que esta categoría de partes sea estructural porque algunas partes ya están asignadas!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Valor predeterminado" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Valor de parámetro por defecto" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Partes" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Ya existe un artículo de almacén con este número de serie" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN duplicado no permitido en la configuración de partes" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "La revisión de parte duplicada ya existe." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Parte con este nombre, IPN y revisión ya existe." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "¡No se pueden asignar partes a las categorías de partes estructurales!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Nombre de la parte" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Es plantilla" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "¿Es esta parte una parte de la plantilla?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Descripción de parte (opcional)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Palabras claves" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Palabras clave para mejorar la visibilidad en los resultados de búsqueda" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Categoría de parte" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Revisión de parte o número de versión" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revisión" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Variante de" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "¿Dónde se almacena este artículo normalmente?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Expiración por defecto" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Tiempo de expiración (en días) para los artículos de stock de esta parte" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Stock mínimo" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Nivel mínimo de stock permitido" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Unidades de medida para esta parte" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "¿Se puede construir esta parte a partir de otras partes?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "¿Se puede utilizar esta parte para construir otras partes?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "¿Esta parte tiene seguimiento de objetos únicos?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "¿Se puede comprar esta parte a proveedores externos?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "¿Se puede vender esta parte a los clientes?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "¿Está activa esta parte?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Las partes bloqueadas no pueden ser editadas" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "¿Es ésta una parte virtual, como un producto de software o una licencia?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Suma de verificación de BOM" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Suma de verificación de BOM almacenada" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOM comprobado por" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Fecha BOM comprobada" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Creación de Usuario" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Dueño responsable de esta parte" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Vender múltiples" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Moneda utilizada para almacenar en caché los cálculos de precios" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Costo mínimo de BOM" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Costo mínimo de partes de componentes" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Costo máximo de BOM" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Costo máximo de partes de componentes" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Costo mínimo de compra" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Costo histórico mínimo de compra" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Costo máximo de compra" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Costo histórico máximo de compra" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Precio interno mínimo" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Costo mínimo basado en precios reducidos internos" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Precio interno máximo" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Costo máximo basado en precios reducidos internos" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Precio mínimo de proveedor" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Precio mínimo de la parte de proveedores externos" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Precio máximo de proveedor" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Precio máximo de la parte de proveedores externos" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Costo mínimo de variante" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Costo mínimo calculado de las partes variantes" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Costo máximo de variante" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Costo máximo calculado de las partes variantes" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Costo mínimo" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Anular el costo mínimo" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Costo máximo" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Reemplazar coste máximo" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Costo mínimo general calculado" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Precio de venta mínimo" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Precio de venta mínimo basado en precios reducidos" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Precio de venta máximo" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Precio de venta máximo basado en precios reducidos" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Costo de venta mínimo" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Precio de venta mínimo histórico" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Costo de Venta Máximo" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Precio de venta máximo histórico" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Número de artículos" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Fecha" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Costo de Stock Mínimo" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Costo mínimo estimado del stock disponible" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Las plantillas de prueba solo pueden ser creadas para partes de prueba" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Nombre de prueba" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Introduzca un nombre para la prueba" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Descripción de prueba" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Introduce la descripción para esta prueba" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Requerido" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "¿Es necesario pasar esta prueba?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Requiere valor" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "¿Esta prueba requiere un valor al agregar un resultado de la prueba?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Adjunto obligatorio" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "¿Esta prueba requiere un archivo adjunto al agregar un resultado de la prueba?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Seleccionar parte principal" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Sub parte" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Seleccionar parte a utilizar en BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Cantidad del artículo en BOM" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Este artículo BOM es opcional" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Este artículo de BOM es consumible (no está rastreado en órdenes de construcción)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Referencia de artículo de BOM" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Notas del artículo de BOM" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Suma de verificación" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Suma de verificación de línea de BOM" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Validado" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Este artículo de BOM ha sido validado" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Este artículo BOM es heredado por BOMs para partes variantes" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Artículos de stock para partes variantes pueden ser usados para este artículo BOM" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "La cantidad debe ser un valor entero para las partes rastreables" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Debe especificar la subparte" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Ítem de BOM sustituto" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "La parte sustituta no puede ser la misma que la parte principal" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Artículo BOM superior" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Sustituir parte" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Parte 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Parte 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Seleccionar parte relacionada" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Nota para esta relación" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Categoría principal de parte" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Subcategorías" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Moneda de compra de ítem de stock" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Parte original" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Seleccione la parte original a duplicar" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Copiar Imagen" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Copiar imagen desde la parte original" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Copiar BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Copiar la factura de materiales de la parte original" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Copiar datos del parámetro de la parte original" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Copiar Notas" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Cantidad Inicial de Stock" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Seleccione proveedor (o déjelo en blanco para saltar)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Seleccionar fabricante (o dejar en blanco para saltar)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Número de parte del fabricante" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "La empresa seleccionada no es un proveedor válido" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "La empresa seleccionada no es un fabricante válido" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Nombre de categoría" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "En construcción" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Elementos de stock" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Inventario Total" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Duplicar Parte" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Copiar Imagen" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Copiar imagen desde la parte original" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Copiar BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Copiar la factura de materiales de la parte original" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Copiar Notas" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Stock Inicial" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Crear Parte con cantidad inicial de stock" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Información del proveedor" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Añadir información inicial del proveedor para esta parte" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Copiar Parámetros de Categoría" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Copiar plantillas de parámetro de la categoría de partes seleccionada" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Imagen Existente" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "El archivo de imagen no existe" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Validación de Lista de Materiales" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Puede construir" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Precio mínimo" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Anular el valor calculado para precio mínimo" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Precio mínimo de moneda" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Precio máximo" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Precio máximo de moneda" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Actualizar" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "El precio mínimo no debe ser mayor que el precio máximo" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "El precio máximo no debe ser inferior al precio mínimo" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Seleccionar parte de la que copiar BOM" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Eliminar Datos Existentes" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Eliminar artículos BOM existentes antes de copiar" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Incluye Heredado" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Incluye artículos BOM que son heredados de partes con plantillas" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Omitir filas no válidas" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Activar esta opción para omitir filas inválidas" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Copiar partes sustitutas" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Notificación por bajo stock" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "El stock disponible para {part.name} ha caído por debajo del nivel mínimo configurado" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Instalado" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "No se especificó ninguna acción" msgid "No matching action found" msgstr "No se encontró ninguna acción coincidente" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "No se encontró ninguna coincidencia para los datos del código de barras" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Coincidencia encontrada para datos de códigos de barras" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "El código de barras coincide con artículo existente" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "No se ha encontrado ningún complemento para datos de código de barras" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Ningún pedido de venta proporcionado" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Proporciona soporte nativo para códigos de barras" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL que se utiliza para enviar mensajes a un canal de slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Abrir enlace" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Proporciona soporte nativo para imprimir etiquetas PDF" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Modo de depuración" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Activar modo de depuración - devuelve código HTML en lugar de PDF" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "El complemento no está instalado" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Instalación del complemento no encontrada" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Complemento" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "No se encontró autor" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "El complemento '{p}' no es compatible con la versión actual de InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "El complemento requiere al menos la versión {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "El complemento requiere como máximo la versión {v}" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Dimensiones de etiqueta inválidas" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Carta" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Nombre de la plantilla" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Adjuntar al modelo al imprimir" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Guardar la salida del informe como un archivo adjunto contra la instancia del modelo enlazado al imprimir" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Patrón de Nombre de archivo" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtros" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Tamaño de página para reportes PDF" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Ancho [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Ancho de la etiqueta, especificado en mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Altura de la etiqueta, especificada en mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Fragmento" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Archivo fragmento de informe" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Descripción de archivo de fragmento" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Activo" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Reportar archivo de activos" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Descripción del archivo de activos" @@ -8291,23 +8771,23 @@ msgstr "Descripción del archivo de activos" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Selecciona la plantilla de etiqueta" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Complemento de impresión" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Selecciona el complemento a usar para imprimir etiquetas" @@ -8338,13 +8818,10 @@ msgstr "Materiales necesarios" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Imagen de parte" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Emitido" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Requerido para" @@ -8380,8 +8857,8 @@ msgstr "Total" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Número de serie" @@ -8405,7 +8882,7 @@ msgstr "Artículo Stock Informe de prueba" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Elementos instalados" @@ -8438,810 +8915,922 @@ msgstr "Ningún resultado (requerido)" msgid "No result" msgstr "Sin resultados" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Ubicación principal" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filtrar por ubicación principal" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Nombre de pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "El nombre de la pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Nombre de la pieza (expresión regular)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "Pieza IPN (insensible a mayúsculas y minúsculas)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "Pieza IPN (insensible a mayúsculas y minúsculas)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "Pieza IPN (expresión regular)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Stock mínimo" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Stock máximo" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Código de estado" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Ubicación externa" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Instalado en otro artículo de existencias" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Árbol de piezas" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Actualizado antes" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Actualizado después" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Inventario antes" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Inventario después" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Desactualizado" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Cantidad requerida" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Debe suministrarse una parte válida" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Ubicación de Stock" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Ubicaciones de Stock" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Propietario" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Seleccionar Propietario" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Externo" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Se debe especificar la pieza" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "La cantidad debe ser 1 para el artículo con un número de serie" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Número de serie no se puede establecer si la cantidad es mayor que 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "El objeto no puede pertenecer a sí mismo" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "El artículo debe tener una referencia de construcción si is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "La referencia de la construcción no apunta al mismo objeto de parte" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Artículo de stock padre" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Parte base" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Seleccione una parte del proveedor correspondiente para este artículo de stock" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "¿Dónde se encuentra este artículo de stock?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Empaquetar este artículo de stock se almacena en" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Instalado en" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "¿Está este artículo instalado en otro artículo?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Número de serie para este artículo" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Código de lote para este artículo de stock" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Cantidad de Stock" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Build de origen" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Build para este item de stock" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Consumido por" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Orden de compra de origen" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Orden de compra para este artículo de stock" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Orden de venta de destino" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Fecha de caducidad del artículo de stock. El stock se considerará caducado después de esta fecha" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Eliminar al agotar" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Eliminar este artículo de stock cuando se agoten las existencias" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Precio de compra único en el momento de la compra" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Convertido a parte" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "La parte no está establecida como rastreable" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Cantidad debe ser un entero" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Los números de serie deben ser proporcionados como una lista" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "La cantidad no coincide con los números de serie" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Artículo de stock ha sido asignado a un pedido de venta" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Artículo de stock está instalado en otro artículo" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Artículo de stock contiene otros artículos" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Artículo de stock ha sido asignado a un cliente" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "El artículo de stock está en producción" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Stock serializado no puede ser combinado" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Artículos de Stock Duplicados" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Los artículos de stock deben referirse a la misma parte" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Los artículos de stock deben referirse a la misma parte del proveedor" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Los códigos de estado del stock deben coincidir" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Stock no se puede mover porque no está en stock" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Notas de entrada" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Debe proporcionarse un valor para esta prueba" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "El archivo adjunto debe ser subido para esta prueba" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Resultado de la prueba" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Valor de salida de prueba" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Adjunto de resultados de prueba" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Notas de prueba" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Finalizó" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Elemento padre" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Introduzca números de serie para nuevos artículos" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Número de pieza del proveedor" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Expirado" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Elementos secundarios" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Introduzca el número de artículos de stock para serializar" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "La cantidad no debe exceder la cantidad disponible de stock ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Ubicación de stock de destino" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Los números de serie no se pueden asignar a esta parte" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Números de serie ya existen" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Añadir nota de transacción (opcional)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Sub-ubicación" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "La parte debe ser vendible" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "El artículo está asignado a una orden de venta" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "El artículo está asignado a una orden de creación" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Cliente para asignar artículos de stock" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "La empresa seleccionada no es un cliente" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Notas de asignación de stock" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Debe proporcionarse una lista de artículos de stock" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Notas de fusión de stock" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Permitir proveedores no coincidentes" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Permitir fusionar artículos de stock con diferentes partes de proveedor" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Permitir estado no coincidente" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Permitir fusionar artículos de stock con diferentes códigos de estado" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Debe proporcionar al menos dos artículos de stock" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Sin cambios" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Valor de clave primaria de Stock" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "No hay existencias del artículo" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Notas de transacción de stock" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Notas de transacción de stock" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Artículos de stock combinados" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Convertir a variante" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Trabajo de ensamblaje creado" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Construir orden de salida completado" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Orden de ensamble rechazada" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Consumido por orden de construcción" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Enviado contra orden de venta" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Recibido contra la orden de compra" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Devuelto contra orden de devolución" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Enviar al cliente" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Devolución del cliente" @@ -9527,19 +10124,19 @@ msgstr "Usuarios" msgid "Select which users are assigned to this group" msgstr "Seleccione qué usuarios están asignados a este grupo" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Información personal" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Permisos" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Fechas importantes" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Token revocado" @@ -9547,279 +10144,283 @@ msgstr "Token revocado" msgid "Token has expired" msgstr "Token expirado" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "Token del API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Tokens del API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Nombre del token" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Nombre personalizado del token" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Fecha de expiración del token" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Última conexión" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Última vez que se usó el token" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Revocado" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Permiso establecido" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Vista" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Permiso para ver artículos" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Añadir" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Permiso para añadir artículos" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Cambiar" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Permisos para editar artículos" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Eliminar" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Permiso para eliminar artículos" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Ordenes de compra" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Órdenes de venta" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Ordenes de devolución" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Nombre de usuario" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Nombre" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Nombre del usuario" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Apellido" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Apellido del usuario" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Dirección de correo del usuario" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superusuario" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Es este usuario un superusuario" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Esta cuenta de usuario está activa" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Su cuenta ha sido creada." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Por favor, utilice la función de restablecer la contraseña para iniciar sesión" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Bienvenido a InvenTree" diff --git a/src/backend/InvenTree/locale/es_MX/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/es_MX/LC_MESSAGES/django.po index b4bba3f73e..0552a2f063 100644 --- a/src/backend/InvenTree/locale/es_MX/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/es_MX/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Spanish, Mexico\n" "Language: es_MX\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "endpoint API no encontrado" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Los artículos deben ser provistos como una lista" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Lista de artículos inválida" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Todos los filtros sólo deben ser usados como verdaderos" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Ningún artículo coincide con el criterio proporcionado" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "El usuario no tiene permiso para ver este modelo" @@ -65,150 +69,155 @@ msgstr "Confirmación de dirección de email" msgid "You must type the same email each time." msgstr "Debe escribir el mismo correo electrónico cada vez." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "La dirección de correo electrónico principal proporcionada no es válida." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "El dominio de correo electrónico proporcionado no está aprobado." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Unidad proporcionada no válida ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Ningún valor proporcionado" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "No se pudo convertir {original} a {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Cantidad proporcionada no válida" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Detalles del error pueden encontrarse en el panel de administración" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Ingrese la fecha" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Número decimal inválido" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Notas" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "El valor '{name}' no aparece en formato de patrón" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "El valor proporcionado no coincide con el patrón requerido: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "No se puede serializar más de 1000 artículos a la vez" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "No se ha proporcionado un número de serie" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Serie duplicada" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Grupo inválido: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Rango del grupo {group} supera la cantidad permitida ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Numeros de serie no encontrados" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "La cantidad de números de serie únicos ({n}) deben coincidir la cantidad ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Eliminar etiquetas HTML de este valor" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Los datos contienen contenido de markdown prohibido" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Error de conexión" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "El servidor respondió con código de estado no válido" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Se ha producido una excepción" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "El servidor respondió con un valor de longitud de contenido inválido" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "El tamaño de la imagen es demasiado grande" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "La descarga de imagen excedió el tamaño máximo" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "El servidor remoto devolvió una respuesta vacía" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "La URL proporcionada no es un archivo de imagen válido" @@ -216,159 +225,203 @@ msgstr "La URL proporcionada no es un archivo de imagen válido" msgid "Log in to the app" msgstr "Iniciar sesión en la aplicación" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Correo electrónico" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Debe habilitar la autenticación de doble factor antes de hacer cualquier otra cosa." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Error al ejecutar la validación del plug-in" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Los metadatos deben ser un objeto diccionario de python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metadatos del complemento" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Campo de metadatos JSON, para uso por complementos externos" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Patrón con formato incorrecto" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Clave de formato especificado desconocida" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Falta la clave de formato necesaria" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "El campo de servidor no puede estar vacío" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "La referencia debe coincidir con la expresión regular {pattern}" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "El número de referencia es demasiado grande" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Selección no válida" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nombre" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Descripción" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Descripción (opcional)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Ruta" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Los nombres duplicados no pueden existir bajo el mismo padre" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Notas de Markdown (opcional)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Datos de código de barras" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Datos de código de barras de terceros" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash del Código de barras" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hash único de datos de código de barras" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Error de servidor" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Se ha registrado un error por el servidor." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Imágen" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Debe ser un número válido" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Moneda" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Seleccionar moneda de las opciones disponibles" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Copiar Parámetros" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Copiar líneas" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Copiar partida del pedido original" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Copiar líneas adicionales" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Copiar partidas extra del pedido original" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Árabe" @@ -521,46 +574,48 @@ msgstr "Chino (Simplificado)" msgid "Chinese (Traditional)" msgstr "Chino (Tradicional)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Unidad física inválida" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "No es un código de moneda válido" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Estado del pedido" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Construcción o Armado Superior" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Incluye Variantes" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Incluye Variantes" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Incluye Variantes" msgid "Part" msgstr "Parte" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Categoría" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Construir antepasado" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Asignado a mí" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Asignadas a" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Creado antes de" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Creado después de" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Tiene fecha inicial" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Fecha objetivo antes de" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Fecha objetivo después de" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Completado antes de" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Completado después de" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "La compilación debe cancelarse antes de poder ser eliminada" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Consumible" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opcional" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Montaje" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Rastreado" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Comprobable" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Pedido pendiente" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Asignadas" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Disponible" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "En pedido" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Construir órden" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Ubicación" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Construir órdenes" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "BOM de ensamblado no ha sido validado" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "La orden de construcción no puede ser creado para una parte inactiva" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "La orden de construcción no puede ser creada para una parte desbloqueada" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Se debe especificar un usuario o grupo responsable" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "La parte del pedido de construcción no puede ser modificada" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Número de orden de construcción o armado" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referencia" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Breve descripción de la construcción (opcional)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Seleccionar parte a construir o armar" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referencia de orden de venta" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Ubicación de la fuente" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Seleccione la ubicación de donde tomar stock para esta construcción o armado (deje en blanco para tomar desde cualquier ubicación)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Ubicación de destino" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Seleccione la ubicación donde se almacenarán los artículos completados" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Cantidad a crear" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Número de objetos existentes a construir" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Elementos completados" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Número de productos en stock que se han completado" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Estado de la construcción" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Código de estado de construcción" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Numero de lote" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Número de lote de este producto final" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Fecha de Creación" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Fecha límite de finalización" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Fecha límite para la finalización de la construcción. La construcción estará vencida después de esta fecha." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Fecha de finalización" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "terminado por" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "El usuario que emitió esta orden" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsable" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Usuario o grupo responsable de esta orden de construcción" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Link externo" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Enlace a URL externa" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Prioridad de construcción" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Prioridad de esta orden de construcción" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Código del proyecto" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Código de proyecto para esta orden de ensamble" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "No se pudo descargar la tarea para completar las asignaciones de construcción" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "El pedido {build} ha sido procesado" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Pedido #[order] ha sido procesado" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Los números de serie deben ser proporcionados para las partes rastreables" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "No se ha especificado salida de construcción" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "La construcción de la salida ya está completa" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "La salida de la construcción no coincide con el orden de construcción" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "La cantidad debe ser mayor que cero" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "La cantidad no puede ser mayor que la cantidad de salida" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "La construcción {serial} no ha pasado todas las pruebas requeridas" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Cantidad disponible ({q}) excedida" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Construir línea de pedido" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Ensamblar equipo" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Ensamblar equipo" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Cantidad" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Cantidad requerida para orden de ensamble" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Item de construcción o armado debe especificar un resultado o salida, ya que la parte maestra está marcada como rastreable" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "El artículo de almacén selelccionado no coincide con la línea BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "La cantidad debe ser 1 para el stock serializado" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Cantidad asignada ({q}) no debe exceder la cantidad disponible de stock ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Artículo de stock sobreasignado" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Artículo de stock" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Producto original de stock" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Cantidad de stock a asignar para construir" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Instalar en" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Artículo de stock de destino" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Nivel de construcción" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Nombre de parte" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "La salida de construcción no coincide con la construcción padre" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "La parte de salida no coincide con la parte de la Orden de Construcción" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Esta salida de construcción ya ha sido completada" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Esta salida de construcción no está completamente asignada" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Ingrese la cantidad para la producción de la construcción" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Cantidad entera requerida para partes rastreables" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Cantidad entera requerida, ya que la factura de materiales contiene partes rastreables" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Números de serie" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Introduzca los números de serie de salidas de construcción" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Ubicación de stock para objetos construidos" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Autoasignar Números de Serie" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Asignar automáticamente los artículos requeridos con números de serie coincidentes" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Los siguientes números seriales ya existen o son inválidos" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Debe proporcionarse una lista de salidas de construcción" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Ubicación de almacén para salidas descartadas" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Descartar asignaciones" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar cualquier asignación de existencias para las salidas descartadas" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Razón para descartar la salida de ensamble(s)" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Ubicación para las salidas de construcción completadas" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Aceptar Asignación Incompleta" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Completar salidas si el inventario no se ha asignado completamente" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Consumir Stock Asignado" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Consume cualquier stock que ya ha sido asignado a esta construcción" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Eliminar salidas incompletas" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Eliminar cualquier salida de construcción que no se haya completado" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "No permitido" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Aceptar como consumido por este pedido de construcción" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Liberar antes de completar esta orden de construcción" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Stock sobreasignado" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Cómo quieres manejar los artículos extra de inventario asignados a la orden de construcción" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Algunos artículos de inventario han sido sobreasignados" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Aceptar no asignado" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Aceptar que los artículos de stock no se han asignado completamente a este pedido de construcción" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "El stock requerido no ha sido completamente asignado" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Aceptar incompleto" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Aceptar que el número requerido de salidas de construcción no se han completado" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "La cantidad de construcción requerida aún no se ha completado" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "La orden de construcción tiene órdenes hijas de construcción abiertas" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Orden de construcción debe estar en estado de producción" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "El orden de construcción tiene salidas incompletas" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Linea de ensamble" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Resultado de la construcción o armado" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "La salida de la construcción debe apuntar a la misma construcción" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Crear partida" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part debe apuntar a la misma parte que la orden de construcción" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "El artículo debe estar en stock" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Cantidad disponible ({q}) excedida" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "La salida de la construcción debe especificarse para la asignación de partes rastreadas" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "La salida de construcción no se puede especificar para la asignación de partes no rastreadas" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Debe proporcionarse la adjudicación de artículos" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Ubicación de inventario donde las partes deben ser obtenidas (dejar en blanco para tomar de cualquier ubicación)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Excluir ubicación" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Excluir artículos de stock de esta ubicación seleccionada" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Stock intercambiable" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Los artículos de inventario en múltiples ubicaciones se pueden utilizar de forma intercambiable" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Sustituir stock" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Permitir la asignación de partes sustitutas" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Elementos opcionales" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Asignar artículos de la BOM opcionales para construir la orden" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Referencia BOM" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID de la parte BOM" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Nombre de parte la BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Parte del proveedor" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Cantidad Asignada" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Referencia de orden de Ensamblado" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Nombre de la categoría por pieza" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Rastreable" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Heredado" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Permitir variantes" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Item de Lista de Materiales" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "En producción" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Stock externo" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Stock Disponible" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Stock sustituto disponible" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Stock variable disponible" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Pendiente" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Producción" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "En espera" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Terminado" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "El pedido {build} ha sido procesado" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Pedido #[order] ha sido procesado" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Stock requerido para la orden de construcción" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Orden de construcción atrasada" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "El pedido de construcción {bo} está atrasado" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "¿Es enlace?" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "¿Es archivo?" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "El usuario no tiene permiso para eliminar estos adjuntos" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "El usuario no tiene permiso para eliminar este adjunto" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Lista de selección bloqueada" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Código de divisa inválido" @@ -1539,15 +1641,20 @@ msgstr "No se han proporcionado códigos de divisa válidos" msgid "No plugin" msgstr "Sin plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Etiqueta del código del proyecto" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Actualizado" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Fecha y hora de la última actualización" @@ -1567,794 +1674,844 @@ msgstr "Código único del proyecto" msgid "Project description" msgstr "Descripción del proyecto" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Usuario o grupo responsable de este projecto" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Tecla de ajustes" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Valor de ajuste" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "El valor elegido no es una opción válida" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "El valor debe ser un valor booleano" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "El valor debe ser un entero" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "El valor debe ser un número válido" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "El valor no pasa las comprobaciones de validación" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Cadena de clave debe ser única" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Usuario" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Cantidad de salto de precio" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Precio" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Precio unitario a la cantidad especificada" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Endpoint" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Punto final en el que se recibe este webhook" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Nombre para este webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Activo" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Usuario o grupo responsable de este projecto" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Tecla de ajustes" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Valor de ajuste" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "El valor elegido no es una opción válida" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "El valor debe ser un valor booleano" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "El valor debe ser un entero" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "El valor debe ser un número válido" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "El valor no pasa las comprobaciones de validación" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Cadena de clave debe ser única" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Usuario" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Cantidad de salto de precio" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Precio" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Precio unitario a la cantidad especificada" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Endpoint" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Punto final en el que se recibe este webhook" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Nombre para este webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Está activo este webhook" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token para el acceso" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Clave" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Secreto compartido para HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID de mensaje" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Identificador único para este mensaje" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Servidor desde el cual se recibió este mensaje" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Encabezado" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Encabezado del mensaje" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Cuerpo" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Cuerpo de este mensaje" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Endpoint en el que se recibió este mensaje" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Trabajado en" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "¿El trabajo en este mensaje ha terminado?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Título" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Enlace" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publicado" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Resumen" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Leer" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "¿Esta noticia ya fue leída?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Archivo de imagen" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Tipo de modelo destino para esta imagen" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Unidad personalizada" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "El símbolo de la unidad debe ser único" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Nombre de unidad debe ser un identificador válido" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Nombre de unidad" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Símbolo de unidad opcional" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definición" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definición de unidad" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Archivo adjunto" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Archivo no encontrado" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Falta enlace externo" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Seleccionar archivo para adjuntar" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Comentario" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Comentario de archivo adjunto" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Fecha de carga" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Fecha de carga del archivo" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Tamaño del archivo" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Tamaño del archivo en bytes" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Tipo de modelo no válido especificado para el archivo adjunto" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Estado personalizado" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Estados personalizados" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Conjunto de estado de referencia" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Conjunto de estado extendido con este estado personalizado" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Llave lógica" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Clave lógica del estado que es igual a este estado personalizado en la lógica de negocios" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Valor" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Valor numérico que se guardará en la base de datos de modelos" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Nombre del estado" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etiqueta" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Etiqueta que se mostrará en el frontend" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Color" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Color que se mostrará en el frontend" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Modelo" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Modelo con el que este estado está asociado" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "El modelo debe ser seleccionado" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "La clave debe ser seleccionada" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "La clave lógica debe ser seleccionada" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "La clave debe ser distinta de la clave lógica" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Debe proporcionarse una clase de estado de referencia válida" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "La clave debe ser distinta de las claves lógicas del estado de referencia" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Lista de selección" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Listas de Selección" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Nombre de la lista de selección" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Descripción de la lista de selección" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Bloqueado" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "¿Está bloqueada esta lista de selección?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "¿Se puede utilizar esta lista de selección?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Complemento de origen" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Complemento que proporciona la lista de selección" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Cadena de origen" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Cadena opcional que identifica la fuente usada para esta lista" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Entrada por defecto" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Entrada predeterminada para esta lista de selección" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Creado" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Fecha y hora en la que se creó la lista de selección" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Última actualización" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Fecha y hora en que la lista de selección fue actualizada por última vez" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Entrada de lista de selección" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Entradas de la lista de selección" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Lista de selección a la que pertenece esta entrada" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Valor del elemento de la lista de selección" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Etiqueta para la entrada de lista de selección" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Descripción de la entrada de lista de selección" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "¿Está activa esta entrada de la lista de selección?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Plantilla de parámetro" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "El nombre de parámetro en la plantilla tiene que ser único" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Nombre de Parámetro" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Unidades" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Casilla de verificación" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "¿Es este parámetro una casilla de verificación?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Opciones" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Opciones válidas para este parámetro (separados por comas)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Lista de selección para este parámetro" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Opción inválida para el valor del parámetro" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Plantilla" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Datos" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Valor del parámetro" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Nota" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Campo de nota opcional" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Escanear código de barras" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Datos de código de barras" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Usuario que escaneó el código de barras" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Fecha y hora del escaneo de código de barras" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Dispositivo URL que procesó el código de barras" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Datos de contexto para el escaneo de código de barras" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Respuesta" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Respuesta de datos del escaneo de código de barras" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Resultado" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "¿El escaneo de código de barras fue exitoso?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Clave" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} cancelado" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Artículos Recibidos" @@ -2388,104 +2545,100 @@ msgstr "Los artículos han sido recibidos contra una orden de compra" msgid "Items have been received against a return order" msgstr "Los artículos han sido recibidos contra una orden de devolución" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Está en ejecución" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Tareas pendientes" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Tareas Programadas" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Tareas fallidas" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Identificación de Tarea" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Identificación de tarea única" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Bloquear hora" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Nombre de la tarea" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Función" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nombre de la Función" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argumentos de la tarea" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Argumentos de palabra clave" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Argumentos de palabra clave de tarea" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nombre de Archivo" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Lista de selección bloqueada" - #: common/setting/system.py:97 msgid "No group" msgstr "Sin grupo" @@ -2614,13 +2767,13 @@ msgstr "Intervalo de actualización de moneda" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Con qué frecuencia actualizar los tipos de cambio (establecer a cero para desactivar)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "días" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Plugin de actualización de moneda a usar" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validación estricta de URL" @@ -2760,947 +2921,1017 @@ msgstr "Complemento para generar códigos de barra" msgid "Plugin to use for internal barcode data generation" msgstr "Complemento a usar para la generación de datos de códigos de barra internos" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "Revisiones de partes" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "Habilitar campo de revisión para parte" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 +msgid "Part Revisions" +msgstr "Revisiones de partes" + +#: common/setting/system.py:413 +msgid "Enable revision field for Part" +msgstr "Habilitar campo de revisión para parte" + +#: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Patrón de expresión regular para IPN de la parte coincidente" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Permitir IPN duplicado" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que varias partes compartan el mismo IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Permitir editar IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Permite cambiar el valor de IPN mientras se edita una parte" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Copiar parte de datos BOM" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Copiar datos BOM por defecto al duplicar una parte" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Copiar parámetros de parte" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Copiar datos de parámetro por defecto al duplicar una parte" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Copiar parte de datos de prueba" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Copiar datos de parámetro por defecto al duplicar una parte" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Copiar plantillas de parámetros de categoría" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Copiar plantillas de parámetros de categoría al crear una parte" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Las partes son plantillas por defecto" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Las partes pueden ser ensambladas desde otros componentes por defecto" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Componente" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Las partes pueden ser usadas como subcomponentes por defecto" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Comprable" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Las partes son comprables por defecto" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Vendible" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Las partes se pueden vender por defecto" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Las partes son rastreables por defecto" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Las partes son virtuales por defecto" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Mostrar partes relacionadas" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Mostrar partes relacionadas para una parte" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Datos iniciales de existencias" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Permitir la creación del stock inicial al añadir una nueva parte" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Datos iniciales del proveedor" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Permitir la creación de datos iniciales del proveedor al agregar una nueva parte" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Formato de visualización de Nombre de Parte" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formato para mostrar el nombre de la parte" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Icono por defecto de la categoría de parte" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Icono por defecto de la categoría de parte (vacío significa que no hay icono)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Mínimo de lugares decimales en el precio" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Número mínimo de decimales a mostrar al procesar los datos de precios" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Máximo de lugares decimales en el precio" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Número máximo de decimales a mostrar al procesar los datos de precios" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Usar precios de proveedor" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Incluir descuentos de precios del proveedor en los cálculos generales de precios" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Anulación del historial de compra" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "El precio histórico de compra anula los descuentos de precios del proveedor" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Usar precio del artículo de almacén" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Usar los precios de los datos de inventario introducidos manualmente para los cálculos de precios" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Edad del precio del artículo de almacén" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Excluir artículos de almacén anteriores a este número de días de los cálculos de precios" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Usar precios variantes" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir variantes de precios en los cálculos generales de precios" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Solo variantes activas" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Usar solo partes de variantes activas para calcular los precios de variantes" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Intervalo de reconstrucción de precios" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Número de días antes de que el precio de la parte se actualice automáticamente" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Precios internos" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Habilitar precios internos para partes" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Anulación del precio interno" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Si está disponible, los precios internos anulan los cálculos del rango de precios" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Habilitar impresión de etiquetas" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Habilitar impresión de etiquetas desde la interfaz web" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "PPP de la imagen de etiqueta" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Resolución DPI al generar archivos de imagen que suministrar para etiquetar complementos de impresión" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Habilitar informes" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Habilitar generación de informes" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Modo de depuración" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Generar informes en modo de depuración (salida HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Registrar errores de reportes" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Registrar errores ocurridos al generar reportes" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Tamaño de página" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Tamaño de página predeterminado para informes PDF" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Forzar unidades de parámetro" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Si se proporcionan unidades, los valores de parámetro deben coincidir con las unidades especificadas" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Seriales únicos globalmente" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Los números de serie para los artículos de inventario deben ser únicos globalmente" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Eliminar existencias agotadas" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Determina el comportamiento por defecto al agotarse un artículo del inventario" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Plantilla de código de lote" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Plantilla para generar códigos de lote por defecto para artículos de almacén" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Expiración de stock" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Habilitar la funcionalidad de expiración de stock" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Vender existencias caducadas" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Permitir venta de existencias caducadas" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Tiempo histórico de Stock" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Número de días de artículos de stock se consideran obsoletos antes de caducar" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Crear Stock Caducado" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Permitir crear con stock caducado" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Control de Stock" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Habilitar control de propiedad sobre ubicaciones de stock y artículos" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Icono por defecto de ubicación de almacén" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Icono por defecto de ubicación de almacén (vacío significa que no hay icono)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Mostrar Articulos de Stock Instalados" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Mostrar los artículos de stock instalados en las tablas de stock" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Revisar BOM al instalar artículos" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Los elementos de stock instalados deben existir en la BOM para la parte padre" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Permitir transferencia Sin Existencias" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Permitir que artículos del inventario sin existencias puedan ser transferidos entre ubicaciones de inventario" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Armado" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Patrón requerido para generar el campo de referencia de la Orden de Ensamblado" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Requerir Dueño Responsable" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Se debe asignar un dueño responsable a cada orden" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Requerir Parte Activa" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Impedir la creación de órdenes de fabricación para partes inactivas" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Requerir Parte Bloqueada" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Impedir la creación de órdenes de fabricación para partes bloqueadas" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Impedir la creación de órdenes de fabricación a menos que se haya validado la lista de materiales" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Prevenir la finalización de la orden de construcción hasta que todas las órdenes hijas estén cerradas" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Bloquear hasta que los Tests pasen" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Evitar que las construcciones sean completadas hasta que todas las pruebas requeridas pasen" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Habilitar órdenes de devolución" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Habilitar la funcionalidad de orden de devolución en la interfaz de usuario" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Patrón de referencia de orden de devolución" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Patrón requerido para generar el campo de referencia de devolución de la orden" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Editar ordenes de devolución completadas" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Permitir la edición de ordenes de devolución después de que hayan sido completados" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Patrón de Referencia de Ordenes de Venta" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Patrón requerido para generar el campo de referencia de la orden de venta" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Envío Predeterminado de Ordenes de Venta" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Habilitar la creación de envío predeterminado con ordenes de entrega" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Editar Ordenes de Venta Completados" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Permitir la edición de ordenes de venta después de que hayan sido enviados o completados" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Marcar pedidos enviados como completados" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Los pedidos marcados como enviados se completarán automáticamente, evitando el estado de \"envío\"" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Patrón de Referencia de Orden de Compra" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Patrón requerido para generar el campo de referencia de la Orden de Compra" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Editar Ordenes de Compra Completados" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Permitir la edición de órdenes de venta después de que hayan sido enviados o completados" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Autocompletar Ordenes de compra" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Marcar automáticamente las órdenes de compra como completas cuando se reciben todos los artículos de línea" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Habilitar función de contraseña olvidada" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Activar la función olvido de contraseña en las páginas de inicio de sesión" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Habilitar registro" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "Activar auto-registro para usuarios en las páginas de inicio de sesión" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Habilitar SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "Habilitar SSO en las páginas de inicio de sesión" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "Habilitar registro SSO" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Activar autoregistro a través de SSO para usuarios en las páginas de inicio de sesión" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "Habilitar sincronización de grupo SSO" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "Habilitar la sincronización de grupos de Inventree con grupos proporcionados por el IdP" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "Clave de grupo SSO" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "El nombre del atributo reclamado por el grupo proporcionado por el IdP" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "Mapa del grupo SSO" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "Un mapeo de grupos SSO a grupos de Inventree locales. Si el grupo local no existe, se creará." - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "Eliminar grupos fuera de SSO" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Habilitar función de contraseña olvidada" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Activar la función olvido de contraseña en las páginas de inicio de sesión" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Habilitar registro" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "Activar auto-registro para usuarios en las páginas de inicio de sesión" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "Habilitar SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "Habilitar SSO en las páginas de inicio de sesión" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "Habilitar registro SSO" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "Activar autoregistro a través de SSO para usuarios en las páginas de inicio de sesión" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "Habilitar sincronización de grupo SSO" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "Habilitar la sincronización de grupos de Inventree con grupos proporcionados por el IdP" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "Clave de grupo SSO" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "El nombre del atributo reclamado por el grupo proporcionado por el IdP" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "Mapa del grupo SSO" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "Un mapeo de grupos SSO a grupos de Inventree locales. Si el grupo local no existe, se creará." + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "Eliminar grupos fuera de SSO" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email requerido" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Requiere usuario para suministrar correo al registrarse" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Auto-rellenar usuarios SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Rellenar automáticamente los datos de usuario de la cuenta SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Correo dos veces" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Al registrarse pregunte dos veces a los usuarios por su correo" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Contraseña dos veces" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Al registrarse, preguntar dos veces a los usuarios por su contraseña" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Dominios permitidos" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Restringir el registro a ciertos dominios (separados por comas, comenzando por @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grupo al registrarse" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Grupo al que se asignan nuevos usuarios al registrarse. Si la sincronización de grupo SSO está activada, este grupo sólo se establece si no se puede asignar ningún grupo desde el IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Forzar MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Los usuarios deben utilizar seguridad multifactor." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Comprobar complementos al iniciar" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Comprobar que todos los complementos están instalados en el arranque - habilitar en entornos de contenedores" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Revisar actualizaciones del plugin" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Habilitar comprobaciones periódicas para actualizaciones de plugins instalados" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Habilitar integración de URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Habilitar plugins para añadir rutas de URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Habilitar integración de navegación" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Habilitar plugins para integrar en la navegación" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Habilitar integración de la aplicación" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Habilitar plugins para añadir aplicaciones" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Habilitar integración de programación" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Habilitar plugins para ejecutar tareas programadas" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Habilitar integración de eventos" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Habilitar plugins para responder a eventos internos" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Habilitar integración de interfaz" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Habilitar complementos para integrar en la interfaz de usuario" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Excluir Ubicaciones Externas" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Periodo de inventario automático" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Mostrar nombres completos de los usuarios" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Mostrar nombres completos de usuarios en lugar de nombres de usuario" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Habilitar datos de estación de prueba" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Habilitar la recolección de datos de estaciones de prueba para resultados de prueba" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Búsqueda usando una expresión regular" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Habilitar expresiones regulares en las consultas de búsqueda" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Búsqueda por palabra completa" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Las consultas de búsqueda devuelven resultados para palabras enteras coincidentes" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Formularios de cierre de teclas de escape" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Usa la clave de escape para cerrar formularios modales" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Barra de navegación fija" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "La posición de la barra de navegación se fija en la parte superior de la pantalla" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Iconos de navegación" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Formato de Fecha" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Formato preferido para mostrar fechas" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Recibir reportes de error" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Recibir notificación de errores del sistema" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Últimas impresoras usadas" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Un dominio vacío no está permitido." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Nombre de dominio inválido: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Empresa" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Tiene existencias" @@ -4123,8 +4387,8 @@ msgstr "Teléfono de contacto" msgid "Contact email address" msgstr "Correo electrónico de contacto" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Contacto" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Dirección" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Direcciones" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Seleccionar empresa" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Título de dirección" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Título que describe la entrada de dirección" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Dirección principal" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Establecer como dirección principal" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Línea 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Dirección línea 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Línea 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Dirección línea 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Código postal" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Ciudad/región" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Código postal de ciudad/región" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Estado/provincia" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Estado o provincia" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "País" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Dirección de país" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Notas de envío de mensajería" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Notas para el mensajero de envío" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Notas de envío internas" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Notas de envío para uso interno" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Enlace a información de dirección (externa)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Parte del fabricante" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Parte base" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Seleccionar parte" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Seleccionar fabricante" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Número de parte de fabricante" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL para el enlace de parte del fabricante externo" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Descripción de la parte del fabricante" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Las unidades de paquete deben ser compatibles con las unidades de partes de base" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Las unidades de paquete deben ser mayor que cero" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "La parte vinculada del fabricante debe hacer referencia a la misma parte base" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Proveedor" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Seleccionar proveedor" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Unidad de mantenimiento de stock de proveedores" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Seleccionar parte del fabricante" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL del enlace de parte del proveedor externo" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Descripción de la parte del proveedor" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "costo base" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Cargo mínimo (p. ej., cuota de almacenamiento)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Paquetes" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Embalaje de partes" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Cantidad de paquete" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Cantidad total suministrada en un solo paquete. Dejar vacío para artículos individuales." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "múltiple" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Pedido múltiple" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Cantidad disponible del proveedor" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Disponibilidad actualizada" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Fecha de última actualización de los datos de disponibilidad" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Moneda predeterminada utilizada para este proveedor" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Nombre de la empresa" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "En Stock" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Información adicional de estado para este artículo" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Clave personalizada de estado" @@ -4476,123 +4740,152 @@ msgstr "Colocado" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Archivo de datos" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Archivo de datos a importar" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Columnas" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Valores predeterminados del campo" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Filtros del campo" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Algunos campos requeridos no han sido mapeados" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "La columna ya fue mapeada a un campo de la base de datos" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "La columna no existe en el archivo de datos" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "El campo no existe en el modelo destino" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "El campo seleccionado es de solo lectura" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Sesión de importación" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Campo" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Columna" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Número de fila" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Datos de la fila original" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Errores" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Válido" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Formato de archivo de datos no soportado" @@ -4600,43 +4893,47 @@ msgstr "Formato de archivo de datos no soportado" msgid "Failed to open data file" msgstr "Error al abrir el archivo de datos" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Dimensiones del archivo de datos inválidas" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Valores predeterminados del campo inválidos" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Filtros del campo inválidos" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Filas" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Listado de IDs de fila a aceptar" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "No hay filas" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "La fila no pertenece a esta sesión" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "La fila contiene datos inválidos" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "La fila ya se ha completado" @@ -4672,115 +4969,115 @@ msgstr "El archivo de datos tiene demasiadas columnas" msgid "Data file contains too many rows" msgstr "El archivo de datos tiene demasiadas filas" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Copias" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Número de copias a imprimir para cada etiqueta" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Conectado" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Desconocido" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Impresión" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Sin archivos multimedia" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Atascamiento de papel" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Desconectado" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Impresora de Etiquetas" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Imprime directamente etiquetas para varios artículos." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Ubicación de la Impresora" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Nombre de la máquina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Tipo de Máquina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Tipo de máquina" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Controlador" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Controlador usado para la máquina" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Las máquinas pueden ser desactivadas" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Controlador disponible" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Sin errores" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Inicializado" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Estado de máquina" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Máquina" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupo" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Referencia del pedido" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Destacado" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Tiene Código de Proyecto" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Creado por" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Creado antes de" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Creado después de" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Fecha objetivo antes de" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Fecha objetivo después de" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Tiene Precio" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Completado antes de" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Completado después de" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Orden" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Orden completada" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Componente interno" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Orden pendiente" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Completados" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Tiene envío" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Orden de compra" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Orden de compra" msgid "Sales Order" msgstr "Orden de Venta" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Orden de devolución" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Precio Total" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Precio total para este pedido" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Moneda de pedido" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Moneda para este pedido (dejar en blanco para utilizar el valor predeterminado de la empresa)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "El contacto no coincide con la empresa seleccionada" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Descripción del pedido (opcional)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Seleccione el código del proyecto para este pedido" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Enlace a Url externa" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Fecha objetivo" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Fecha esperada para la entrega del pedido. El pedido se retrasará después de esta fecha." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Fecha de emisión" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Fecha de expedición del pedido" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Usuario o grupo responsable de este pedido" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Punto de contacto para este pedido" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Dirección de la empresa para este pedido" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Referencia del pedido" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Estado" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Estado de la orden de compra" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Empresa de la cual se están encargando los artículos" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Referencia del proveedor" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Código de referencia de pedido del proveedor" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "recibido por" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "La fecha de pedido fue completada" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Destinación" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Destino para los artículos recibidos" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "El proveedor de la parte debe coincidir con el proveedor de PO" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "La partida no coincide con la orden de compra" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "La cantidad debe ser un número positivo" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Empresa a la que se venden los artículos" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Estado de la orden de venta" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Referencia del cliente " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Código de referencia de pedido del cliente" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Fecha de envío" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "enviado por" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "La partida no está asociada con este pedido" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "No se han encontrado coincidencias para los siguientes números de serie" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Los siguientes números de serie no están disponibles" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "La orden ya fue completada" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "La orden ya fue cancelada" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Sólo una orden abierta puede ser marcada como completa" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "El pedido no se puede completar porque hay envíos incompletos" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "El pedido no se puede completar ya que hay asignaciones incompletas" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "El pedido no se puede completar porque hay partidas incompletas" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Cantidad del artículo" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Referencia de partida" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Notas de partida" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Fecha objetivo para esta partida (dejar en blanco para usar la fecha de destino de la orden)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Descripción de partida (opcional)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Contexto adicional para esta línea" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Precio unitario" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "La parte del proveedor debe coincidir con el proveedor" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Parte del proveedor" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Recibido" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Número de artículos recibidos" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Precio de Compra" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Precio de compra unitario" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Sólo las partes vendibles pueden ser asignadas a un pedido de venta" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Precio de Venta" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Precio de venta unitario" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Cantidad enviada" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Fecha del envío" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Fecha de entrega" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Fecha de entrega del envío" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Revisado por" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Usuario que revisó este envío" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envío" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Número de envío" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Número de Seguimiento" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Información de seguimiento del envío" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Número de factura" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Número de referencia para la factura asociada" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "El envío ya ha sido enviado" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "El envío no tiene artículos de stock asignados" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "El artículo de stock no ha sido asignado" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "No se puede asignar el artículo de stock a una línea con una parte diferente" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "No se puede asignar stock a una línea sin una parte" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La cantidad de asignación no puede exceder la cantidad de stock" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Cantidad asignada debe ser mayor que cero" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "La cantidad debe ser 1 para el stock serializado" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "La orden de venta no coincide con el envío" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "El envío no coincide con el pedido de venta" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Línea" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Referencia del envío del pedido de venta" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Ítem" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Seleccionar artículo de stock para asignar" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Especificar la cantidad de asignación de stock" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Referencia de la orden de devolución" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Empresa de la cual se están devolviendo los artículos" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Estado de la orden de devolución" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "El artículo de almacén debe ser especificado" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "La cantidad de retorno excede la cantidad de existencias" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "La cantidad de retorno debe ser mayor que cero" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Cantidad inválida para el artículo de stock serializado" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Seleccionar el artículo a devolver del cliente" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Fecha de recepción" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Resultado" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Salida para esta partida" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Costo asociado con la devolución o reparación para esta partida" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID del Pedido" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID del pedido a duplicar" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Copiar líneas" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Copiar partida del pedido original" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Copiar líneas adicionales" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Copiar partidas extra del pedido original" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Copiar Parámetros" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Partidas" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Líneas completadas" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Duplicar pedido" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Especificar opciones para duplicar este pedido" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "ID de pedido inválido" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Nombre del proveedor" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "El pedido no puede ser cancelado" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Permitir cerrar el pedido con partidas incompletas" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "El pedido tiene partidas incompletas" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "El pedido no está abierto" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Precio automático" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Calcular precio de compra automáticamente con base en los datos del proveedor" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Moneda del precio de compra" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Combinar artículos" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Número de parte interna" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Nombre interno de parte" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Debe especificar la parte del proveedor" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "La orden de compra debe especificarse" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "El proveedor debe coincidir con la orden de compra" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "La orden de compra debe coincidir con el proveedor" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Partida" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Seleccione la ubicación de destino para los artículos recibidos" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Introduzca el código de lote para los artículos de almacén entrantes" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Fecha de Expiración" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Introduzca números de serie para artículos de almacén entrantes" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Código de barras escaneado" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Código de barras en uso" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Se deben proporcionar las partidas" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Se requiere ubicación de destino" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Los valores del código de barras deben ser únicos" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Envíos" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Envíos completados" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Moneda del precio de venta" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Elementos asignados" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "No se proporcionaron detalles de envío" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "La partida no está asociada con este pedido" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "La cantidad debe ser positiva" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Introduzca números de serie para asignar" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "El envío ya ha sido enviado" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "El envío no está asociado con este pedido" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "No se han encontrado coincidencias para los siguientes números de serie" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Los siguientes números de serie no están disponibles" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Partida de orden de devolución" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "La partida no coincide con la orden de devolución" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "La partida ya ha sido recibida" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Los artículos sólo pueden ser recibidos contra pedidos en curso" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Cantidad a devolver" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Moneda de precio de línea" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Perdida" @@ -5718,1279 +6125,1312 @@ msgstr "Perdida" msgid "Returned" msgstr "Devuelto" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "En progreso" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Devolución" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Reparación" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Reemplazo" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Reembolso" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Rechazo" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Emitido" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Orden de compra atrasada" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "La orden de compra {po} está atrasada" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Orden de venta atrasada" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "La orden de venta {so} está atrasada" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Favoritos" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Profundidad" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filtrar por profundidad de categoría" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Nivel superior" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filtrar por categorías de nivel superior" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "En cascada" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Tiene resultados" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Categoría de parte" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Categorías de parte" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Ubicación Predeterminada" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Ubicación predeterminada para partes de esta categoría" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Estructural" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Las partes no pueden asignarse directamente a una categoría estructural, pero pueden asignarse a categorías hijas." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Palabras clave predeterminadas" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Palabras clave por defecto para partes en esta categoría" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Icono" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Icono (opcional)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "¡No puedes hacer que esta categoría de partes sea estructural porque algunas partes ya están asignadas!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Valor predeterminado" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Valor de parámetro por defecto" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Partes" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Ya existe un artículo de almacén con este número de serie" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN duplicado no permitido en la configuración de partes" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "La revisión de parte duplicada ya existe." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Parte con este nombre, IPN y revisión ya existe." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "¡No se pueden asignar partes a las categorías de partes estructurales!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Nombre de la parte" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Es plantilla" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "¿Es esta parte una parte de la plantilla?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Descripción de parte (opcional)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Palabras claves" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Palabras clave para mejorar la visibilidad en los resultados de búsqueda" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Categoría de parte" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Revisión de parte o número de versión" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revisión" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "¿Es esta parte una variante de otra parte?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Variante de" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "¿Dónde se almacena este artículo normalmente?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Expiración por defecto" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Tiempo de expiración (en días) para los artículos de stock de esta parte" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Stock mínimo" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Nivel mínimo de stock permitido" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Unidades de medida para esta parte" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "¿Se puede construir esta parte a partir de otras partes?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "¿Se puede utilizar esta parte para construir otras partes?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "¿Esta parte tiene seguimiento de objetos únicos?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "¿Se puede comprar esta parte a proveedores externos?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "¿Se puede vender esta parte a los clientes?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "¿Está activa esta parte?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Las partes bloqueadas no pueden ser editadas" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "¿Es ésta una parte virtual, como un producto de software o una licencia?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Suma de verificación de BOM" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Suma de verificación de BOM almacenada" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOM comprobado por" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Fecha BOM comprobada" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Creación de Usuario" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Dueño responsable de esta parte" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Vender múltiples" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Moneda utilizada para almacenar en caché los cálculos de precios" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Costo mínimo de BOM" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Costo mínimo de partes de componentes" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Costo máximo de BOM" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Costo máximo de partes de componentes" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Costo mínimo de compra" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Costo histórico mínimo de compra" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Costo máximo de compra" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Costo histórico máximo de compra" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Precio interno mínimo" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Costo mínimo basado en precios reducidos internos" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Precio interno máximo" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Costo máximo basado en precios reducidos internos" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Precio mínimo de proveedor" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Precio mínimo de la parte de proveedores externos" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Precio máximo de proveedor" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Precio máximo de la parte de proveedores externos" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Costo mínimo de variante" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Costo mínimo calculado de las partes variantes" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Costo máximo de variante" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Costo máximo calculado de las partes variantes" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Costo mínimo" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Anular el costo mínimo" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Costo máximo" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Reemplazar coste máximo" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Costo mínimo general calculado" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Precio de venta mínimo" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Precio de venta mínimo basado en precios reducidos" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Precio de venta máximo" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Precio de venta máximo basado en precios reducidos" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Costo de venta mínimo" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Precio de venta mínimo histórico" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Costo de Venta Máximo" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Precio de venta máximo histórico" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Número de artículos" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Fecha" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Costo de Stock Mínimo" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Costo mínimo estimado del stock disponible" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Las plantillas de prueba solo pueden ser creadas para partes de prueba" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Nombre de prueba" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Introduzca un nombre para la prueba" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Descripción de prueba" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Introduce la descripción para esta prueba" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Requerido" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "¿Es necesario pasar esta prueba?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Requiere valor" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "¿Esta prueba requiere un valor al agregar un resultado de la prueba?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Adjunto obligatorio" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "¿Esta prueba requiere un archivo adjunto al agregar un resultado de la prueba?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Seleccionar parte principal" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Sub parte" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Seleccionar parte a utilizar en BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Cantidad del artículo en BOM" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Este artículo BOM es opcional" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Este artículo de BOM es consumible (no está rastreado en órdenes de construcción)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Referencia de artículo de BOM" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Notas del artículo de BOM" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Suma de verificación" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Suma de verificación de línea de BOM" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Validado" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Este artículo de BOM ha sido validado" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Este artículo BOM es heredado por BOMs para partes variantes" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Artículos de stock para partes variantes pueden ser usados para este artículo BOM" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "La cantidad debe ser un valor entero para las partes rastreables" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Debe especificar la subparte" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Ítem de BOM sustituto" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "La parte sustituta no puede ser la misma que la parte principal" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Artículo BOM superior" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Sustituir parte" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Parte 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Parte 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Seleccionar parte relacionada" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Nota para esta relación" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Categoría principal de parte" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Subcategorías" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Moneda de compra de ítem de stock" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Parte original" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Seleccione la parte original a duplicar" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Copiar Imagen" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Copiar imagen desde la parte original" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Copiar BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Copiar la factura de materiales de la parte original" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Copiar datos del parámetro de la parte original" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Copiar Notas" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Cantidad Inicial de Stock" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Seleccione proveedor (o déjelo en blanco para saltar)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Seleccionar fabricante (o dejar en blanco para saltar)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Número de parte del fabricante" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "La empresa seleccionada no es un proveedor válido" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "La empresa seleccionada no es un fabricante válido" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Nombre de categoría" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "En construcción" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Elementos de stock" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Inventario Total" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Duplicar Parte" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Copiar Imagen" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Copiar imagen desde la parte original" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Copiar BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Copiar la factura de materiales de la parte original" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Copiar Notas" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Stock Inicial" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Crear Parte con cantidad inicial de stock" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Información del proveedor" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Añadir información inicial del proveedor para esta parte" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Copiar Parámetros de Categoría" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Copiar plantillas de parámetro de la categoría de partes seleccionada" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Imagen Existente" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "El archivo de imagen no existe" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Validación de Lista de Materiales" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Puede construir" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Precio mínimo" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Anular el valor calculado para precio mínimo" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Precio mínimo de moneda" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Precio máximo" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Precio máximo de moneda" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Actualizar" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "El precio mínimo no debe ser mayor que el precio máximo" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "El precio máximo no debe ser inferior al precio mínimo" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Seleccionar parte de la que copiar BOM" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Eliminar Datos Existentes" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Eliminar artículos BOM existentes antes de copiar" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Incluye Heredado" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Incluye artículos BOM que son heredados de partes con plantillas" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Omitir filas no válidas" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Activar esta opción para omitir filas inválidas" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Copiar partes sustitutas" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Notificación por bajo stock" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "El stock disponible para {part.name} ha caído por debajo del nivel mínimo configurado" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Instalado" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "No se especificó ninguna acción" msgid "No matching action found" msgstr "No se encontró ninguna acción coincidente" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "No se encontró ninguna coincidencia para los datos del código de barras" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Coincidencia encontrada para datos de códigos de barras" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "El código de barras coincide con artículo existente" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "No se ha encontrado ningún complemento para datos de código de barras" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Ningún complemento coincide con el código de barras del proveedor" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Ningún pedido de venta proporcionado" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "Se encontró artículo coincidente" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "La pieza del proveedor no coincide con la partida" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "La partida ya está completada" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "No se pudo recibir partida" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Proporciona soporte nativo para códigos de barras" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL que se utiliza para enviar mensajes a un canal de slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Abrir enlace" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Proporciona soporte nativo para imprimir etiquetas PDF" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Modo de depuración" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Activar modo de depuración - devuelve código HTML en lugar de PDF" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "El complemento no está instalado" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Instalación del complemento no encontrada" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Complemento" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "No se encontró autor" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "El complemento '{p}' no es compatible con la versión actual de InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "El complemento requiere al menos la versión {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "El complemento requiere como máximo la versión {v}" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Dimensiones de etiqueta inválidas" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Carta" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Nombre de la plantilla" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Adjuntar al modelo al imprimir" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Guardar la salida del informe como un archivo adjunto contra la instancia del modelo enlazado al imprimir" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Patrón de Nombre de archivo" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtros" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Tamaño de página para reportes PDF" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Ancho [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Ancho de la etiqueta, especificado en mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Altura de la etiqueta, especificada en mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Fragmento" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Archivo fragmento de informe" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Descripción de archivo de fragmento" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Activo" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Reportar archivo de activos" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Descripción del archivo de activos" @@ -8291,23 +8771,23 @@ msgstr "Descripción del archivo de activos" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Selecciona la plantilla de etiqueta" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Complemento de impresión" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Selecciona el complemento a usar para imprimir etiquetas" @@ -8338,13 +8818,10 @@ msgstr "Materiales necesarios" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Imagen de parte" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Emitido" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Requerido para" @@ -8380,8 +8857,8 @@ msgstr "Total" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Número de serie" @@ -8405,7 +8882,7 @@ msgstr "Artículo Stock Informe de prueba" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Elementos instalados" @@ -8438,810 +8915,922 @@ msgstr "Ningún resultado (requerido)" msgid "No result" msgstr "Sin resultados" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Ubicación principal" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filtrar por ubicación principal" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Nombre de pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "El nombre de la pieza contiene (insensible a mayúsculas y minúsculas)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Nombre de la pieza (expresión regular)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "IPN de Pieza (insensible a mayúsculas y minúsculas)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "IPN de pieza contiene (insensible a mayúsculas y minúsculas)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "IPN de Pieza (expresión regular)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Existencias mínimas" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Existencias máximas" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Código de estado" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Ubicación externa" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Consumido por orden de construcción" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Instalado en otro artículo de existencias" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Árbol de piezas" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Actualizado antes de" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Actualizado después de" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Inventario antes de" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Inventario después de" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Desactualizado" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Cantidad requerida" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Debe suministrarse una parte válida" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Ubicación de Stock" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Ubicaciones de Stock" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Propietario" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Seleccionar Propietario" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Externo" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Se debe especificar la pieza" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "La cantidad debe ser 1 para el artículo con un número de serie" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Número de serie no se puede establecer si la cantidad es mayor que 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "El objeto no puede pertenecer a sí mismo" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "El artículo debe tener una referencia de construcción si is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "La referencia de la construcción no apunta al mismo objeto de parte" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Artículo de stock padre" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Parte base" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Seleccione una parte del proveedor correspondiente para este artículo de stock" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "¿Dónde se encuentra este artículo de stock?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Empaquetar este artículo de stock se almacena en" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Instalado en" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "¿Está este artículo instalado en otro artículo?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Número de serie para este artículo" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Código de lote para este artículo de stock" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Cantidad de Stock" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Build de origen" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Build para este item de stock" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Consumido por" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Orden de compra de origen" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Orden de compra para este artículo de stock" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Orden de venta de destino" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Fecha de caducidad del artículo de stock. El stock se considerará caducado después de esta fecha" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Eliminar al agotar" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Eliminar este artículo de stock cuando se agoten las existencias" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Precio de compra único en el momento de la compra" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Convertido a parte" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "La parte no está establecida como rastreable" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Cantidad debe ser un entero" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Los números de serie deben ser proporcionados como una lista" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "La cantidad no coincide con los números de serie" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Artículo de stock ha sido asignado a un pedido de venta" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Artículo de stock está instalado en otro artículo" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Artículo de stock contiene otros artículos" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Artículo de stock ha sido asignado a un cliente" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "El artículo de stock está en producción" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Stock serializado no puede ser combinado" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Artículos de Stock Duplicados" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Los artículos de stock deben referirse a la misma parte" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Los artículos de stock deben referirse a la misma parte del proveedor" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Los códigos de estado del stock deben coincidir" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Stock no se puede mover porque no está en stock" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Notas de entrada" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Debe proporcionarse un valor para esta prueba" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "El archivo adjunto debe ser subido para esta prueba" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Resultado de la prueba" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Valor de salida de prueba" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Adjunto de resultados de prueba" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Notas de prueba" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Finalizó" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Elemento padre" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Introduzca números de serie para nuevos artículos" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Número de pieza del proveedor" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Expirado" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Elementos secundarios" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Introduzca el número de artículos de stock para serializar" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "La cantidad no debe exceder la cantidad disponible de stock ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Ubicación de stock de destino" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Los números de serie no se pueden asignar a esta parte" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Números de serie ya existen" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Añadir nota de transacción (opcional)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Sub-ubicación" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "La parte debe ser vendible" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "El artículo está asignado a una orden de venta" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "El artículo está asignado a una orden de creación" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Cliente para asignar artículos de stock" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "La empresa seleccionada no es un cliente" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Notas de asignación de stock" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Debe proporcionarse una lista de artículos de stock" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Notas de fusión de stock" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Permitir proveedores no coincidentes" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Permitir fusionar artículos de stock con diferentes partes de proveedor" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Permitir estado no coincidente" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Permitir fusionar artículos de stock con diferentes códigos de estado" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Debe proporcionar al menos dos artículos de stock" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Sin cambios" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Valor de clave primaria de Stock" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "No hay existencias del artículo" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Notas de transacción de stock" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Notas de transacción de stock" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Artículos de stock combinados" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Convertir a variante" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Trabajo de ensamblaje creado" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Construir orden de salida completado" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Orden de ensamble rechazada" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Consumido por orden de construcción" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Enviado contra orden de venta" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Recibido contra la orden de compra" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Devuelto contra orden de devolución" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Enviar al cliente" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Devolución del cliente" @@ -9527,19 +10124,19 @@ msgstr "Usuarios" msgid "Select which users are assigned to this group" msgstr "Seleccione qué usuarios están asignados a este grupo" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Información personal" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Permisos" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Fechas importantes" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Token revocado" @@ -9547,279 +10144,283 @@ msgstr "Token revocado" msgid "Token has expired" msgstr "Token expirado" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "Token del API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Tokens del API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Nombre del token" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Nombre personalizado del token" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Fecha de expiración del token" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Última conexión" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Última vez que se usó el token" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Revocado" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Permiso establecido" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Vista" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Permiso para ver artículos" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Añadir" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Permiso para añadir artículos" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Cambiar" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Permisos para editar artículos" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Eliminar" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Permiso para eliminar artículos" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Ordenes de compra" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Órdenes de venta" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Ordenes de devolución" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Nombre de usuario" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Nombre" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Nombre del usuario" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Apellido" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Apellido del usuario" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Dirección de correo del usuario" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superusuario" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Es este usuario un superusuario" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Esta cuenta de usuario está activa" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Su cuenta ha sido creada." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Por favor, utilice la función de restablecer la contraseña para iniciar sesión" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Bienvenido a InvenTree" diff --git a/src/backend/InvenTree/locale/et/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/et/LC_MESSAGES/django.po index ac5f2ae637..7b6d751dc2 100644 --- a/src/backend/InvenTree/locale/et/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/et/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Estonian\n" "Language: et_EE\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Teil ei ole selle lehe vaatamiseks luba" @@ -65,150 +69,155 @@ msgstr "E-posti aadressi kinnitus" msgid "You must type the same email each time." msgstr "" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Ei tohi tühi olla" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Pane kuupäev" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Märkmed" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Ühenduse viga" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Esines tõrge" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -216,159 +225,203 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-post" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Vigane valik" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nimi" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Kirjeldus" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Kirjeldus (valikuline)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Tee" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Serveri viga" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Pilt" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Kopeeri parameetrid" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Kopeeri read" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Kopeeri reaüksused algsest tellimusest" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Kopeeri lisareaüksused algsest tellimusest" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Araabia" @@ -521,46 +574,48 @@ msgstr "Hiina (lihtsustatud)" msgid "Chinese (Traditional)" msgstr "Hiina (traditsiooniline)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Osa" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Määratud" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Valikuline" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Jälgitud" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Saadaval" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Asukoht" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Tootekood" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Koostamise olek" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Loomise kuupäev" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Kogus" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Osa nimi" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Tühista kõik laoseisu eraldised mahakantud väljundite jaoks" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Valikained" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Jälgitav" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Saadaval laos" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Ootel" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Tootmine" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Katkestatud" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Valmis" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "On link" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "On fail" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "Pluginat pole" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Uuendatud" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Seade võti" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Seade väärtus" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Seade võti" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Seade väärtus" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "ID" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Pealkiri" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Avaldatud" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Kokkuvõte" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Loetud" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Pildifail" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Ühiku nimi" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Sümbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definitsioon" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Ühiku definitsioon" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Manus" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Puuduv fail" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Puuduv väline link" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Vali fail, mida lisada" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Kommentaar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "Faili suurus" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Faili suurus" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Silt" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Loodud" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Mall" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Andmed" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Märkus" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Vöötkoodi andmed" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Kontekst" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Vastus" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Tulemus" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Võti" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Ülesande nimi" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funktsioon" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Funktsiooni nimi" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumendid" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Ülesande argumendid" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Failinimi" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Mudeli liik" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "Grupp puudub" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "päeva" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,800 +2921,790 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Ostetav" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuaalne" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "Lehe suurus" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" -msgstr "" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" +msgstr "Lehe suurus" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1111 @@ -3561,146 +3712,230 @@ msgid "Enable interface integration" msgstr "Luba liidese integreerimine" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" -msgstr "Luba pluginatel integreeruda kasutajaliidesesse" - -#: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enforce MFA" msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." +msgstr "" + +#: common/setting/system.py:1118 +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +msgstr "" + +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +#: common/setting/system.py:1174 +msgid "Enable interface integration" +msgstr "Luba liidese integreerimine" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" -msgstr "" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" +msgstr "Luba pluginatel integreeruda kasutajaliidesesse" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4116,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Tootja" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Ettevõte" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Laos" @@ -4123,8 +4391,8 @@ msgstr "Kontakttelefoni number" msgid "Contact email address" msgstr "Kontakt e-postiaadress" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4444,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Aadress" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Aadressid" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Vali ettevõte" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Peamine aadress" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Määra peamine aadress" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Rida 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Aadressi rida 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Rida 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Aadressi rida 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Postiindeks" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Linn/Piirkond" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Riik" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Tarnija" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Vali tarnija" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4744,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Andmefail" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Veerud" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Väli" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Veerg" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4897,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4973,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5093,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupp" @@ -4816,117 +5117,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5236,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Staatus" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Järgmised seerianumbrid ei ole saadaval" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Müügihind" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Saadetud" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Saadetis" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Rida" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "Tellimuse ID" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "Kopeeritava tellimuse ID" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Kopeeri read" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Kopeeri reaüksused algsest tellimusest" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Kopeeri lisareaüksused algsest tellimusest" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Kopeeri parameetrid" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Määrake selle tellimuse dubleerimise valikud" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Vale tellimuse ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Tootekood" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Vöötkood" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Skännitud ribakood" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Saadetised" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Järgmised seerianumbrid ei ole saadaval" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5718,1279 +6129,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Paranda" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Asenda" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Tagasimakse" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Keeldu" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Sügavus" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Osa kategooria" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Osa kategooriad" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ikoon" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ikoon (valikuline)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Osad" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Osa nimi" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "On mall" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Märksõnad" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Osa kategooria" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimaalne laoseis" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Testimalle saab luua ainult testitavate osade jaoks" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Originaalosa" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kopeeri pilt" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Kategooria nimi" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Ehitamine" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kopeeri pilt" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Tarnija info" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Minimaalne hind" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Maksimaalne hind" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Uuenda" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7455,7 @@ msgstr "" msgid "Installed" msgstr "Paigaldatud" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7467,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7499,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7568,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7721,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7765,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7967,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8096,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8121,55 @@ msgstr "" msgid "Options" msgstr "Valikud" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Piirjoon" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8221,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8347,25 @@ msgstr "" msgid "Package Plugin" msgstr "Paki plugin" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Autorit ei leitud" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8590,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Lisa mudelile printimisel" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Salvesta aruande väljund manusega seotud mudeli eksemplari juurde printimisel" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtrid" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Mallifaili" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8775,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8822,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8861,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Seerianumber" @@ -8405,7 +8886,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8919,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Testitulemused" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Tarnija osa number" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9935,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10128,19 @@ msgstr "Kasutajad" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Isiklik info" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Õigused" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Olulised kuupäevad" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10148,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API tunnus" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API tunnused" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Lunnuse nimi" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Kohandatud tunnuse nimi" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Tunnuse aegumise kuupäev" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Viimati nähtud" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Tühistatud" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Vaade" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Muuda" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Kustuta" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Kasutajanimi" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Eesnimi" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Perekonnanimi" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/fa/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/fa/LC_MESSAGES/django.po index 5bda507b9e..322283c92a 100644 --- a/src/backend/InvenTree/locale/fa/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/fa/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Persian\n" "Language: fa_IR\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Address e API peida nashod" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "موارد باید به صورت لیست ارائه شود" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "لیست موارد نامعتبر ارائه شده است" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "تمامی فیلترها باید منحصراً با مقدار true مورد استفاده قرار گیرند" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "هیچ موردی با معیارهای ارائه شده مطابقت ندارد" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "کاربر سطح دسترسی نمایش این مدل را ندارد" @@ -65,150 +69,155 @@ msgstr "تایید آدرس ایمیل" msgid "You must type the same email each time." msgstr "هر بار باید همان ایمیل را تایپ کنید." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "آدرس ایمیل اصلی ارائه شده معتبر نیست." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "دامنه ایمیل ارائه شده تایید نشده است." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "واحد نامعتبر ارائه شده ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "مقداری افزوده نشده" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "نمی‌توان {original} را به {unit} تبدیل کرد" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "مقدار ارائه شده نامعتبر است" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "جزئیات خطا را می توان در پنل مدیریت پیدا کرد" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "تاریخ را وارد کنید" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "مقدار اعشاری نامعتبر است" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "یادداشت" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "مقدار '{name}' در قالب الگو ظاهر قرار نمی گیرد" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "مقدار ارائه شده با الگوی مورد نیاز مطابقت ندارد: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "نمی توان بیش از 1000 مورد را به طور همزمان سریال کرد" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "رشته شماره سریال خالی" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "سریال تکراری" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "گروه نامعتبر: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "محدوده گروه {group} از مقدار مجاز بیشتر است ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "هیچ شماره سریالی پیدا نشد" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "برچسب های HTML را از این مقدار حذف کنید" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "داده ها حاوی محتوای علامت گذاری ممنوع است" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "خطا در اتصال" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "سرور با کد وضعیت نامعتبر پاسخ داد" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "یک استثنا رخ داده است" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "سرور با مقدار طول محتوا نامعتبر پاسخ داد" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "اندازه عکس بسیار بزرگ است" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "حجم دانلود تصویر از حداکثر اندازه بیشتر شده است" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "سرور ریموت پاسخ خالی را برگرداند" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "URL ارائه شده یک فایل تصویری معتبر نیست" @@ -216,159 +225,203 @@ msgstr "URL ارائه شده یک فایل تصویری معتبر نیست" msgid "Log in to the app" msgstr "وارد برنامه شوید" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "ایمیل" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "قبل از انجام هر کار دیگری باید احراز هویت دو مرحله ای را فعال کنید." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "خطا در اجرای تأیید اعتبار افزونه" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "فراداده باید یک شیء دیکت پایتون باشد" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "فراداده افزونه" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "فیلد فراداده JSON، برای استفاده توسط افزونه های خارجی" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "الگوی فرمت نامناسب" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "کلید قالب ناشناخته مشخص شده است" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "کلید قالب مورد نیاز وجود ندارد" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "فیلد مرجع نمی تواند خالی باشد" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "مرجع باید با الگوی مورد نیاز مطابقت داشته باشد" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "شماره مرجع خیلی بزرگ است" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "انتخاب نامعتبر" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "نام" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "توضیحات" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "توضیحات (اختیاری)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "مسیر" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "نام‌های تکراری نمی‌توانند تحت یک والد وجود داشته باشند" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "یادداشت های علامت گذاری (اختیاری)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "داده های بارکد" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "داده های بارکد شخص ثالث" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "هش بارکد" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "هش منحصر به فرد داده های بارکد" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "بارکد موجود پیدا شد" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "خطای سرور" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "یک خطا توسط سرور ثبت شده است." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "باید یک عدد معتبر باشد" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "ارز" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "ارز را از گزینه های موجود انتخاب کنید" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "مقدار نامعتبر" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "عربی" @@ -521,46 +574,48 @@ msgstr "چینی (ساده شده)" msgid "Chinese (Traditional)" msgstr "چینی (سنتی)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "واحد فیزیکی نامعتبر" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "کد ارز معتبر" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "وضعیت سفارش" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "قطعه" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "دسته" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "واگذار شده به من" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "واگذار شده به" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "ایجاد شده قبل از" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "ایجاد شده بعد از" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "دارای تاریخ شروع" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "تاریخ شروع قبل از" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "تاریخ شروع بعد از" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "دارای تاریخ موعد" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "تاریخ موعد قبل از" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "تاریخ موعد بعد از" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "تکمیل شده قبل از" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "تکمیل شده بعد از" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "مصرفی" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "اختیاری" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "مونتاژ" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "سفارش معوق" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "اختصاص داده شده" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "در دسترس" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "سفارش ساخت" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "مکان" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "سفارش‌های ساخت" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "مرجع سفارش فروش" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "منبع محل" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "مقصد" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "تاریخ تکمیل" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "تکمیل شده توسط" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "صادر شده توسط" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "کاربری که این سفارش ساخت را صادر کرده است" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "پیوند خارجی" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "فایل‌های داده" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5718,1279 +6125,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "هیچ عملیات کاربر-محوری، مشخص نشده است" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/fi/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/fi/LC_MESSAGES/django.po index d2c4c54d3a..e4ee79f569 100644 --- a/src/backend/InvenTree/locale/fi/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/fi/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Finnish\n" "Language: fi_FI\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API-rajapintaa ei löydy" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Käyttäjän oikeudet eivät riitä kohteen tarkastelemiseen" @@ -65,150 +69,155 @@ msgstr "Sähköpostiosoitteen vahvistus" msgid "You must type the same email each time." msgstr "Sinun täytyy kirjoittaa sama sähköposti joka kerta." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Annettu ensisijainen sähköpostiosoite ei kelpaa." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Annetun sähköpostiosoitteen verkkotunnusta ei hyväksytä." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Arvoa ei annettu" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Annettu määrä on virheellinen" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Virheen tiedot löytyvät hallintapaneelista" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Anna päivämäärä" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Merkinnät" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Tyhjä sarjanumero" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Duplikaatti sarjanumero" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Sarjanumeroita ei löytynyt" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Yhteysvirhe" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Palvelin vastasi virheellisellä tilakoodilla" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Kuva on liian iso" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Kuvan lataus ylitti enimmäiskoon" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Etäpalvelin palautti tyhjän vastauksen" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Annettu URL ei ole kelvollinen kuvatiedosto" @@ -216,159 +225,203 @@ msgstr "Annettu URL ei ole kelvollinen kuvatiedosto" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Sähköposti" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metatietojen tulee olla python dict objekti" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Liitännäisen metadata" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON metadatakenttä, ulkoisten liitännäisten käyttöön" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Virheellisesti muotoiltu malli" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Viitekenttä ei voi olla tyhjä" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Viitenumero on liian suuri" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Virheellinen valinta" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nimi" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Kuvaus" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Kuvaus (valinnainen)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Polku" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Viivakoodin Tiedot" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Palvelinvirhe" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Kuva" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Täytyy olla kelvollinen luku" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuutta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Valitse valuutta käytettävissä olevista vaihtoehdoista" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Virheellinen arvo" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Osa" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategoria" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Saatavilla" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Sijainti" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Ulkoinen linkki" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Linkki ulkoiseen URLiin" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Määrä" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Varastotuote" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Sarjanumerot" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Ei sallittu" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Seurattavissa" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Odottaa" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Peruttu" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Valmis" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Päivitetty" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Viimeisimmän päivityksen aikaleima" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Käyttäjä" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Hinta" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktiivinen" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Käyttäjä" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Hinta" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Salaisuus" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Isäntä" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Otsikko" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Linkki" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Julkaistu" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Julkaisija" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Yhteenveto" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Kuvatiedosto" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Liite" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Puuttuva tiedosto" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Puuttuva ulkoinen linkki" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Valitse liitettävä tiedosto" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Kommentti" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Arvo" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Käytössä" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Muistiinpano" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Avain" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Tiedostonimi" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "Ei ryhmää" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "päivää" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponentti" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Ostettavissa" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Sisäiset hinnat" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Sisäisen hinnan ohitus" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "Sivun koko" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" -msgstr "" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" +msgstr "Sivun koko" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Salli salasananpalautus" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Salli rekisteröinti" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Salli SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "Salli SSO kirjautumissivuilla" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "Salli SSO rekisteröinti" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "Sähköposti vaaditaan" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Salli salasananpalautus" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Salli rekisteröinti" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "Salli SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "Salli SSO kirjautumissivuilla" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "Salli SSO rekisteröinti" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "" + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 +msgid "Email required" +msgstr "Sähköposti vaaditaan" + +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" +msgstr "" + +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Sähköpostiosoite kahdesti" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Salasana kahdesti" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Sallitut verkkotunnukset" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Pakota MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "" -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Verkkotunnus ei saa olla tyhjä." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Virheellinen verkkotunnus: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Valmistaja" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Yritys" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontakti" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Osoite" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Valitse valmistaja" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Valmistajan osanumero" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Toimittaja" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Valitse toimittaja" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Toimittajan varastonimike" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Valitse valmistajan osa" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Datatiedosto" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Ryhmä" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Valmis" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Hinta yhteensä" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Tilauksen valuutta" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Tilauksen viite" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Tila" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Asiakas" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Asiakkaan viite " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Vastaanotettu" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Lähetetty" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Seurantakoodi" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Laskunumero" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Viivakoodi" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Kadonnut" @@ -5718,1279 +6125,1312 @@ msgstr "Kadonnut" msgid "Returned" msgstr "Palautettu" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Kesken" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Oletus avainsanat" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Kuvake" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Kuvake (valinnainen)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Avainsanat" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Päivämäärä" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Valmistajan osanumero" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Avaa linkki" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Suodattimet" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Leveys [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Korkeus [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Osan kuva" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Sarjanumero" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "Käyttäjät" msgid "Select which users are assigned to this group" msgstr "Valitse mitkä käyttäjät on määritetty tähän ryhmään" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Henkilökohtaiset tiedot" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Oikeudet" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Näytä" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Oikeus tarkastella kohteita" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Oikeus lisätä kohteita" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Muuta" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Oikeus muokata kohteita" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Poista" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Oikeus poistaa kohteita" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Käyttäjätunnus" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Etunimi" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Sukunimi" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/fr/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/fr/LC_MESSAGES/django.po index 55d8b2aaf4..b5aaf06ac5 100644 --- a/src/backend/InvenTree/locale/fr/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/fr/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Point de terminaison de l'API introuvable" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Les éléments doivent être fournis sous forme de liste" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Liste d'éléments non valide fournie" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Tous les filtres ne doivent être utilisés qu'avec \"true\"" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Aucun élément ne correspond aux critères fournis" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Aucune donnée disponible" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Ce champ doit être unique" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "L'utilisateur n'a pas la permission de voir ce modèle" @@ -65,150 +69,155 @@ msgstr "Confirmation de l'adresse email" msgid "You must type the same email each time." msgstr "Vous devez taper le même e-mail à chaque fois." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "L'adresse e-mail principale fournie n'est pas valide." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Le domaine e-mail fourni n'est pas approuvé." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Unité fournie invalide ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Pas de valeur renseignée" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Impossible de convertir {original} en {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Quantité fournie invalide" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Les détails de l'erreur peuvent être trouvées dans le panneau d'administration" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Entrer la date" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Valeur décimale invalide" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Notes" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "La valeur '{name}' n'apparaît pas dans le format du modèle" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "La valeur fournie ne correspond pas au modèle requis : " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Impossible de sérialiser plus de 1000 éléments à la fois" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Chaîne de numéro de série vide" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Numéro de série en doublon" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Groupe invalide : {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "La plage de groupe {group} dépasse la quantité autorisée ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Aucun numéro de série trouvé" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Le nombre de numéros de série uniques ({n}) doit correspondre à la quantité ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Retirer les balises HTML de cette valeur" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Les données contiennent du contenu markdown interdit" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Erreur de connexion" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Le serveur a répondu avec un code de statut invalide" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Une erreur est survenue" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Le serveur a répondu avec une valeur de longueur de contenu invalide" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Image trop volumineuse" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "La taille de l'image dépasse la taille maximale autorisée" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Le serveur distant a renvoyé une réponse vide" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "L'URL fournie n'est pas un fichier image valide" @@ -216,159 +225,203 @@ msgstr "L'URL fournie n'est pas un fichier image valide" msgid "Log in to the app" msgstr "Se connecter à l'application" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Vous devez activer l'authentification à deux facteurs avant toute autre chose." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Erreur lors de l'exécution de la validation du plugin" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Les metadata doivent être un objet python de type \"dict\"" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Métadonnées de l'Extension" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Champs metadata JSON, pour plugins tiers" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Modèle mal formaté" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Clé de format inconnu spécifiée" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Clé de format requise manquante" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Le champ de référence ne peut pas être vide" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "La référence doit correspondre au modèle requis" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Le numéro de référence est trop grand" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Choix invalide" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nom" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Description" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Description (facultative)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Chemin d'accès" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Les noms dupliqués ne peuvent pas exister sous le même parent" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Notes Markdown (option)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Données du code-barres" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Données de code-barres tierces" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash du code-barre" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hachage unique des données du code-barres" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Code-barres existant trouvé" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Erreur serveur" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Une erreur a été loguée par le serveur." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Image" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Doit être un nombre valide" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Devise" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Sélectionnez la devise à partir des options disponibles" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Ce champ ne peut pas être vide." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Valeur non valide" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Format du type de contenu invalide" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Type de contenu introuvable" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "Le type de contenu ne correspond pas à la classe de mixin requise" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Copier les paramètres" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Copier des lignes" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Copier les postes de l'ordre original" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Copier les lignes supplémentaires" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Copier les postes supplémentaires de l'ordre original" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabe" @@ -521,46 +574,48 @@ msgstr "Chinois (Simplifié)" msgid "Chinese (Traditional)" msgstr "Chinois (Traditionnel)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Mise à jour disponible" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Une mise à jour pour InvenTree est disponible" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Unité invalide" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Code de devise invalide" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Statut de la commande" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Fabrication parente" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Inclure les variantes" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Inclure les variantes" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Inclure les variantes" msgid "Part" msgstr "Pièce" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Catégorie" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Version Précédente" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Attribué à moi" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Attribué à" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Créé avant" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Créé après" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "A une date de début" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Date de début avant" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Date de début après" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "A une date butoir" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Date cible avant" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Date cible après" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Terminé avant" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Terminé après" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Date min" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Date maximale" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Exclure l'arbre" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "La construction doit être annulée avant de pouvoir être supprimée" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Consommable" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Facultatif" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Assemblage" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Suivi" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testable" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Commande en cours" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Allouée" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Consommé" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Disponible" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "En Commande" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Ordre de Fabrication" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Emplacement" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Sortie" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Filtrer par l'identifiant (ID) des articles du stock de sortie. Utilisez 'null' pour trouver les éléments de fabrication non installés." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Ordres de Fabrication" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "La liste des composants de l'assemblage n'a pas été validée" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Impossible de créer un ordre de fabrication pour une pièce inactive" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Impossible de créer un ordre de fabrication pour une pièce non verrouillée" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Les ordres de fabrication ne peuvent être exécutées qu'en externe pour les pièces achetables" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Un utilisateur ou un groupe responsable doit être spécifié" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "La pièce de commande de construction ne peut pas être changée" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "La date cible doit être postérieure à la date de début" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Référence de l' Ordre de Fabrication" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Référence" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Brève description de la fabrication (optionnel)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Commande de fabrication associée à cette fabrication" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Sélectionnez la pièce à construire" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Bon de commande de référence" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Commande de vente à laquelle cette fabrication est allouée" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Emplacement d'origine" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Sélectionner l'emplacement à partir duquel le stock doit être pris pour cette construction (laisser vide pour prendre à partir de n'importe quel emplacement de stock)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Fabrication externe" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Cet ordre de fabrication est exécuté en externe" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Emplacement cible" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Sélectionnez l'emplacement où les éléments complétés seront stockés" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Quantité a fabriquer" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Nombre de stock items à construire" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Articles terminés" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Nombre d'articles de stock qui ont été terminés" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "État de la construction" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Code de statut de construction" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Code de lot" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Code de lot pour ce build output" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Date de création" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Début de la fabrication" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Date de début prévue pour cet ordre de construction" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Date d'achèvement cible" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Date cible pour l'achèvement de la construction. La construction sera en retard après cette date." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Date d'achèvement" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "achevé par" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Émis par" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Utilisateur ayant émis cette commande de construction" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsable" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Utilisateur ou groupe responsable de cet ordre de construction" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Lien Externe" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Lien vers une url externe" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Priorité de fabrication" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Priorité de cet ordre de fabrication" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Code du projet" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Code de projet pour cet ordre de construction" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Impossible de terminer l'ordre de fabrication avec des constructions enfant ouvertes" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Impossible de terminer l'ordre de fabrication avec des sorties incomplètes" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Échec du déchargement de la tâche pour terminer les allocations de construction" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "La commande de construction {build} a été effectuée" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Une commande de construction a été effectuée" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Les numéros de série doivent être fournis pour les pièces traçables" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Pas d'ordre de production défini" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "L'ordre de production a déjà été réalisé" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "L'ordre de production de correspond pas à l'ordre de commande" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "La quantité doit être supérieure à zéro" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "La quantité ne peut pas être supérieure à la quantité de sortie" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "Les sorties de fabrication n'ont pas passé tous les tests requis" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "La sortie de compilation {serial} n'a pas réussi tous les tests requis" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "Les articles en stock alloués sont toujours en production" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Impossible de compléter partiellement une sortie de construction avec les éléments alloués" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Quantité disponible ({q}) dépassée" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Poste de l'ordre de construction" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Création de l'objet" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Création de l'objet" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantité" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Quantité requise pour la commande de construction" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Quantité de stock consommé" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "L'élément de construction doit spécifier une sortie de construction, la pièce maîtresse étant marquée comme objet traçable" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "L'article de stock sélectionné ne correspond pas à la ligne BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "La quantité allouée doit être supérieure à zéro" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "La quantité doit être de 1 pour stock sérialisé" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "La quantité allouée ({q}) ne doit pas excéder la quantité disponible ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "L'article de stock est suralloué" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Article en stock" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Stock d'origine de l'article" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Quantité de stock à allouer à la construction" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Installer dans" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Stock de destination de l'article" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Niveau de construction" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Nom de l'article" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Sortie d'assemblage" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "L'ordre de production ne correspond pas à l'ordre parent" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "La pièce en sortie ne correspond pas à la pièce de l'ordre de construction" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Cet ordre de production a déjà été produit" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Cet ordre de production n'est pas complètement attribué" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Entrer la quantité désiré pour la fabrication" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Quantité entière requise pour les pièces à suivre" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Quantité entière requise, car la facture de matériaux contient des pièces à puce" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Numéros de série" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Entrer les numéros de séries pour la fabrication" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Emplacement de stock pour la sortie de la fabrication" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Allouer automatiquement les numéros de série" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Affecter automatiquement les éléments requis avec les numéros de série correspondants" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Les numéros de série suivants existent déjà, ou sont invalides" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Une liste d'ordre de production doit être fourni" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Emplacement du stock pour les sorties épuisées" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Ignorer les allocations" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Abandonner les allocations de stock pour les sorties abandonnées" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Motif de l'élimination des produits de construction(s)" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Emplacement des ordres de production achevés" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Accepter l'allocation incomplète" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Compléter les sorties si le stock n'a pas été entièrement alloué" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Consommation du stock alloué" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Consommer tout stock qui a déjà été alloué à cette construction" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Retirer les sorties incomplètes" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Supprimer toutes les sorties de construction qui n'ont pas été complétées" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Non permis" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Accepter comme consommé par cet ordre de construction" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Désaffecter avant de terminer cette commande de fabrication" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Stock suralloué" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Comment voulez-vous gérer les articles en stock supplémentaires assignés à l'ordre de construction" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Certains articles de stock ont été suralloués" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Accepter les non-alloués" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Accepter les articles de stock qui n'ont pas été complètement alloués à cette ordre de production" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Le stock requis n'a pas encore été totalement alloué" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Accepter les incomplèts" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Accepter que tous les ordres de production n'aient pas encore été achevés" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "La quantité nécessaire n'a pas encore été complétée" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "L'ordre de construction a des ordres de construction enfants ouverts" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "L'ordre de construction doit être en état de production" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "L'ordre de production a des sorties incomplètes" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Chaîne d'assemblage" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Sortie d'assemblage" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "La sortie de la construction doit pointer vers la même construction" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Élément de la ligne de construction" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part doit pointer sur la même pièce que l'ordre de construction" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "L'article doit être en stock" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Quantité disponible ({q}) dépassée" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "La sortie de construction doit être spécifiée pour l'allocation des pièces suivies" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "La sortie de la construction ne peut pas être spécifiée pour l'allocation des pièces non suivies" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Les articles d'allocation doivent être fournis" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Emplacement de stock où les pièces doivent être fournies (laissez vide pour les prendre à partir de n'importe quel emplacement)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Emplacements exclus" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Exclure les articles de stock de cet emplacement sélectionné" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Stock interchangeable" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Les articles de stock à plusieurs emplacements peuvent être utilisés de manière interchangeable" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Stock de substitution" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Autoriser l'allocation de pièces de remplacement" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Objets Optionnels" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Affecter des éléments de nomenclature facultatifs à l'ordre de fabrication" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Référence de la nomenclature" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID de la pièce de la nomenclature" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Nomenclature Nom de la pièce" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Construire" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Pièce fournisseur" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Quantité allouée" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Référence de construction" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Nom de la catégorie de pièces" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Traçable" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Reçu de quelqu'un" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Autoriser les variantes" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Article du BOM" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "En Production" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Planifié pour fabrication" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Stock externe" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Stock disponible" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Stock de substitution disponible" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Stock de variantes disponibles" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "La quantité consommée dépasse la quantité allouée" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Note optionnelle pour la consommation du stock" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "L'article fabriqué doit pointer vers l'ordre de fabrication correct" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Dupliquer l'allocation de l'article de fabrication" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "L'article fabriqué doit pointer vers l'ordre de fabrication correct" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Dupliquer l'allocation de ligne de fabrication" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Au moins un élément ou une ligne doit être fourni" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "En attente" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Fabrication" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "En pause" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Annulé" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Terminé" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "La commande de construction {build} a été effectuée" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Une commande de construction a été effectuée" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Stock requis pour la commande de construction" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "L'ordre de fabrication {build} nécessite du stock additionnel" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Ordre de commande en retard" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "L'ordre de commande {bo} est maintenant en retard" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "C'est un lien" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "C'est un fichier" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "L'utilisateur n'a pas les permissions de supprimer cette pièce jointe" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "La liste de sélection est verrouillée" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Code de devise invalide" @@ -1539,15 +1641,20 @@ msgstr "Aucun code de devise valide fourni" msgid "No plugin" msgstr "Pas de plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Code du projet Étiquette" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Mise à jour" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Date de la dernière mise à jour" @@ -1567,794 +1674,844 @@ msgstr "Code projet unique" msgid "Project description" msgstr "Description du projet" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Utilisateur ou groupe responsable de ce projet" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Paramétrés des touches" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Valeur du paramètre" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "La valeur choisie n'est pas une option valide" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "La valeur doit être une valeur booléenne" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "La valeur doit être un nombre entier" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Valeur doit être un nombre valide" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "La valeur ne passe pas les contrôles de validation" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "La chaîne de caractères constituant la clé doit être unique" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Utilisateur" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Quantité de rupture de prix" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Prix" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Prix unitaire à la quantité spécifiée" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Point final" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Point de terminaison auquel ce webhook est reçu" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Nom de ce webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Actif" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Utilisateur ou groupe responsable de ce projet" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Paramétrés des touches" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Valeur du paramètre" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "La valeur choisie n'est pas une option valide" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "La valeur doit être une valeur booléenne" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "La valeur doit être un nombre entier" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Valeur doit être un nombre valide" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "La valeur ne passe pas les contrôles de validation" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "La chaîne de caractères constituant la clé doit être unique" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Utilisateur" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Quantité de rupture de prix" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Prix" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Prix unitaire à la quantité spécifiée" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Point final" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Point de terminaison auquel ce webhook est reçu" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Nom de ce webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Ce webhook (lien de rappel HTTP) est-il actif" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Jeton" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Jeton d'accès" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Confidentiel" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Secret partagé pour HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID message" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Identifiant unique pour ce message" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Hôte" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Hôte à partir duquel ce message a été reçu" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Entête" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "En-tête de ce message" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Corps" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Corps de ce message" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Endpoint à partir duquel ce message a été reçu" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Travaillé sur" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Le travail sur ce message est-il terminé ?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Titre" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Lien" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publié" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Auteur" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Résumé" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Lu" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Cette nouvelle a-t-elle été lue ?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Fichier image" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Type de modèle cible pour cette image" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "ID du modèle cible pour cette image" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Unité personnalisée" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Le symbole de l'unité doit être unique" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Le nom de l'unité doit être un identifiant valide" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Nom de l'unité" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbole" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Symbole d'unité facultatif" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Définition" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Définition de l'unité" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Pièce jointe" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Fichier manquant" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Lien externe manquant" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Type de modèle" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Type de modèle cible pour l'image" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Sélectionnez un fichier à joindre" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Commentaire" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Commentaire sur la pièce jointe" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Date de téléchargement" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Date de téléchargement du fichier" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Taille du fichier" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Taille du fichier en octets" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Type de modèle non valide spécifié pour la pièce jointe" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "État personnalisé" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "États membres de l'Union européenne" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Ensemble d'états de référence" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Ensemble d'états étendu à cet état personnalisé" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Clé logique" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Clé logique de l'état qui est égale à cet état personnalisé dans la logique métier" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Valeur" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Valeur numérique qui sera enregistrée dans la base de données des modèles" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Nom de l'Etat" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Étiquette" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Etiquette qui sera affichée dans le frontend" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Couleur" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Couleur qui sera affichée dans le frontend" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Modèle" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Modèle cet état est associé à" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Le modèle doit être sélectionné" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "La clé doit être sélectionnée" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "La clé logique doit être sélectionnée" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "La clé doit être différente de la clé logique" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Une classe de statut de référence valide doit être fournie" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "La clé doit être différente des clés logiques de l'état de référence" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "La clé logique doit se trouver dans les clés logiques de l'état de référence" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Le nom doit être différent des noms des statuts de référence" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Liste de sélection" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Listes de sélection" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Nom de la liste de sélection" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Description de la liste de sélection" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Verrouillé" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Cette liste de sélection est-elle verrouillée ?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Cette liste de sélection peut-elle être utilisée ?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Plug-in source" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Plugin qui fournit la liste de sélection" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Chaîne source" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Chaîne facultative identifiant la source utilisée pour cette liste" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Entrée par défaut" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Entrée par défaut pour cette liste de sélection" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Créé le" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Date et heure de création de la liste de sélection" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Dernière mise à jour" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Date et heure de la dernière mise à jour de la liste de sélection" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Entrée de la liste de sélection" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Entrées de la liste de sélection" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Liste de sélection à laquelle appartient cette entrée" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Valeur de l'entrée de la liste de sélection" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Étiquette pour l'entrée de la liste de sélection" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Description de l'entrée de la liste de sélection" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Cette entrée de la liste de sélection est-elle active ?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Modèle de paramètre" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "Modèle de paramètre" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Les paramètres des cases à cocher ne peuvent pas avoir d'unités" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Les paramètres des cases à cocher ne peuvent pas comporter de choix" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Les choix doivent être uniques" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Le nom du modèle de paramètre doit être unique" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "Type de modèle cible pour ce modèle de paramètre" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Nom du paramètre" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Unités" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Unités physiques pour ce paramètre" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Description des paramètres" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Case à cocher" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Ce paramètre est-il une case à cocher ?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Choix" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Choix valables pour ce paramètre (séparés par des virgules)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Liste de sélection pour ce paramètre" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Activé" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "Ce modèle de paramètre est-il activé ?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "Paramètre" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "Paramètres" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Choix incorrect pour la valeur du paramètre" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "Type de modèle non valide pour la pièce jointe" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "Identifiant du Modèle (ID)" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "ID du modèle cible pour ce paramètre" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Modèle" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "Modèle de paramètre" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Données" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Valeur du paramètre" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Note" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Champ de notes facultatif" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Analyse du code-barres" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Données du code-barres" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Utilisateur qui a scanné le code-barres" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Horodatage" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Date et heure du scan de code-barres" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Point d'accès à l'URL qui a traité le code-barres" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Contexte" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Données contextuelles pour la lecture du code-barres" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Réponse" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Données de réponse provenant de la lecture du code-barres" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Résultat" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "La lecture du code-barres a-t-elle réussi ?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Une erreur s'est produite" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8 : La suppression du journal d'e-mail est protégée. Définissez INVENTREE_PROTECT_EMAIL_LOG à False pour permettre la suppression." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "Message email" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "Messages email" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Annoncé" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Envoyé" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Échec" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Livré" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Confirmé" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Entrant" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Sortant" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Sans réponse" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Suivi de livraison" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Suivi de la lecture" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Suivi du clic" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "ID Global" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Identifiant pour ce message (peut être fourni par un système externe)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "ID du sujet de discussion" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Identifiant pour ce fil de message (peut être fourni par un système externe)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Fil de discussion" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Fil lié à ce message" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "Priorité" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "Fil d'Email" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "Fils d'Emails" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Clé" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Clé unique pour ce fil (utilisée pour identifier le fil)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Identifiant unique pour ce fil" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Démarré en interne" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Est-ce que ce fil a été démarré en interne ?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Date et heure de création du fil" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Date et heure de dernière mise à jour du fil" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} annulé" msgid "A order that is assigned to you was canceled" msgstr "Une commande qui vous est assignée a été annulée" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Articles reçus" @@ -2388,104 +2545,100 @@ msgstr "Des articles d'un bon de commande ont été reçus" msgid "Items have been received against a return order" msgstr "Les articles ont été reçus dans le cadre d'un ordre de retour" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "Indique si la modification de ce paramètre nécessite une confirmation" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "Ce paramètre nécessite une confirmation avant les changements. Veuillez confirmer." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Indique si le paramètre est écrasé par une variable d'environnement" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Écraser" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "En cours d'exécution" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Tâches en attente" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Tâches planifiées" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Tâches échouées" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID de la tâche" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "ID unique de la tâche" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Verrouillé" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Heure verrouillé" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Nom de la tâche" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Fonction" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nom de la fonction" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Arguments" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Arguments tâche" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Mots-clés Arguments" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Mots-clés arguments tâche" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nom du fichier" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Type de modèle" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "L'utilisateur n'a pas le droit de créer ou de modifier des pièces jointes pour ce modèle" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "L'utilisateur n'a pas le droit de créer ou de modifier les paramètres de ce modèle." -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "La liste de sélection est verrouillée" - #: common/setting/system.py:97 msgid "No group" msgstr "Pas de groupe" @@ -2614,13 +2767,13 @@ msgstr "Intervalle de mise à jour des devises" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Fréquence de mise à jour des taux de change (définir à zéro pour désactiver)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "jours" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Plugin de mise à jour des devises à utiliser" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validation stricte d'URL" @@ -2760,947 +2921,1017 @@ msgstr "Plugin de génération de codes-barres" msgid "Plugin to use for internal barcode data generation" msgstr "Plugin à utiliser pour la génération interne de données de code-barres" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Modifications de la pièce" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Activer le champ de modification de la pièce" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Révision de l'assemblage uniquement" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "N'autoriser les révisions que pour les pièces d'assemblage" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Autoriser la suppression de l'Assemblée" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Permettre la suppression de pièces utilisées dans un assemblage" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Expression régulière pour la correspondance avec l'IPN de la Pièce" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Autoriser les IPN dupliqués" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Permettre à plusieurs pièces de partager le même IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Autoriser l'édition de l'IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Permettre de modifier la valeur de l'IPN lors de l'édition d'une pièce" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Copier les données de la pièce" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Copier les données des paramètres par défaut lors de la duplication d'une pièce" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Copier les données des paramètres de la pièce" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Copier les données des paramètres par défaut lors de la duplication d'une pièce" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Copier les données de test de la pièce" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Copier les données de test par défaut lors de la duplication d'une pièce" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Copier les templates de paramètres de catégorie" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Copier les templates de paramètres de la catégorie lors de la création d'une pièce" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Les pièces sont des templates par défaut" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Les pièces peuvent être assemblées à partir d'autres composants par défaut" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Composant" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Les pièces peuvent être utilisées comme sous-composants par défaut" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Achetable" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Les pièces sont achetables par défaut" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Vendable" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Les pièces sont vendables par défaut" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Les pièces sont traçables par défaut" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuelle" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Les pièces sont virtuelles par défaut" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Afficher les pièces connexes" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Afficher les pièces connexes à une pièce" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Stock initial" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Permettre la création d'un stock initial lors de l'ajout d'une nouvelle pièce" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Données initiales du fournisseur" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Permettre la création des données initiales du fournisseur lors de l'ajout d'une nouvelle pièce" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Format d'affichage du nom de la pièce" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Format pour afficher le nom de la pièce" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Icône de catégorie par défaut" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Icône par défaut de la catégorie de la pièce (vide signifie aucune icône)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Nombre minimal de décimales" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Nombre minimum de décimales à afficher lors de l'affichage des prix" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Nombre maximal de décimales pour la tarification" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Nombre maximal de décimales à afficher lors du rendu des données de tarification" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Utiliser le prix fournisseur" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Inclure les réductions de prix dans le calcul du prix global" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Remplacer l'historique des achats" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "La tarification historique des bons de commande remplace les réductions de prix des fournisseurs" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Utiliser les prix des articles en stock" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Utiliser les prix des données de stock saisies manuellement pour calculer les prix" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Âge de tarification des articles de stock" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Exclure les articles en stock datant de plus de ce nombre de jours des calculs de prix" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Utiliser les prix variants" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Inclure la tarification variante dans le calcul global des prix" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Variantes actives uniquement" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "N'utiliser que des pièces de variante actives pour calculer le prix de la variante" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Mise à jour automatique des prix" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Mettre à jour automatiquement les prix des pièces quand les données internes changes" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Intervalle de regénération des prix" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Nombre de jours avant la mise à jour automatique du prix de la pièce" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Prix internes" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Activer les prix internes pour les pièces" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Substitution du prix interne" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Si disponible, les prix internes remplacent les calculs de la fourchette de prix" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Activer l'impression d'étiquettes" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Activer l'impression d'étiquettes depuis l'interface Web" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Étiquette image DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Résolution DPI lors de la génération de fichiers image pour fournir aux plugins d'impression d'étiquettes" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Activer les rapports" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Activer la génération de rapports" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Mode Débogage" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Générer des rapports en mode debug (sortie HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Journal des erreurs" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Enregistrer les erreurs qui se produisent lors de la génération de rapports" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Taille de la page" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Taille de page par défaut pour les rapports PDF" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Renforcer les unités des paramètres" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Si des unités sont fournies, les valeurs de paramètre doivent correspondre aux unités spécifiées" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Numéro de Série Universellement Unique" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Les numéros de série pour les articles en stock doivent être uniques au niveau global" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Supprimer le stock épuisé" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Détermine le comportement par défaut lorsqu'un article de stock est épuisé" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Modèle de code de lot" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Modèle pour générer des codes par défaut pour les articles en stock" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Expiration du stock" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Activer la fonctionnalité d'expiration du stock" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Vendre le stock expiré" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Autoriser la vente de stock expiré" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Délai de péremption du stock" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Nombre de jours pendant lesquels les articles en stock sont considérés comme périmés avant d'expirer" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Construction de stock expirée" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Autoriser la construction avec un stock expiré" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Contrôle de la propriété des stocks" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Activer le contrôle de la propriété sur les emplacements de stock et les articles" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Icône par défaut de l'emplacement du stock" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Icône par défaut de l'emplacement du stock (vide signifie aucune icône)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Afficher les pièces en stock installées" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Affichage des articles en stock installés dans les tableaux de stock" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Vérifier la nomenclature lors de l'installation des articles" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Les articles de stock installés doivent exister dans la nomenclature de la pièce mère" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Autoriser le transfert des produits en rupture de stock" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Permettre le transfert d'articles qui ne sont pas en stock d'un magasin à l'autre" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Modèle de référence de commande de construction" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Modèle requis pour générer le champ de référence de l'ordre de construction" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Nécessite un Responsable propriétaire" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Un propriétaire responsable doit être assigné à chaque commande" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Exiger une partie active" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Empêcher la création d'un ordre de fabrication pour les pièces inactives" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Requiert une pièce verrouillée" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Empêcher la création d'un ordre de fabrication pour les pièces non verrouillées" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Exiger une nomenclature valide" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Empêcher la création d'un ordre de fabrication si la nomenclature n'a pas été validée" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Exiger des ordonnances fermées pour les enfants" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Empêcher l'achèvement de l'ordre de construction jusqu'à ce que tous les ordres d'enfants soient clôturés" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Ordres de fabrication externes" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Activer la fonctionnalité d'ordre de fabrication externe" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blocage jusqu'à la réussite des tests" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Empêcher l'achèvement des résultats de la construction jusqu'à ce que tous les tests requis soient réussis" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Activer les retours de commandes" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Activer la fonctionnalité de retour de commande dans l'interface utilisateur" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Modèle de référence de retour de commande" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Modèle requis pour générer le champ de référence de la commande de retour" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Modifier les retours de commandes terminées" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Autoriser la modification des retours après leur enregistrement" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Modèle de référence de bon de commande" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Modèle requis pour générer le champ de référence du bon de commande" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Expédition par défaut du bon de commande" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Activer la création d'expédition par défaut avec les bons de commandes" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Modifier les commandes de vente terminées" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Autoriser la modification des commandes de vente après avoir été expédiées ou complétées" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "L'expédition nécessite une vérification" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Empêcher l'achèvement des envois jusqu'à ce que les articles aient été vérifiés" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Marquer les commandes expédiées comme achevées" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Les commandes marquées comme expédiées seront automatiquement complétées, en contournant le statut « expédié »" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Modèle de référence de commande d'achat" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Modèle requis pour générer le champ de référence de bon de commande" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Modifier les bons de commande terminés" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Autoriser la modification des bons de commande après avoir été expédiés ou complétés" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Convertir la monnaie" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Convertir la valeur de l'article dans la devise de base lors de la réception du stock" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Achat automatique des commandes" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Marquer automatiquement les bons de commande comme terminés lorsque tous les articles de la ligne sont reçus" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Activer les mots de passe oubliés" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Activer la fonction \"Mot de passe oublié\" sur les pages de connexion" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Activer les inscriptions" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Activer l'auto-inscription pour les utilisateurs sur les pages de connexion" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "Activer le SSO" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Activer le SSO sur les pages de connexion" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Activer l'inscription SSO" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Activer l'auto-inscription via SSO pour les utilisateurs sur les pages de connexion" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Activer la synchronisation du groupe SSO" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Permettre la synchronisation des groupes InvenTree avec les groupes fournis par l'IdP" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "Clé du groupe SSO" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Le nom de l'attribut de revendication de groupe fourni par l'IdP" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "Carte de groupe SSO" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Une correspondance entre les groupes SSO et les groupes InvenTree locaux. Si le groupe local n'existe pas, il sera créé." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Supprimer les groupes en dehors de SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Indique si les groupes attribués à l'utilisateur doivent être supprimés s'ils ne sont pas gérés par l'IdP. La désactivation de ce paramètre peut entraîner des problèmes de sécurité" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email requis" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Exiger que l'utilisateur fournisse un mail lors de l'inscription" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Saisie automatique des utilisateurs SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Remplir automatiquement les détails de l'utilisateur à partir des données de compte SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Courriel en double" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Lors de l'inscription, demandez deux fois aux utilisateurs leur mail" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Mot de passe deux fois" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Lors de l'inscription, demandez deux fois aux utilisateurs leur mot de passe" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Domaines autorisés" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Restreindre l'inscription à certains domaines (séparés par des virgules, commençant par @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grouper sur inscription" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Groupe auquel les nouveaux utilisateurs sont assignés lors de l'enregistrement. Si la synchronisation des groupes SSO est activée, ce groupe n'est défini que si aucun groupe ne peut être attribué par l'IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Forcer l'authentification multifacteurs" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Les utilisateurs doivent utiliser l'authentification multifacteurs." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "Activer ce paramètre demandera à tous les utilisateurs de configurer l'authentification multi-facteurs. Toutes les sessions seront déconnectées immédiatement." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Vérifier les plugins au démarrage" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Vérifier que tous les plugins sont installés au démarrage - activer dans les environnements conteneurs" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Vérifier les mises à jour des plugins" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Activer les vérifications périodiques pour les mises à jour des plugins installés" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Activer l'intégration d'URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Autoriser les plugins à ajouter des chemins URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Activer l'intégration de navigation" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Activer les plugins à s'intégrer dans la navigation" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Activer l'intégration de plugins" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Activer l'intégration de plugin pour ajouter des apps" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Activer l'intégration du planning" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Autoriser les plugins à éxécuter des tâches planifiées" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Activer l'intégration des évènements" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Autoriser les plugins à répondre aux évènements internes" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Permettre l'intégration de l'interface" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Permettre aux plugins de s'intégrer dans l'interface utilisateur" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Activer l'intégration mail" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Autoriser les plugins à traiter les mails entrants/sortants" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Activer les codes de projet" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Activer les codes de projet pour le suivi des projets" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Activer la fonctionnalité d'enregistrement des historiques de niveaux de stock et de leur valeur" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Exclure les localisations externes" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Période de l'inventaire automatique" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Afficher les noms des utilisateurs" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Afficher les noms complets des utilisateurs au lieu des noms d'utilisateur" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Afficher les profils d'utilisateur" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Afficher les profils des utilisateurs sur leur page de profil" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Activer les données de station de test" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Activer la collecte des données de la station de test pour les résultats de test" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Nombre de résultats à afficher dans chaque section de la fenêtre de prévisualisation de recherche" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Recherche Regex" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Activer les expressions régulières dans les requêtes de recherche" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Recherche de mot complet" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Les requêtes de recherche renvoient des résultats pour des mots entiers" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Notes de recherche" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Les requêtes de recherche renvoient les résultats correspondant aux notes de l'article" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "La touche Echap ferme les formulaires" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Utilisez la touche Echap pour fermer les formulaires modaux" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Barre de navigation fixe" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "La position de la barre de navigation est fixée en haut de l'écran" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "En-têtes de tableau fixes" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Les en-têtes de table sont fixes au-dessus du tableau" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Afficher Spotlight" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Activer la fonctionnalité de navigation spotlight" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Icônes de navigation" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Afficher les icônes dans la barre de navigation" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Format de date" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Format préféré pour l'affichage des dates" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Voir l'historique du stock" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Voir l'historique du stock dans la page de détails de la pièce" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Afficher le dernier fil d'Ariane" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Afficher la page actuelle dans les fils d'Ariane" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Voir l'emplacement complet du stock dans les tableaux" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Désactivé : Le chemin complet de l'emplacement est affiché sous la forme d'une infobulle survolée. Activé : Le chemin de l'emplacement complet est affiché en texte brut." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Voir les catégories complètes des pièces dans les tableaux" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Désactivé : Le chemin de la catégorie complète est affiché comme un info-bulle de survol. Activé : Le chemin de la catégorie complète est affiché en texte brut." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Recevoir des rapports d'erreur" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Recevoir des notifications en cas d'erreurs du système" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Dernières machines d'impression utilisées" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Sauvegarder les dernières machines d'impression utilisées par un utilisateur" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Tous les modèles" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Aucun type de modèle d'attachement n'est fourni" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Type de modèle de pièce jointe non valide" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Les places minimales ne peuvent être supérieures aux places maximales" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Le nombre maximum de places ne peut être inférieur au nombre minimum de places" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Un domaine vide n'est pas autorisé." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Nom de domaine invalide : {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "La valeur doit être en majuscules" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "La valeur doit être un identifiant de variable valide" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "La pièce est active" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Le fabricant est actif" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Le fournisseur de la pièce est active" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "La pièce interne est active" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Le fournisseur est actif" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Fabricant" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Société" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "A du stock" @@ -4123,8 +4387,8 @@ msgstr "Numéro de téléphone de contact" msgid "Contact email address" msgstr "Adresse e-mail de contact" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Contact" @@ -4176,283 +4440,283 @@ msgstr "N° de TVA" msgid "Company Tax ID" msgstr "Numéro d'identification fiscale de l'entreprise" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adresse" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adresses" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Sélectionner une entreprise" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Intitulé de l'adresse" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Titre décrivant la saisie de l'adresse" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Adresse principale" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Sélectionner comme adresse principale" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Ligne 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Adresse" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Ligne 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Seconde ligne d'adresse" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Code postal" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Ville / Région" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Code postal Ville / Région" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "État / Province" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "État ou province" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Pays" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Pays" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Notes du livreur" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Instructions pour le livreur" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Notes pour la livraison interne" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Notes internes pour la livraison" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Lien vers les informations de l'adresse (externe)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Pièces du fabricant" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Pièce de base" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Sélectionner une partie" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Sélectionner un fabricant" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "Référence fabricant" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Référence du fabricant" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL pour le lien externe de la pièce du fabricant" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Description de la pièce du fabricant" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Les unités d'emballage doivent être compatibles avec les unités de base" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Les unités d'emballage doivent être supérieures à zéro" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "La pièce du fabricant liée doit faire référence à la même pièce de base" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fournisseur" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Sélectionner un fournisseur" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Unité de gestion des stocks des fournisseurs" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Cette partie du fournisseur est-elle active ?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Sélectionner un fabricant" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "Lien de la pièce du fournisseur externe" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Description de la pièce du fournisseur" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "coût de base" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Frais minimums (par exemple frais de stock)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Conditionnement" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Conditionnement de l'article" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Nombre de paquet" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Quantité totale fournie dans un emballage unique. Laisser vide pour les articles individuels." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "plusieurs" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Commande multiple" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Quantité disponible auprès du fournisseur" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Disponibilité mise à jour" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Date de dernière mise à jour des données de disponibilité" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Rupture de prix pour le fournisseur" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Devise par défaut utilisée pour ce fournisseur" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Nom de l'entreprise" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "En Stock" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Ruptures de prix" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Une erreur s'est produite lors de l'exportation des données" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Le plugin d'exportation de données renvoie un format de données incorrect" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Format d'exportation" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Sélectionner le format du fichier d'exportation" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Plugin d'exportation" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Sélectionner le plugin d'exportation" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Informations complémentaires sur le statut de ce poste" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Touche d'état personnalisée" @@ -4476,123 +4740,152 @@ msgstr "Placé" msgid "Invalid status code" msgstr "Code d'état invalide" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Fichier de données" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Fichier de données à importer" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Colonnes" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Type de modèle cible pour cette session d'importation" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Statut de l'importation" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Champs par défaut" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Remplacements de champs" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Filtres de terrain" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Mettre à jour les enregistrements existants" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Si activé, les enregistrements existants seront mis à jour avec de nouvelles données" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Certains champs obligatoires n'ont pas été cartographiés" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Identifiant de base de données existant pour l'enregistrement" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "La colonne est déjà associée à un champ de la base de données" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Le champ est déjà associé à une colonne de données" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Le mappage des colonnes doit être lié à une session d'importation valide" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "La colonne n'existe pas dans le fichier de données" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Le champ n'existe pas dans le modèle cible" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Le champ sélectionné est en lecture seule" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Session d'importation" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Champ d'application" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Colonne" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Index des lignes" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Données de la ligne d'origine" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Erreurs" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Valide" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "L'ID est requis pour mettre à jour les enregistrements existants." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Aucun enregistrement trouvé avec l'ID fourni" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Format d'ID invalide" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "L'ID est requis pour mettre à jour les enregistrements existants." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Format de fichier de données non pris en charge" @@ -4600,43 +4893,47 @@ msgstr "Format de fichier de données non pris en charge" msgid "Failed to open data file" msgstr "Échec de l'ouverture du fichier de données" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Dimensions du fichier de données non valides" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Valeurs par défaut des champs invalides" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Remplacements de champs non valides" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Filtres de champ non valides" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Rangs" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Liste des identifiants de ligne à accepter" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Pas de rangs fournis" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "La ligne n'appartient pas à cette session" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "La ligne contient des données non valides" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "La rangée a déjà été complétée" @@ -4672,115 +4969,115 @@ msgstr "Le fichier de données contient trop de colonnes" msgid "Data file contains too many rows" msgstr "Le fichier de données contient trop de lignes" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "La valeur doit être un objet dictionnaire valide" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Copies" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Nombre de copies à imprimer pour chaque étiquette" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Connecté" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Inconnu" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Impression" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Attention" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Aucun média" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Bourrage de papier" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Déconnecté" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Erreur" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Imprimante Etiquette" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Impression directe des étiquettes pour divers articles." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Emplacement Imprimante" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Porter de l'imprimante sur un emplacement spécifique" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Nom de la machine" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Machine Type" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Type de machine" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Pilote" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Pilote utilisé pour la machine" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Les machines peuvent être inactivées" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Pilote disponible" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Aucune erreur" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Initialisé" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Statut de la machine" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Machine" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Configuration de la machine" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Type de configuration" @@ -4792,7 +5089,7 @@ msgstr "Clé de la propriété" msgid "Value of the property" msgstr "Valeur de la propriété" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Groupe" @@ -4816,117 +5113,118 @@ msgstr "Progression maximale" msgid "Maximum value for progress type, required if type=progress" msgstr "Valeur maximale pour le type de progression, requis si type=progress" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Référence de commande" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Remarquable" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "A le code du projet" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Créé par" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Créé avant" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Créé après" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "A la date de début" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Date de début Avant" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Date de début Après" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "A une date cible" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Date cible Avant" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Date cible Après" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Possède un Tarif" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Terminé avant" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Terminé après" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Ordre de fabrication externe" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Commande" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Commande Complétée" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Pièces Internes" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Commande En Attente" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Terminé" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Fait l'objet d'une expédition" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Commande d’achat" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Commande d’achat" msgid "Sales Order" msgstr "Commandes" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Retour de commande" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Prix Total" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Prix total pour cette commande" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Devise de la commande" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Devise de cette commande (laisser vide pour utiliser la devise par défaut de l'entreprise)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Cette commande est verrouillée et ne peut être modifiée" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Le contact ne correspond pas à l'entreprise sélectionnée" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "La date de début doit être antérieure à la date cible" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "L'adresse ne correspond pas à la société sélectionnée" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Description de la commande (facultatif)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Sélectionner le code du projet pour cette commande" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Lien vers une page externe" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Date de début" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Date de début prévue pour cette commande" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Date Cible" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Date prévue pour la livraison de la commande. La commande sera en retard après cette date." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Date d'émission" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Date d'émission de la commande" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Utilisateur ou groupe responsable de cette commande" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Point de contact pour cette commande" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Adresse de l'entreprise pour cette commande" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Référence de la commande" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "État" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Statut de la commande d'achat" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Société de laquelle les articles sont commandés" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Référence du fournisseur" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Code de référence de la commande fournisseur" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "reçu par" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Date à laquelle la commande a été complété" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Destination" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Destination des articles reçus" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Le fournisseur de la pièce doit correspondre au fournisseur de la commande" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Le poste ne correspond pas au bon de commande" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "Il manque une pièce liée à l'article de la ligne" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "La quantité doit être un nombre positif" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Client" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Société à laquelle les articles sont vendus" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Statut de la commande client" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Référence client " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Code de référence de la commande du client" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Nom de l’expédition" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "expédié par" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Le poste n'est pas associé à cette commande" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Aucune correspondance trouvée pour les numéros de série suivants" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Les numéros de série suivants sont indisponibles" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "La commande est déjà terminée" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "La commande est déjà annulée" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Seule une commande ouverte peut être marquée comme complète" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "La commande ne peut pas être terminée car il y a des envois incomplets" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "L'ordre ne peut pas être achevé car les allocations sont incomplètes" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "L'ordre ne peut pas être complété car il y a des postes incomplets" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "La commande est verrouillée et ne peut être modifiée" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Nombre d'élement" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Référence du poste" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Notes sur les postes" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Date cible pour ce poste (laisser vide pour utiliser la date cible de la commande)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Description du poste (facultatif)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Contexte supplémentaire pour cette ligne" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Prix unitaire" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Poste du bon de commande" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "La pièce du fournisseur doit correspondre à celle du fournisseur" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "L'ordre de fabrication doit être marqué externe" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Les ordres de fabrication ne peuvent être liées qu'à des pièces d'assemblage" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "Les pièces d'ordre de fabrication doivent correspondre la pièce d'objet" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Pièce fournisseur" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Reçu" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Nombre d'éléments reçus" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Prix d'achat" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Prix d'achat unitaire" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Ordre de fabrication externe à remplir par cet élément de ligne" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Ligne supplémentaire du bon de commande" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Poste de commande client" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Seules les pièces vendues peuvent être attribuées à une commande" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Prix de vente" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Prix de vente unitaire" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Expédié" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Quantité expédiée" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Envoi de la commande client" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "L'adresse d'expédition doit correspondre au client" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Adresse de livraison pour cet envoi" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Date d'expédition" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Date de Livraison" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Date de livraison de l'envoi" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Vérifié par" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Utilisateur qui a vérifié cet envoi" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envoi" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Numéro d'expédition" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "N° de suivi" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Information de suivi des colis" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "N° de facture" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Numéro de référence de la facture associée" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Le colis a déjà été envoyé" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "L'expédition n'a pas d'articles en stock alloués" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "L'expédition doit être vérifiée avant de pouvoir être terminée" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Ligne supplémentaire de commande client" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Affectation des commandes clients" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "L'article de stock n'a pas été assigné" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Impossible d'allouer l'article en stock à une ligne avec une autre pièce" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Impossible d'allouer le stock à une ligne sans pièce" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La quantité d'allocation ne peut pas excéder la quantité en stock" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "La quantité allouée doit être supérieure à zéro" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "La quantité doit être égale à 1 pour un article de stock sérialisé" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "La commande client ne correspond pas à l'expédition" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "L'envoi ne correspond pas à la commande client" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Ligne" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Référence de l'expédition de la commande client" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Article" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Sélectionner l'article de stock à affecter" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Saisir la quantité d'allocation de stock" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Retour Référence de la commande" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Entreprise à l'origine du retour des articles" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Statut du retour de commande" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Poste de l'ordre de retour" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "L'article en stock doit être spécifié" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "La quantité retournée dépasse la quantité en stock" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "La quantité retournée doit être supérieure à zéro" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Quantité non valide pour un article de stock sérialisé" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Sélectionner l'article à retourner par le client" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Date de réception" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "La date de réception de cet article en retour" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Résultats" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Résultat pour ce poste" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Coût associé au retour ou à la réparation de ce poste" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Ordre de retour Ligne supplémentaire" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID de commande" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID de l'ordre à dupliquer" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Copier des lignes" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Copier les postes de l'ordre original" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Copier les lignes supplémentaires" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Copier les postes supplémentaires de l'ordre original" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Copier les paramètres" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Postes de travail" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Lignes achevées" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Duplicata de commande" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Spécifier les options de duplication de cette commande" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "ID de commande invalide" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Nom du fournisseur" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "La commande ne peut pas être annulée" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Permettre la clôture d'une commande avec des postes incomplets" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "La commande comporte des postes incomplets" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "La commande n'est pas ouverte" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Tarification automobile" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Calculer automatiquement le prix d'achat sur la base des données de pièces du fournisseur" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Devise du prix d'achat" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Fusionner des éléments" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Fusionner en un seul poste les éléments ayant la même partie, la même destination et la même date cible" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Unité de gestion des stocks" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Numéro de pièce interne" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Nom de la pièce interne" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "La pièce du fournisseur doit être spécifiée" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Le bon de commande doit être spécifié" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Le fournisseur doit correspondre au bon de commande" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Le bon de commande doit correspondre au fournisseur" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Poste" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Sélectionner le lieu de destination des envois reçus" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Saisir le code de lot pour les articles de stock entrant" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Date d'expiration" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Saisir la date d'expiration des articles de stock entrant" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Entrez les numéros de série pour les articles de stock entrants" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Remplacer les informations d'emballage pour les articles en stock entrants" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Note supplémentaire pour les articles en stock entrant" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Code-barres" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Code-barres scanné" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Le code-barres est déjà utilisé" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Les postes doivent être fournis" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "L'emplacement de la destination doit être spécifié" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Les valeurs de code-barres fournies doivent être uniques" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Envois" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Envois terminés" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "Lignes allouées" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Devise du prix de vente" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Postes alloués" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Aucun détail sur l'expédition n'est fourni" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Le poste n'est pas associé à cette commande" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "La quantité doit être positive" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Entrez les numéros de série à allouer" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "L'envoi a déjà été effectué" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "L'envoi n'est pas associé à cette commande" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Aucune correspondance trouvée pour les numéros de série suivants" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Les numéros de série suivants sont indisponibles" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Poste de commande de retour" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Le poste ne correspond pas à l'ordre de retour" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Le poste a déjà été reçu" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Les articles ne peuvent être reçus que pour des commandes en cours" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Quantité à retourner" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Devise du prix de la ligne" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Perdu" @@ -5718,1279 +6125,1312 @@ msgstr "Perdu" msgid "Returned" msgstr "Retourné" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "En Cours" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Retour" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Réparer" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Remplacer" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Remboursement" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Refuser" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Délivré" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Bon de commande en souffrance" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Le bon de commande {po} est maintenant en retard" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Commande en souffrance" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "La commande {so} est maintenant en retard" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Ordre de retour en retard" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "L'ordre de retour {ro} est maintenant en retard" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Étoilé" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Filtrer par catégories étoilées" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Profondeur" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filtrer par profondeur de catégorie" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Premier niveau" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filtrer par catégories de premier niveau" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Cascade" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Inclure les sous-catégories dans les résultats filtrés" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Parent" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Filtrer par catégorie de parents" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Exclure les sous-catégories de la catégorie spécifiée" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "A des résultats" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Est variante" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Est la révision" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "A des révisions" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "Nomenclature valide" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Catégories en cascade" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Si vrai, inclure des éléments dans les sous-catégories de la catégorie donnée" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Filtrer par ID de catégorie numérique ou par 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "La pièce d'assemblage est active" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "La pièce d'assemblage est traçable" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "La pièce d'assemblage est testable" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Le composant est testable" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Utilise" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Catégorie de composant" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Catégories de composants" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Emplacement par défaut" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Emplacement par défaut des pièces de cette catégorie" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Structurel" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Les pièces ne peuvent pas être directement affectées à une catégorie structurelle, mais peuvent être affectées à des catégories enfantines." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Mots-clés par défaut" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Mots-clés par défaut pour les pièces de cette catégorie" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Icône" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Icône (facultatif)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Vous ne pouvez pas rendre cette catégorie de pièces structurelle car certaines pièces lui sont déjà affectées !" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Catégorie de pièce Modèle de paramètre" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Valeur par Défaut" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Valeur par défaut du paramètre" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Pièces" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Impossible de supprimer cette partie car elle est verrouillée" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Impossible de supprimer cette partie car elle est toujours active" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Impossible de supprimer cette pièce car elle est utilisée dans un assemblage" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "La partie \"{self}\" ne peut pas être utilisée dans la nomenclature de \"{parent}\" (récursif)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "La partie \"{parent}\" est utilisée dans la nomenclature de \"{self}\" (récursif)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "L'IPN doit correspondre au modèle de regex {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Une partie ne peut pas être une révision d'elle-même" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Les révisions ne sont autorisées que pour les pièces d'assemblage" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Impossible d'effectuer une révision d'un modèle de pièce" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "La partie parentale doit pointer vers le même modèle" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Il existe déjà un article en stock avec ce numéro de série" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN dupliqué non autorisé dans les paramètres de la pièce" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "La révision de la pièce existe déjà en double." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Une pièce avec ce nom, IPN et révision existe déjà." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Les pièces ne peuvent pas être affectées à des catégories de pièces structurelles !" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Nom de l'article" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Est un modèle" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Cette pièce est-elle une pièce modèle ?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Cette pièce est-elle une variante d'une autre pièce ?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Description de la pièce (facultatif)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Mots-clés" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Les mots-clés partiels pour améliorer la visibilité dans les résultats de recherche" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Catégorie de la pièce" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Numéro de révision ou de version de la pièce" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Révision" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Cette partie est-elle une révision d'une autre partie ?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Révision de" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Où cet article est-il normalement stocké ?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Expiration par défaut" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Délai d'expiration (en jours) pour les articles en stock de cette pièce" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Stock Minimum" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Niveau de stock minimum autorisé" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Unités de mesure pour cette partie" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Cette pièce peut-elle être fabriquée à partir d'autres pièces ?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Cette pièce peut-elle être utilisée pour construire d'autres pièces ?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Cette partie dispose-t-elle d'un suivi pour les articles uniques ?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Des résultats de tests peuvent-ils être enregistrés pour cette pièce ?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Cette pièce peut-elle être achetée auprès de fournisseurs externes ?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Cette pièce peut-elle être vendue aux clients ?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Est-ce que cette pièce est active ?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Les parties verrouillées ne peuvent pas être modifiées" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "S'agit-il d'un élément virtuel, tel qu'un logiciel ou une licence ?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "Nomenclature validée" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Est-ce que la nomenclature pour cette pièce est correcte ?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Somme de contrôle de la nomenclature" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Somme de contrôle de la nomenclature enregistrée" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Nomenclature vérifiée par" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Date de vérification de la nomenclature" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Création Utilisateur" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Propriétaire responsable de cette pièce" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Ventes multiples" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Devise utilisée pour cacher les calculs de prix" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Coût minimum de la nomenclature" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Coût minimal des composants" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Coût maximal de la nomenclature" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Coût maximal des composants" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Coût d'achat minimum" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Coût d'achat historique minimum" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Coût d'achat maximum" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Coût d'achat historique maximum" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Prix interne minimum" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Coût minimum basé sur des ruptures de prix internes" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Prix interne maximum" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Coût maximum basé sur les écarts de prix internes" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Prix minimum du fournisseur" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Prix minimum des pièces provenant de fournisseurs externes" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Prix maximum du fournisseur" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Prix maximum des pièces provenant de fournisseurs externes" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Coût minimum de la variante" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Calcul du coût minimum des pièces de la variante" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Coût maximal de la variante" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Calcul du coût maximal des pièces de la variante" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Coût minimal" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Remplacer le coût minimum" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Coût maximal" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Dépassement du coût maximal" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Calcul du coût minimum global" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Calcul du coût maximum global" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Prix de vente minimum" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Prix de vente minimum basé sur des ruptures de prix" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Prix de vente maximum" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Prix de vente maximum en fonction des écarts de prix" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Coût minimum de vente" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Prix de vente historique minimum" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Coût de vente maximum" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Prix de vente historique maximum" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Partie pour l'inventaire" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Nombre d'articles" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Nombre d'entrées individuelles au moment de l'inventaire" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Stock total disponible au moment de l'inventaire" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Date" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Date de l'inventaire" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Coût minimum du stock" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Coût minimum estimé des stocks disponibles" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Coût maximal du stock" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Coût maximum estimé des stocks disponibles" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Vente de pièces détachées Prix cassé" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Modèle de test partiel" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Le nom du modèle n'est pas valide - il doit comporter au moins un caractère alphanumérique" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Les modèles de test ne peuvent être créés que pour les parties testables" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Un modèle de test avec la même clé existe déjà pour la partie" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Nom de test" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Entrez un nom pour le test" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Clé de test" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Clé simplifiée pour le test" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Description du test" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Saisir la description de ce test" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Ce test est-il activé ?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Requis" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Ce test est-il obligatoire pour passer l'examen ?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Valeur requise" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Ce test nécessite-t-il une valeur lors de l'ajout d'un résultat de test ?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Nécessite une pièce jointe" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Ce test nécessite-t-il un fichier joint lors de l'ajout d'un résultat de test ?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Choix valables pour ce test (séparés par des virgules)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "L'article de nomenclature ne peut pas être modifié - l'assemblage est verrouillé" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Le poste de nomenclature ne peut pas être modifié - l'assemblage de la variante est verrouillé" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Sélectionner la partie parentale" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Sous-partie" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Sélectionner la pièce à utiliser dans la nomenclature" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Quantité de nomenclature pour ce poste de nomenclature" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Ce poste de nomenclature est facultatif" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Ce poste de nomenclature est consommable (il n'est pas suivi dans les ordres de fabrication)." -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Définir la quantité" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Attrition" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Attrition estimée pour cette fabrication, exprimée en pourcentage (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Arrondi au multiple" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Arrondir la quantité de production requise au multiple le plus proche de cette valeur" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Référence du poste de nomenclature" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Notes sur les postes de nomenclature" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Somme de contrôle" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Somme de contrôle de la ligne de nomenclature" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Validée" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Ce poste de nomenclature a été validé" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Obtient l'héritage" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Ce poste de nomenclature est hérité des nomenclatures des composants variants" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Les postes de stock pour les composants variants peuvent être utilisés pour ce poste de nomenclature" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "La quantité doit être un nombre entier pour les pièces pouvant être suivies" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "La sous-partie doit être spécifiée" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Remplacement d'un poste de nomenclature" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "La pièce de remplacement ne peut pas être identique à la pièce maîtresse" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Poste de nomenclature parent" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Pièce de rechange" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Première partie" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Partie 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Sélectionner une partie connexe" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Note pour cette relation" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Il n'est pas possible de créer une relation entre une pièce et elle-même" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Une relation en double existe déjà" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Catégorie de parents" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Catégorie de pièce mère" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Sous-catégories" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Résultats" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Nombre de résultats enregistrés par rapport à ce modèle" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Devise d'achat de l'item" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Le fichier n'est pas une image" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Partie originale" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Sélectionner la partie originale à dupliquer" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Copier l'image" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Copier l'image à partir de la partie originale" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Copier la nomenclature" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Copie de la nomenclature de la pièce originale" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Copie des données de paramètres de la pièce d'origine" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Notes sur la copie" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Copier les notes de la partie originale" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Test Copie" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Quantité de stock initial" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Indiquer la quantité de stock initiale pour cette pièce. Si la quantité est égale à zéro, aucun stock n'est ajouté." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Emplacement initial du stock" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Spécifier l'emplacement du stock initial pour cette pièce" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Sélectionner le fournisseur (ou laisser en blanc pour passer)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Sélectionner le fabricant (ou laisser en blanc pour ignorer)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Numéro de pièce du fabricant" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "L'entreprise sélectionnée n'est pas un fournisseur valide" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "L'entreprise sélectionnée n'est pas un fabricant valide" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "La pièce du fabricant correspondant à ce MPN existe déjà" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "La pièce du fournisseur correspondant à cette UGS existe déjà" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Nom catégorie" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Construction" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Quantité de cette pièce actuellement en production" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Quantité exceptionnelle de cette pièce sont planifié à la fabrication" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Éléments en stock" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Révisions" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Stock total" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Stock non attribué" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Variante Stock" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Dupliquer une pièce" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Copier les données initiales d'une autre partie" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Copier l'image" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Copier l'image à partir de la partie originale" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Copier la nomenclature" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Copie de la nomenclature de la pièce originale" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Notes sur la copie" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Copier les notes de la partie originale" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Test Copie" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Stock initial" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Créer une pièce avec une quantité de stock initiale" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Informations sur le fournisseur" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Ajouter les informations initiales du fournisseur pour cette pièce" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Copier les paramètres de la catégorie" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Copier les modèles de paramètres de la catégorie de pièces sélectionnée" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Image existante" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Nom de fichier d'une image de pièce existante" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Le fichier image n'existe pas" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Valider l'ensemble de la nomenclature" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Peut construire" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Nécessaire pour fabrication" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Alloué à la fabrication" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Nécessaire pour les commandes" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Alloué aux commandes" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Prix Minimum" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Remplacer la valeur calculée pour le prix minimum" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Prix minimum monnaie" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Prix Maximum" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Remplacer la valeur calculée pour le prix maximum" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Devise du prix maximum" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Mise à jour" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Mise à jour des prix pour cette pièce" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Impossible de convertir les devises fournies en {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Le prix minimum ne doit pas être supérieur au prix maximum" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Le prix maximum ne doit pas être inférieur au prix minimum" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Sélectionner l'assemblage parent" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Sélectionner le composant" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Sélectionner la pièce à partir de laquelle copier la nomenclature" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Supprimer les données existantes" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Supprimer les postes de nomenclature existants avant de les copier" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Inclure l'héritage" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Inclure les éléments de nomenclature hérités des pièces modélisées" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Sauter les lignes non valides" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Activez cette option pour ignorer les lignes non valides" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Copier les pièces de remplacement" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Copie de pièces de rechange en cas de duplication de postes de nomenclature" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Notification de stock faible" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Le stock disponible pour {part.name}, est tombé en dessous du niveau minimum configuré" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "Pas de date d'expieatio" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Expire aujourd’hui" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} jours" @@ -7011,7 +7451,7 @@ msgstr "Échantillon" msgid "Installed" msgstr "Installé" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Le plugin ne peut pas être supprimé car il est actuellement actif" @@ -7023,23 +7463,23 @@ msgstr "Aucune action spécifiée" msgid "No matching action found" msgstr "Aucune action correspondante trouvée" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Aucune correspondance trouvée pour les données du code-barres" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Correspondance trouvée pour les données du code-barres" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Le modèle n'est pas pris en charge" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "L'instance de modèle n'a pas été trouvée" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Le code-barres correspond à l'article existant" @@ -7055,51 +7495,67 @@ msgstr "Aucune pièce de fournisseur correspondante n'a été trouvée" msgid "Multiple matching supplier parts found" msgstr "Plusieurs pièces de fournisseurs correspondantes trouvées" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Aucun plugin correspondant n'a été trouvé pour les données de code-barres" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Pièce du fournisseur assortie" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "L'article a déjà été reçu" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Pas de correspondance de plugin pour le code-barres du fournisseur" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Plusieurs postes correspondants trouvés" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Aucun poste correspondant n'a été trouvé" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Aucun ordre de vente n'a été fourni" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Le code-barres ne correspond pas à un article de stock existant" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Le poste de stock ne correspond pas au poste individuel" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Stock disponible insuffisant" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Article de stock attribué à la commande client" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Pas assez d'informations" @@ -7108,23 +7564,23 @@ msgstr "Pas assez d'informations" msgid "Found matching item" msgstr "Trouvé l'article correspondant" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "La pièce du fournisseur ne correspond pas au poste" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Le poste est déjà clôturé" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Informations complémentaires requises pour l'obtention d'un poste budgétaire" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Poste de commande reçu" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Échec de la réception d'un poste" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Prise en charge native des codes-barres" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Préfixe du code-barres abrégé" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Personnaliser le préfixe utilisé pour les codes-barres courts, peut être utile pour les environnements avec plusieurs instances InvenTree" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL utilisée pour envoyer des messages à un canal Slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Ouvrir le lien" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Prise en charge native de l'impression d'étiquettes au format PDF" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Mode débogage" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Activer le mode débogage - renvoie du HTML brut au lieu du PDF" @@ -7653,55 +8117,55 @@ msgstr "dernière utilisation" msgid "Options" msgstr "Paramètres" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Taille de la page pour la feuille d'étiquettes" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Sauter les étiquettes" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Sauter ce nombre d'étiquettes lors de l'impression de feuilles d'étiquettes" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Frontière" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Imprimer une bordure autour de chaque étiquette" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Paysage" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Imprimer la feuille d'étiquettes en mode paysage" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Marge de page" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Marge autour de la page en mm" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "Imprimante de feuilles d'étiquettes InvenTree" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Regroupement de plusieurs étiquettes sur une seule feuille" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "L'étiquette est trop grande pour la taille de la page" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Aucune étiquette n'a été générée" @@ -7753,77 +8217,85 @@ msgstr "Prise en charge de la lecture des codes-barres TME" msgid "The Supplier which acts as 'TME'" msgstr "Le fournisseur qui agit en tant que \"TME" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "L'installation du plugin est désactivée" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Installation réussie du plugin" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Installation du plugin dans {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Le plugin n'a pas été trouvé dans le registre" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Le plugin n'est pas un plugin packagé" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Le nom du paquet du plugin n'a pas été trouvé" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Seuls les membres du personnel peuvent administrer les plugins" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "La désinstallation des plugins est désactivée" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Le plugin ne peut pas être désinstallé car il est actuellement actif" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Le plugin n'est pas installé" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "L'installation du plugin n'a pas été trouvée" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Désinstallation réussie du plugin" @@ -7871,25 +8343,25 @@ msgstr "Plugin obligatoire" msgid "Package Plugin" msgstr "Plugin Package" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Extension" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Aucun auteur trouvé" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Le plugin '{p}' n'est pas compatible avec la version actuelle d'InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Le plugin nécessite au moins la version {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Le plugin nécessite au maximum la version {v}" @@ -8114,176 +8586,184 @@ msgstr "Supprimer la configuration" msgid "Delete the plugin configuration from the database" msgstr "Supprimer la configuration du plugin de la base de données" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Articles" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Plugin non trouvé" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Le plugin ne prend pas en charge l'impression d'étiquettes" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Dimensions de l'étiquette non valides" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Aucun élément valide n'a été fourni au modèle" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Juridique" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Lettre" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Le fichier modèle portant ce nom existe déjà" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Nom du modèle" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Description du modèle" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Numéro de révision (auto-incrémentation)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Joindre au modèle sur l'impression" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Enregistrer le rapport en tant que pièce jointe à l'instance de modèle liée lors de l'impression" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Modèle de nom de fichier" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Modèle de génération de noms de fichiers" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Le modèle est activé" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Type de modèle cible pour le modèle" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtres" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Filtres de requête de modèle (liste de paires clé/valeur séparées par des virgules)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Fichier modèle" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Taille des pages pour les rapports PDF" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Rendre le rapport en orientation paysage" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "Fusionner" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Rapport généré à partir du modèle {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Erreur dans la génération du rapport" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Largeur [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Largeur de l'étiquette, spécifiée en mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Hauteur [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Hauteur de l'étiquette, spécifiée en mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Erreur d'impression des étiquettes" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Extrait " -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Fichier d'extrait de rapport" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Description du fichier d'extrait" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Elément" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Rapport sur le fichier d'actifs" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Description du fichier d'actifs" @@ -8291,23 +8771,23 @@ msgstr "Description du fichier d'actifs" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Sélectionner un modèle de rapport" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Liste des clés primaires des éléments à inclure dans le rapport" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Sélection du modèle d'étiquette" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Plugin d'impression" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Sélectionner le plugin à utiliser pour l'impression des étiquettes" @@ -8338,13 +8818,10 @@ msgstr "Matériel nécessaire" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Image partielle" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Délivré" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Requis pour" @@ -8380,8 +8857,8 @@ msgstr "Total" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Numéro de série" @@ -8405,7 +8882,7 @@ msgstr "Rapport de test des articles en stock" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Éléments installés" @@ -8438,810 +8915,922 @@ msgstr "Pas de résultat (obligatoire)" msgid "No result" msgstr "Pas de résultat" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Fichier image non trouvé" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "la balise part_image nécessite une instance de Part" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "la balise company_image nécessite une instance d'entreprise" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Filtrer par profondeur de localisation" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Filtrer par lieux de premier niveau" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Inclure les sous-emplacements dans les résultats filtrés" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Emplacement parent" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filtrer par emplacement parent" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Nom de la pièce (insensible à la casse)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Le nom de la pièce contient (insensible à la casse)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Nom de la pièce (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "Partie IPN (insensible à la casse)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "La partie IPN contient (insensible à la casse)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "Partie IPN (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Stock minimum" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Stock maximum" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Code de statut" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Emplacement externe" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Consommé par l'ordre de construction" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Installé dans un autre article en stock" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Arbre en pièces détachées" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Mise à jour avant" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Mise à jour après" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Inventaire avant" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Inventaire après" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Date d'expiration avant" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Date d’expiration après" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Périmé" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "La quantité est requise" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "La partie valide doit être fournie" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Le fournisseur donné n'existe pas" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "La pièce du fournisseur a une taille d'emballage définie, mais le drapeau use_pack_size n'est pas activé" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Les numéros de série ne peuvent pas être fournis pour une pièce non traçable" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Type d'emplacement du stock" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Types d'emplacements de stock" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Icône par défaut pour tous les lieux qui n'ont pas d'icône (facultatif)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Emplacement du stock" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Emplacement des stocks" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Propriétaire" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Sélectionner un propriétaire" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Les articles en stock ne peuvent pas être directement placés dans un emplacement de stock structurel, mais peuvent être placés dans des emplacements subordonnés." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Externe" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Il s'agit d'un emplacement de stock externe" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Type d'emplacement" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Type d'emplacement du stock de cet emplacement" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Vous ne pouvez pas rendre ce magasin structurel car certains articles de stock y sont déjà localisés !" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "La pièce doit être spécifiée" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Les articles en stock ne peuvent pas être localisés dans des emplacements de stock structurel !" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Il n'est pas possible de créer un article de stock pour les pièces virtuelles" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Le type de pièce ('{self.supplier_part.part}') doit être {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "La quantité doit être de 1 pour un article avec un numéro de série" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Le numéro de série ne peut pas être défini si la quantité est supérieure à 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "L'objet ne peut pas s'appartenir à lui-même" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "L'élément doit avoir une référence de construction si is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "La référence de construction ne pointe pas vers le même objet de pièce" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Poste de stock parent" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Pièce de base" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Sélectionnez une pièce fournisseur correspondante pour cet article en stock" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Où se trouve cet article en stock ?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "L'emballage de cet article en stock est stocké dans" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Installé dans" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "L'article a été installé dans un autre article ?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Numéro de série pour cet article" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Code de lot pour cet article de stock" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Quantité en stock" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Source Construire" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Construire pour cet article en stock" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Consommé par" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Ordre de construction qui a consommé cet article de stock" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Bon de commande source" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Commande d'achat pour cet article en stock" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Destination de la commande client" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Date d'expiration de l'article en stock. Le stock sera considéré comme périmé après cette date" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Supprimer lors de l'épuisement" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Supprimer ce poste de stock lorsque le stock est épuisé" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Prix d'achat de l'unité unique au moment de l'achat" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Converti en partie" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "La pièce n'est pas définie comme pouvant faire l'objet d'un suivi" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "La quantité doit être un nombre entier" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "La quantité ne doit pas dépasser la quantité disponible en stock ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Les numéros de série doivent être fournis sous forme de liste" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "La quantité ne correspond pas au nombre de numéros de série" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Le modèle de test n'existe pas" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Un article de stock a été affecté à une commande client" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "L'article de stock est installé dans un autre article" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "L'article de stock contient d'autres articles" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Un article de stock a été affecté à un client" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "L'article de stock est actuellement en production" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Le stock sérialisé ne peut pas être fusionné" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Articles de stock en double" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Les articles en stock doivent se référer à la même pièce" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Les articles en stock doivent se référer à la même pièce du fournisseur" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Les codes d'état des stocks doivent correspondre" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "StockItem ne peut pas être déplacé car il n'est pas en stock" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Suivi des articles en stock" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Notes d'entrée" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Résultat du test de l'article en stock" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Une valeur doit être fournie pour ce test" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "La pièce jointe doit être téléchargée pour ce test" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "Valeur non valide pour ce test" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Résultat du test" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Valeur de sortie du test" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Pièce jointe au résultat du test" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Notes de test" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Station de test" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "L'identifiant de la station de test où le test a été effectué" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Commencé" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Horodatage du début du test" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Fini" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Horodatage de la fin du test" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Code de lot généré" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Sélectionner l'ordre de construction" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Sélectionner l'article de stock pour lequel le code de lot doit être généré" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Sélectionnez l'emplacement pour lequel vous souhaitez générer un code de lot" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Sélectionnez la partie pour laquelle vous souhaitez générer un code de lot" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Sélectionner un ordre d'achat" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Saisir la quantité pour le code de lot" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Numéro de série généré" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Sélectionner la pièce pour laquelle un numéro de série doit être généré" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Nombre de numéros de série à générer" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Modèle de test pour ce résultat" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "L'ID du modèle ou le nom du test doit être fourni" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "L'heure de fin du test ne peut être antérieure à l'heure de début du test" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Article Parent" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Article de stock parent" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Utiliser la taille de l'emballage lors de l'ajout : la quantité définie est le nombre d'emballages" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Entrez les numéros de série pour les nouveaux articles" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Référence du fournisseur" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Expiré" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Éléments enfants" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Suivi des éléments" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Prix d'achat de cet article en stock, par unité ou par paquet" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Entrez le nombre d'articles en stock à sérialiser" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "La quantité ne doit pas dépasser la quantité disponible en stock ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Emplacement du stock de destination" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Les numéros de série ne peuvent pas être assignés à cette pièce" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Les numéros de série existent déjà" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Sélectionner l'article de stock à installer" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Quantité à installer" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Saisir la quantité d'articles à installer" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Ajouter une note de transaction (facultatif)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "La quantité à installer doit être d'au moins 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "L'article en stock n'est pas disponible" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "La pièce sélectionnée ne figure pas dans la nomenclature" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "La quantité à installer ne doit pas dépasser la quantité disponible" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Emplacement de destination de l'élément désinstallé" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Sélectionner la pièce à convertir en article de stock" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "La partie sélectionnée n'est pas une option valide pour la conversion" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Impossible de convertir un article de stock auquel un SupplierPart a été attribué" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Code d'état de l'article en stock" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Sélectionner la pièce à convertir en article de stock" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "La partie sélectionnée n'est pas une option valide pour la conversion" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Impossible de convertir un article de stock auquel un SupplierPart a été attribué" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Sélectionner les articles en stock pour modifier leur statut" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Aucun article en stock n'a été sélectionné" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Sous-localisations" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Emplacement du stock mère" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "La pièce doit être vendable" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "L'article est affecté à une commande client" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "L'article est attribué à un ordre de fabrication" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Affectation d'articles en stock par le client" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "L'entreprise sélectionnée n'est pas un client" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Notes d'affectation des stocks" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Une liste des articles en stock doit être fournie" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Notes sur les fusions d'actions" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Autoriser les fournisseurs non concordants" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Permettre la fusion d'articles en stock avec des pièces de fournisseurs différents" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Autoriser la non-concordance des statuts" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Permettre la fusion d'articles en stock ayant des codes de statut différents" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Au moins deux articles en stock doivent être fournis" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Pas de changement" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Valeur de la clé primaire StockItem" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "L'article n'est plus en stock" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Notes sur les transactions boursières" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Notes sur les transactions boursières" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Numéro de série suivant" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Numéro de série précédent" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Articles de stock fusionnés" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Converti en variante" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "La sortie de l'ordre de construction a été créée" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Sortie de l'ordre de construction terminée" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "La sortie de l'ordre de construction a été refusée" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Consommé par ordre de construction" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Commandes expédiées vs. ventes" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Livraisons reçues vs. commandes réalisées" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Livraisons retournées vs. commandes retournées" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Envoyé au client" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Retourné par le client" @@ -9527,19 +10124,19 @@ msgstr "Utilisateurs" msgid "Select which users are assigned to this group" msgstr "Sélectionner quels utilisateurs sont assignés à ce groupe" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Informations personnelles" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Droits" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Dates importantes" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Le jeton a été révoqué" @@ -9547,279 +10144,283 @@ msgstr "Le jeton a été révoqué" msgid "Token has expired" msgstr "Le jeton a expiré" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "Jeton API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Jetons API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Nom du jeton" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Nom du jeton personnalisé" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Date d'expiration du jeton" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Dernière visite" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Dernière utilisation du jeton" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Révoquée" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Droit défini" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Vue" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Droit de voir des éléments" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Ajouter" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Droit d'ajouter des éléments" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Modifier" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Droit de modifier des élément" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Supprimer" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Droit de supprimer des éléments" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Bot" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Interne" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Invité" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Langue" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Langue préférée de l'utilisateur" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Thème" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Paramètres pour l'interface web sous forme de JSON - ne pas modifier manuellement !" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Raccourcis" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Paramètres des widgets du tableau de bord sous forme de JSON - ne pas modifier manuellement !" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Nom d'affichage" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Nom d'affichage choisi pour l'utilisateur" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Localisation" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Intitulé de l'emploi principal ou du poste" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Message sur le statut de l'utilisateur" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Informations sur la localisation de l'utilisateur" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "L'utilisateur utilise activement le système" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Coordonnées préférées de l'utilisateur" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Type d'utilisateur" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "De quel type d'utilisateur s'agit-il ?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organisation" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Organisation/affiliation principale de l'utilisateur" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Groupe primaire" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Groupe principal de l'utilisateur" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Administrateur" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Bons de commande" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Ventes" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Commandes de retour" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Nom d'utilisateur" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Prénom" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Prénom de l'utilisateur" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Nom" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Nom de famille de l'utilisateur" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Adresse e-mail de l'utilisateur" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Super-utilisateur" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Cet utilisateur est-il un super-utilisateur" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Ce compte d'utilisateur est-il actif" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Seul un superutilisateur peut modifier ce champ" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Mot de passe" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Mot de passe pour l'utilisateur" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Écraser l'alerte sur les règles de mot de passe" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Vous n'avez pas le droit de créer des utilisateurs" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Votre compte a été créé." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Veuillez utiliser la fonction de réinitialisation du mot de passe pour vous connecter" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Bienvenue dans InvenTree" diff --git a/src/backend/InvenTree/locale/he/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/he/LC_MESSAGES/django.po index 00965ce03b..dff8271dc6 100644 --- a/src/backend/InvenTree/locale/he/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/he/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Hebrew\n" "Language: he_IL\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "למשתמש אין הרשאה לצפות במוזל הזה" @@ -65,150 +69,155 @@ msgstr "אישור כתובת אימייל" msgid "You must type the same email each time." msgstr "חובה לרשום את אותו אימייל בכל פעם." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "סופקה יחידה שלא קיימת ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "לא צוין ערך" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "הזן תאריך סיום" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "מספרים סידוריים לא נמצאו" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -216,159 +225,203 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "אימייל" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "שגיאה בהפעלת אימות הפלאגין" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata must be a python dict object" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "מטא נתונים של תוסף" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "שדה מטא נתונים של JSON, לשימוש על ידי תוספים חיצוניים" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "דפוס מעוצב בצורה לא נכונה" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "צוין מפתח פורמט לא ידוע" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "חסר מפתח פורמט נדרש" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "שדה הפניה לא יכול להיות ריק" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "הפניה חייבת להתאים לדפוס הנדרש" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "מספר האסמכתה גדול מדי" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "בחירה שגויה" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "שם" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "תיאור" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "תיאור (לא חובה)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "נתיב" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "שמות כפולים אינם יכולים להתקיים תחת אותו אב" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "הערות סימון (אופציונלי)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "נתוני ברקוד" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "נתוני ברקוד של צד שלישי" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "ברקוד Hash" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hash ייחודי של נתוני ברקוד" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "נמצא ברקוד קיים" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "שגיאת שרת" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "נרשמה שגיאה על ידי השרת." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "המספר חייב להיות תקין" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "מטבע" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "בחר מטבע מהאפשרויות הזמינות" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "ערבית" @@ -521,46 +574,48 @@ msgstr "סינית (פשוטה)" msgid "Chinese (Traditional)" msgstr "סינית (מסורתית)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "קוד מטבע לא מאושר" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "מקור הבנייה" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "רכיב" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "מקט" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "בחר רכיב לבנייה" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "כמות בניה" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "קישור חיצוני" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "כמות" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "מספרים סידוריים" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "בהמתנה" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "ייצור" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "מבוטל" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "הושלם" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "משתמש" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "משתמש" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "קישור" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "קובץ מצורף" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "קובץ חסר" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "חסר קישור חיצוני" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "בחר קובץ לצירוף" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "הערה" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "שם קובץ" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "מוקם" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "נשלח" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "אבד" @@ -5718,1279 +6125,1312 @@ msgstr "אבד" msgid "Returned" msgstr "הוחזר" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "לא פורטה הפעולה" msgid "No matching action found" msgstr "פעולה מבוקשת לא נמצאה" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "נשלח ללקוח" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "הוחזר מלקוח" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "שם משתמש" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "שם פרטי" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/hi/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/hi/LC_MESSAGES/django.po index d218890f60..38a0ea0665 100644 --- a/src/backend/InvenTree/locale/hi/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/hi/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Hindi\n" "Language: hi_IN\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "" @@ -65,150 +69,155 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "तारीख दर्ज करें" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "कनेक्शन त्रुटि" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -216,159 +225,203 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "ई-मेल" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5718,1279 +6125,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/hu/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/hu/LC_MESSAGES/django.po index 9eadd76556..f84a04ceea 100644 --- a/src/backend/InvenTree/locale/hu/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/hu/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Hungarian\n" "Language: hu_HU\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API funkciót nem találom" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "A tételeket listában kell átadni" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Érvénytelen a tétel lista" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Minden szűrő csak true értékkel használható" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Nincs a szűrésnek megfelelő tétel" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Nincs adat megadva" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Ennek a mezőnek egyedinek kell lennie." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Nincs jogosultságod az adatok megtekintéséhez" @@ -65,150 +69,155 @@ msgstr "Email cím megerősítés" msgid "You must type the same email each time." msgstr "Mindig ugyanazt az email címet kell beírni." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "A megadott elsődleges email cím nem valós." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "A megadott email domain nincs jóváhagyva." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Érvénytelen mennyiségi egység ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nincs érték megadva" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "{original} átváltása {unit}-ra sikertelen" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Nem megfelelő mennyiség" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "A hiba részleteit megtalálod az admin panelen" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Dátum megadása" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Érvénytelen decimális érték" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Megjegyzések" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "A(z) '{name}' érték nem a szükséges minta szerinti" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "A megadott érték nem felel meg a szükséges mintának: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Nem lehet 1000 tételnél többet szerializálni" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Üres sorozatszám" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Duplikált sorozatszám" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Érvénytelen csoport: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Csoport tartomány {group} több mint az engedélyezett ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Nem található sorozatszám" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "A megadott számú egyedi sorozatszám ({n}) meg kell egyezzen a darabszámmal ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "HTML tag-ek eltávolítása ebből az értékből" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Az adatban tiltott markdown tartalom található" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Csatlakozási hiba" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "A kiszolgáló érvénytelen státuszkóddal válaszolt" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Kivétel történt" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "A kiszolgáló érvénytelen Content-Length értéket adott" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "A kép mérete túl nagy" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "A kép letöltés meghaladja a maximális méretet" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "A kiszolgáló üres választ adott" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "A megadott URL nem egy érvényes kép fájl" @@ -216,159 +225,203 @@ msgstr "A megadott URL nem egy érvényes kép fájl" msgid "Log in to the app" msgstr "Bejelentkezés az appba" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Mielőtt továbbmenne kötelező a kétfaktoros authentikációt engedélyeznie." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Hiba a plugin validálása közben" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "A meta adatnak egy python dict objektumnak kell lennie" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Plugin meta adatok" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON meta adat mező, külső pluginok számára" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Helytelenül formázott minta" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Ismeretlen formátum kulcs lett megadva" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Hiányzó formátum kulcs" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Az azonosító mező nem lehet üres" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Az azonosítónak egyeznie kell a mintával" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Azonosító szám túl nagy" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Érvénytelen választás" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Név" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Leírás" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Leírás (opcionális)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Elérési út" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplikált nevek nem lehetnek ugyanazon szülő alatt" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown megjegyzések (opcionális)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Vonalkód adat" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Harmadik féltől származó vonalkód adat" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Vonalkód hash" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Egyedi vonalkód hash" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Létező vonalkód" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Kiszolgálóhiba" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "A kiszolgáló egy hibaüzenetet rögzített." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Kép" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Érvényes számnak kell lennie" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Pénznem" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Válassz pénznemet a lehetőségek közül" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Ez a mező nem lehet null." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Érvénytelen érték" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Érvénytelen tartalomtípus-formátum" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Tartalomtípus nem található" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "A tartalomtípus nem egyezik a szükséges mixin osztállyal" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Paraméterek másolása" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Sorok másolása" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Sortételek másolása az eredeti rendelésről" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Extra sorok másolása" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Az eredeti rendelés extra tételeinek másolása" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arab" @@ -521,46 +574,48 @@ msgstr "Kínai (egyszerűsített)" msgid "Chinese (Traditional)" msgstr "Kínai (Hagyományos)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Frissítés elérhető" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "InvenTree frissítés elérhető" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Érvénytelen fizikai mértékegység" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Érvénytelen pénznem kód" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Rendelés állapota" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Szülő gyártás" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Változatokkal együtt" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Változatokkal együtt" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Változatokkal együtt" msgid "Part" msgstr "Alkatrész" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategória" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Szülő Gyártás" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Hozzám rendelt" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Hozzárendelve" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Ez előtt létrehozva" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Létrehozva ez után" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Van kezdeti dátuma" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Kezdeti dátum ez előtt" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Kezdeti dátum ez után" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Van céldátum" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Céldátum ez előtt" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Céldátum ez után" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Elkészült ez előtt" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Elkészült ez után" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Ettől a dátumtól" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Eddig a dátumig" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Fa kihagyása" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "A gyártást be kell fejezni a törlés előtt" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Fogyóeszköz" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opcionális" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Gyártmány" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Követett" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Ellenőrizhető" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Befejezetlen rendelés" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Lefoglalva" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Felhasználva" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Elérhető" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Rendelve" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "Gyártás nem található" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Gyártási utasítás" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Hely" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Kimenet" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Szűrés a kimeneti készlet tétel azonosítójára. Használj 'null'-t ha a be nem épített gyártási tételeket keresed." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Gyártási utasítások" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Az alkatrészjegyzék még nincs jóváhagyva" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Nem lehet inaktív alkatrészre Gyártást kezdeményezni" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Nem lehet lezáratlan alkatrészre Gyártást kezdeményezni" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Gyártási rendeléseket kizárólag beszerezhető alkatrészekkel lehet külső forrásból teljesíteni" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Meg kell adni felelős felhasználót vagy csoportot" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Gyártási rendelés alkatrész nem változtatható" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Céldátumnak a kezdeti dátum után kell lennie" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Gyártási utasítás azonosító" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Azonosító" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Gyártás rövid leírása (opcionális)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Gyártási megrendelés, amelyhez ez a gyártás hozzá van rendelve" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Válassz alkatrészt a gyártáshoz" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Vevői rendelés azonosító" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Vevői rendelés, amelyhez ez a gyártás tartozik" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Forrás hely" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Válassz helyet ahonnan készletet vegyünk el ehhez a gyártáshoz (hagyd üresen ha bárhonnan)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Külső gyártás" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Ez a gyártási rendelés külsőleg teljesül" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Cél hely" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Válassz helyet ahol a kész tételek tárolva lesznek" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Gyártási mennyiség" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Gyártandó készlet tételek száma" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Kész tételek" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Elkészült készlet tételek száma" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Gyártási állapot" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Gyártás státusz kód" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Batch kód" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Batch kód a gyártás kimenetéhez" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Létrehozás dátuma" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Gyártás kezdeti dátuma" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Gyártási rendelés ütemezett kezdeti dátuma" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Befejezés cél dátuma" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Cél dátum a gyártás befejezéséhez. Ez után késettnek számít majd." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Befejezés dátuma" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "elkészítette" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Indította" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Felhasználó aki ezt a gyártási utasítást kiállította" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Felelős" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Felhasználó vagy csoport aki felelős ezért a gyártásért" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Külső link" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link külső URL-re" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Priorítás" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Gyártási utasítás priorítása" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Projektszám" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Projekt kód a gyártáshoz" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "A gyártási rendelés nem befejezhető amíg nyitott al-gyártások vannak" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "A gyártási rendelés nem befejezhető amíg hiányos a kimenet" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "A gyártási foglalások teljesítése háttérfeladat elvégzése nem sikerült" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "A {build} gyártási utasítás elkészült" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Gyártási utasítás elkészült" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Egyedi követésre jelölt alkatrészeknél kötelező sorozatszámot megadni" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nincs gyártási kimenet megadva" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Gyártási kimenet már kész" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Gyártási kimenet nem egyezik a gyártási utasítással" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Mennyiségnek nullánál többnek kell lennie" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "A mennyiség nem lehet több mint a gyártási mennyiség" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "A gyártási kimenet nem felelt meg az összes kötelező teszten" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "A {serial} gyártási kimenet nem felelt meg az összes kötelező teszten" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "A lefoglalt készletelemek még gyártás alatt vannak" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Nem lehet részben befejezni egy építési kimenetet lefoglalt tételekkel" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Rendelkezésre álló mennyiség ({q}) túllépve" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Gyártási Rendelés Sor Tétel" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Gyártás objektum" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,452 +1081,473 @@ msgstr "Gyártás objektum" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Mennyiség" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Gyártáshoz szükséges mennyiség" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Felhasznált készlet mennyisége" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Gyártási tételnek meg kell adnia a gyártási kimenetet, mivel a fő darab egyedi követésre kötelezett" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "A készlet tétel nem egyezik az alkatrészjegyzékkel" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "A lefoglalt mennyiségnek nullánál nagyobbnak kell lennie" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Egyedi követésre kötelezett tételeknél a menyiség 1 kell legyen" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "A lefoglalt mennyiség ({q}) nem lépheti túl a szabad készletet ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Készlet túlfoglalva" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Készlet tétel" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Forrás készlet tétel" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Készlet mennyiség amit foglaljunk a gyártáshoz" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Beépítés ebbe" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Cél készlet tétel" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Gyártási Szint" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Alkatrész neve" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Gyártás kimenet" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Gyártási kimenet nem egyezik a szülő gyártással" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Kimeneti alkatrész nem egyezik a gyártási utasításban lévő alkatrésszel" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Ez a gyártási kimenet már elkészült" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Ez a gyártási kimenet nincs teljesen lefoglalva" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Add meg a mennyiséget a gyártás kimenetéhez" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Egész számú mennyiség szükséges az egyedi követésre kötelezett alkatrészeknél" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Egész számú mennyiség szükséges, mivel az alkatrészjegyzék egyedi követésre kötelezett alkatrészeket tartalmaz" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Sorozatszámok" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Add meg a sorozatszámokat a gyártás kimenetéhez" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Legyártott készlet helye" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Sorozatszámok automatikus hozzárendelése" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Szükséges tételek automatikus hozzárendelése a megfelelő sorozatszámokkal" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "A következő sorozatszámok már léteznek vagy nem megfelelőek" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "A gyártási kimenetek listáját meg kell adni" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Selejtezet gyártási kimenetek helye" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Foglalások törlése" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Selejtezett kimenetek foglalásainak felszabadítása" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Selejtezés oka" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "A kész gyártási kimenetek helye" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Hiányos foglalás elfogadása" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Kimenetek befejezése akkor is ha a készlet nem\n" "lett teljesen lefoglalva" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Lefoglalt készlet felhasználása" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Az összes ehhez a gyártáshoz lefoglalt készlet felhasználása" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Befejezetlen kimenetek törlése" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "A nem befejezett gyártási kimenetek törlése" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Nem engedélyezett" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Gyártásban fel lett használva" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Foglalás felszabadítása a készre jelentés előtt" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Túlfoglalt készlet" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Hogyan kezeljük az gyártáshoz rendelt egyéb készletet" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Pár készlet tétel túl lett foglalva" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Kiosztatlanok elfogadása" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Fogadd el hogy a készlet tételek nincsenek teljesen lefoglalva ehhez a gyártási utastáshoz" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "A szükséges készlet nem lett teljesen lefoglalva" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Befejezetlenek elfogadása" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Fogadd el hogy a szükséges számú gyártási kimenet nem lett elérve" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Szükséges gyártási mennyiség nem lett elérve" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "A Gyártásnak nyitott leszármazott Gyártása van" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "A Gyártásnak folyamatban kell lennie" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "A gyártási utasítás befejezetlen kimeneteket tartalmaz" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Gyártás sor" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Gyártás kimenet" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "A gyártási kimenetnek ugyanarra a gyártásra kell mutatnia" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Gyártás sor tétel" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part ugyanarra az alkatrészre kell mutasson mint a gyártási utasítás" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "A tételnek kell legyen készlete" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Rendelkezésre álló mennyiség ({q}) túllépve" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Gyártási kimenetet meg kell adni a követésre kötelezett alkatrészek lefoglalásához" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Gyártási kimenetet nem lehet megadni a követésre kötelezett alkatrészek lefoglalásához" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "A lefoglalandó tételeket meg kell adni" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Készlet hely ahonnan az alkatrészek származnak (hagyd üresen ha bárhonnan)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Hely kizárása" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Készlet tételek kizárása erről a kiválasztott helyről" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Felcserélhető készlet" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "A különböző helyeken lévő készlet egyenrangúan felhasználható" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Készlet helyettesítés" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Helyettesítő alkatrészek foglalásának engedélyezése" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Opcionális tételek" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Opcionális tételek lefoglalása a gyártáshoz" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "Összes elem" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "Nem követett tételek" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "Követett tételek" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "Tétel típusa" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "Válasszon tétel típust az automatikus foglaláshoz" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Alkatrészjegyzék Hivatkozás" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "Alkatrészjegyzék Cikk Azonosító" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Alkatrészjegyzék Alkatrész Név" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "Beépítés helye" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Gyártás" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Beszállítói alkatrész" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Lefoglalt mennyiség" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Gyártási Hivatkozás" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Alkatrész kategória Neve" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Követésre kötelezett" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Örökölt" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Változatok" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Alkatrészjegyzék tétel" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "Gyártásban" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Gyártás Ütemezve" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Külső raktárkészlet" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Elérhető készlet" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Elérhető Helyettesítő Készlet" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Elérhető Készlet Változatokból" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "Felhasznált mennyiség meghaladja a lefoglalt mennyiséget" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Megjegyzés a készletfelhasználáshoz" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "Gyártási tételnek a megfelelő gyártási rendelésre kell mutatnia" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Dupla gyártási tétel lefoglalás" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "Gyártási sornak a megfelelő gyártási rendelésre kell mutatnia" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Duplikált gyártási sor foglalás" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Legalább egy tétel vagy sor megadása kötelező" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Függőben" @@ -1471,59 +1556,76 @@ msgid "Production" msgstr "Folyamatban" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Felfüggesztve" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Törölve" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Kész" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "A {build} gyártási utasítás elkészült" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Gyártási utasítás elkészült" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "A gyártási utasításhoz készlet szükséges" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "A {build} gyártási rendelésnek további készletre van szüksége" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Késésben lévő gyártás" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "A {bo} gyártás most már késésben van" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "Ez egy hivatkozás" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Ez egy állomány" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "A felhasználó nem jogosult ezen mellékletek törlésére" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "A felhasználó nem jogosult ezen melléklet törlésére" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Választéklista lezárva" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Érvénytelen valuta kód" @@ -1540,15 +1642,20 @@ msgstr "Hiányzó érvényes valuta kód" msgid "No plugin" msgstr "Nincsen plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Projekt kód címke" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Frissítve" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Legutóbbi frissítés időpontja" @@ -1568,794 +1675,844 @@ msgstr "Egyedi projektszám" msgid "Project description" msgstr "Projekt leírása" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "A projektért felelős felhasználó vagy csoport" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Beállítási kulcs" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Beállítás értéke" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "A kiválasztott érték nem egy érvényes lehetőség" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Az érték bináris kell legyen" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Az érték egész szám kell legyen" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Az értéknek számnak kell lennie" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Az érték nem felel meg az ellenőrzéseknek" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Kulcs string egyedi kell legyen" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Felhasználó" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Ársáv mennyiség" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Ár" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Egységár egy meghatározott mennyiség esetén" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Végpont" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Végpont ahol ez a webhook érkezik" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Webhook neve" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktív" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "A projektért felelős felhasználó vagy csoport" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Beállítási kulcs" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Beállítás értéke" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "A kiválasztott érték nem egy érvényes lehetőség" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Az érték bináris kell legyen" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Az érték egész szám kell legyen" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Az értéknek számnak kell lennie" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Az érték nem felel meg az ellenőrzéseknek" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Kulcs string egyedi kell legyen" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Felhasználó" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Ársáv mennyiség" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Ár" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Egységár egy meghatározott mennyiség esetén" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Végpont" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Végpont ahol ez a webhook érkezik" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Webhook neve" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Aktív-e ez a webhook" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token a hozzáféréshez" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Titok" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Megosztott titok a HMAC-hoz" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Üzenet azonosító" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Egyedi azonosító ehhez az üzenethez" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Kiszolgáló" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Kiszolgáló ahonnan ez az üzenet érkezett" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Fejléc" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Üzenet fejléce" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Törzs" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Üzenet törzse" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Végpont amin ez az üzenet érkezett" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Dolgozott rajta" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Befejeződött a munka ezzel az üzenettel?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Azonosító" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Cím" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Közzétéve" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Szerző" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Összefoglaló" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Elolvasva" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Elolvasva?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Képfájl" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "A képhez tartozó model típus" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "A képhez tartozó model azonosító" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Egyedi mértékegység" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "A mértékegység szimbólumának egyedinek kell lennie" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "A mértékegységnek valós azonosítónak kell lennie" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Egység neve" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Szimbólum" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Opcionális mértékegység szimbólum" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definíció" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Mértékegység definíció" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Melléklet" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Hiányzó fájl" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Hiányzó külső link" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Modell típusa" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Képhez tartozó model típus" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Válaszd ki a mellekelni kívánt fájlt" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Megjegyzés" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Melléklet megjegyzés" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Feltöltés dátuma" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "A fájl feltöltésének dátuma" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Fájl mérete" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Fájlméret bájtban" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "A melléklet model típusa érvénytelen" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Egyedi Állapot" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Egyedi Állapotok" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Hivatkozott Állapot Készlet" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Az az Állapot készlet, melyet ez az egyedi állapot kibővít" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logikai kulcs" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Az állapot logikai kulcsa amely megegyezik az üzleti logika egyedi állapotával" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Érték" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "A model adatbázisba tárolandó szám" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Az állapot neve" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Címke" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "A felületen megjelenített címke" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Szín" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "A felöleten megjelenő szín" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "A Model amihez ez az állapot tartozik" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Modelt választani kötelező" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Kulcsot választani kötelező" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Logikai kulcsot választani kötelező" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "A kulcs és a logikai kulcs nem lehet azonos" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Helyes hivatkozási állapot osztályt kell megadni" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "A kulcsnak eltérőnek kell lennie a hivatkozott állapotok logikai kulcsaitól" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "A logikai kulcsnak szerepelnie kell a hivatkozott állapotok logikai kulcsai közt" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "A Névnek el kell térnie a referencia állapotok neveitől" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Választéklista" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Választéklisták" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Választéklista neve" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Választéklista leírása" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Lezárt" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Választéklista lezárva?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Választéklista használható?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Forrás plugin" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Választéklista szolgáltató plugin" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Forrás szöveg" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Elhagyható lista forrás azonosító szöveg" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Alapértelmezett bejegyzés" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Alapértelmezett elem ezen a listán" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Létrehozva" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Választéklista létrehozási dátuma és ideje" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Utoljára módosítva" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "A választéklista utolsó módosításának dátuma és ideje" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Választéklista bejegyzés" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Választéklista bejegyzések" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Választéklista amihez ez a bejegyzés tartozik" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Választéklista bejegyzés értéke" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Választéklista bejegyzés felirata" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Választéklista bejegyzés leírása" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Választéklista bejegyzés aktív?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Paraméter sablon" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "Paraméter Sablonok" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Jelölőnégyzet paraméternek nem lehet mértékegysége" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Jelölőnégyzet paraméternek nem lehetnek választási lehetőségei" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "A lehetőségek egyediek kell legyenek" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "A paraméter sablon nevének egyedinek kell lennie" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "Célmodell típusa ehhez a paramétersablonhoz" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Paraméter neve" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Mértékegység" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Paraméter mértékegysége" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Paraméter leírása" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Jelölőnégyzet" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Ez a paraméter egy jelölőnégyzet?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Lehetőségek" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Választható lehetőségek (vesszővel elválasztva)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "A paraméter választéklistája" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Engedélyezve" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "Ez a paramétersablon engedélyezett?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "Paraméter" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "Paraméterek" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Hibás választás a paraméterre" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "Érvénytelen modelltípus megadva a paraméterhez" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "Modell ID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "A célmodell azonosítója ehhez a paraméterhez" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Sablon" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "Paraméter sablon" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Adat" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Paraméter értéke" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Megjegyzés" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Opcionális megjegyzés mező" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Vonalkód beolvasás" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Vonalkód adat" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Melyik felhasználó olvasta be a vonalkódot" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Időbélyeg" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Vonalkód beolvasás dátuma és ideje" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Vonalkód feldolgozó URL végpont" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Kontextus" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Vonalkód olvasás kontextus adat" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Válasz" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Vonalkód olvasó válasz adat" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Eredmény" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Vonalkód olvasás sikeres volt?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Hiba történt" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: Email napló törlés védett. Állítsd be az INVENTREE_PROTECT_EMAIL_LOG-ot False-ra hogy engedélyezd a törlést." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "E-mail üzenet" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "E-mail üzenetek" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Bejelentve" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Elküldve" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Megbukott" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Kiszállítva" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Megerősítve" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Bejövő" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Kimenő" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Nincs válasz" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Kiszállítás követése" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Olvasási visszaigazolás" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Kattintások nyomkövetése" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "Globális ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Üzenet azonosítója (külső rendszertől származhat)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "Szál ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Üzenet-sor azonosító (külső rendszerből származhat)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Szál" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Ehhez az üzenethez kapcsolódó üzenet-lánc" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "Prioritás" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "Email szál" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "Email szálak" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Kulcs" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Az üzenetlánc egyedi azonosítója (az üzenetlánc azonosítására szolgál)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Üzenetlánc egyedi azonosítója" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Belső kezdés" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Ez az üzenetlánc belül indult?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Az üzenetlánc kezdeti dátuma és ideje" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Az üzenetlánc utolsó módosításának dátuma és ideje" @@ -2377,7 +2534,7 @@ msgstr "{verbose_name} megszakítva" msgid "A order that is assigned to you was canceled" msgstr "Egy hozzád rendelt megrendelés megszakítva" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Készlet érkezett" @@ -2389,104 +2546,100 @@ msgstr "Készlet érkezett egy beszerzési megrendeléshez" msgid "Items have been received against a return order" msgstr "Készlet érkezett vissza egy visszavétel miatt" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "Jelzi, hogy a beállítás módosítása megerősítést igényel-e" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "Ez a beállítás módosítás előtt megerősítést igényel. Kérjük, erősítse meg a változtatást." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Ez a beállítás felül van bírálva egy környezeti változó által" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Felülbírálás" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Folyamatban" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Folyamatban lévő feladatok" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Ütemezett Feladatok" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Hibás feladatok" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Feladat ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Egyedi feladat ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Zárol" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Zárolási idő" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Feladat neve" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funkció" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Funkció neve" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Paraméterek" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Feladat paraméterei" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Kulcsszó paraméterek" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Feladat kulcsszó paraméterek" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Fájlnév" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Modell típusa" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "A felhasználónak nincs joga létrehozni vagy módosítani ehhez a modelhez tartozó mellékleteket" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "A felhasználónak nincs jogosultsága paraméterek létrehozására vagy szerkesztésére ehhez a modellhez" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Választéklista lezárva" - #: common/setting/system.py:97 msgid "No group" msgstr "Nincs csoport" @@ -2615,13 +2768,13 @@ msgstr "Árfolyam frissítési gyakoriság" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Milyen gyakran frissítse az árfolyamokat (nulla a kikapcsoláshoz)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "nap" @@ -2634,6 +2787,14 @@ msgid "Currency update plugin to use" msgstr "Kiválasztott árfolyam frissítő plugin" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Erős URL validáció" @@ -2761,947 +2922,1017 @@ msgstr "Vonalkód Generáló Plugin" msgid "Plugin to use for internal barcode data generation" msgstr "Belső vonalkód generálásra használatos plugin" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Alkatrész változatok" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Alkatrész változat vagy verziószám tulajdonság használata" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Csak Összeállítás Verzió" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Csak összeállított alkatrészeknek lehessen verziója" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Lehessen törölni az Összeállításból" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Lehessen olyan alkatrészt törölni ami Összeállításban szerepel" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN reguláris kifejezés" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Reguláris kifejezés ami illeszkedik az alkatrész IPN-re" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Többször is előforduló IPN engedélyezése" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Azonos IPN használható legyen több alkatrészre is" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "IPN szerkesztésének engedélyezése" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "IPN megváltoztatásánsak engedélyezése az alkatrész szerkesztése közben" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Alkatrészjegyzék adatok másolása" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Alkatrész másoláskor az alkatrészjegyzék adatokat is másoljuk alapból" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Alkatrész paraméterek másolása" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Alkatrész másoláskor a paramétereket is másoljuk alapból" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Alkatrész teszt adatok másolása" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Alkatrész másoláskor a tesztek adatait is másoljuk alapból" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kategória paraméter sablonok másolása" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Kategória paraméter sablonok másolása alkatrész létrehozásakor" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Alkatrészek alapból sablon alkatrészek legyenek" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Alkatrészeket alapból lehessen gyártani másik alkatrészekből" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Összetevő" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Alkatrészek alapból használhatók összetevőként más alkatrészekhez" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Beszerezhető" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Alkatrészek alapból beszerezhetők legyenek" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Értékesíthető" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Alkatrészek alapból eladhatók legyenek" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Alkatrészek alapból követésre kötelezettek legyenek" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuális" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Alkatrészek alapból virtuálisak legyenek" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Kapcsolódó alkatrészek megjelenítése" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Alkatrész kapcsolódó alkatrészeinek megjelenítése" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Kezdeti készlet adatok" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Kezdeti készlet létrehozása új alkatrész felvételekor" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Kezdeti beszállítói adatok" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Kezdeti beszállítói adatok létrehozása új alkatrész felvételekor" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Alkatrész név megjelenítés formátuma" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formátum az alkatrész név megjelenítéséhez" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Alkatrész kategória alapértelmezett ikon" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Alkatrész kategória alapértelmezett ikon (üres ha nincs)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Áraknál használt tizedesjegyek min. száma" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Tizedejegyek minimális száma az árak megjelenítésekor" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Áraknál használt tizedesjegyek max. száma" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Tizedejegyek maximális száma az árak megjelenítésekor" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Beszállítói árazás használata" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Beszállítói ársávok megjelenítése az általános árkalkulációkban" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Beszerzési előzmények felülbírálása" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Beszerzési árelőzmények felülírják a beszállítói ársávokat" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Készlet tétel ár használata" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "A kézzel bevitt készlet tétel árak használata az árszámításokhoz" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Készlet tétel ár kora" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Az ennyi napnál régebbi készlet tételek kizárása az árszámításból" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Alkatrészváltozat árak használata" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Alkatrészváltozat árak megjelenítése az általános árkalkulációkban" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Csak az aktív változatokat" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Csak az aktív alkatrészváltozatok használata az árazásban" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Árazás automatikus frissítése" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Alkatrész árazás automatikus frissítése belső adat változáskor" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Árazás újraszámítás gyakoriság" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Árak automatikus frissítése ennyi nap után" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Belső árak" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Alkatrészekhez belső ár engedélyezése" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Belső ár felülbírálása" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Ha elérhetőek az árkalkulációkban a belső árak lesznek alapul véve" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "Nulla mennyiség engedélyezése az anyagjegyzékben" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Címke nyomtatás engedélyezése" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Címke nyomtatás engedélyezése a web felületről" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Címke kép DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Képek felbontása amik átadásra kerülnek címkenyomtató pluginoknak" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Riportok engedélyezése" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Riportok előállításának engedélyezése" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Debug mód" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Riportok előállítása HTML formátumban (hibakereséshez)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Jelentési hibák naplózása" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Jelentések generálása közben jelentkező hibák naplózása" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Lapméret" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Alapértelmezett lapméret a PDF riportokhoz" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Csak választható mértékegységek" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "A megadott mértékegység csak a beállított lehetőségekből legyen elfogadva" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Globálisan egyedi sorozatszámok" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "A sorozatszámoknak egyedinek kell lennie a teljes készletre vonatkozóan" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Kimerült készlet törlése" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Alapértelmezett művelet mikor a készlet tétel elfogy" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Batch kód sablon" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Sablon a készlet tételekhez alapértelmezett batch kódok előállításához" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Készlet lejárata" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Készlet lejárat kezelésének engedélyezése" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Lejárt készlet értékesítése" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Lejárt készlet értékesítésének engedélyezése" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Álló készlet ideje" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Napok száma amennyivel a lejárat előtt a készlet tételeket állottnak vesszük" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Lejárt készlet gyártása" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Gyártás engedélyezése lejárt készletből" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Készlet tulajdonosok kezelése" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Tulajdonosok kezelésének engedélyezése a készlet helyekre és tételekre" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Hely alapértelmezett ikon" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Hely alapértelmezett ikon (üres ha nincs)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Beépített készlet megjelenítése" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Beépített készlet tételek megjelenítése a készlet táblákban" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Tételek telepítésekor a darabjegyzék ellenőrzése" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "A beépített tételeknek a szülő elem darabjegyzékében szerepelniük kell" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Lehet Hiányzó Készletet Mozgatni" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Lehet-e olyan készleteket mozgatni készlethelyek között amik nincsenek raktáron" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Gyártási utasítás azonosító minta" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Szükséges minta a gyártási utasítás azonosító mező előállításához" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Felelős tulajdonos szükséges" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Minden rendeléshez felelőst kell rendelni" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Szükséges Aktív Alkatrész" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Inaktív alkatrészekre nem lehet Gyártási Rendelést létrehozni" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Elvárás a Lezárt Alkatrész" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Megakadályozza, hogy nem lezárt alkatrészekre gyártási rendelést lehessen indítani" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Jóváhagyott Alkatrészjegyzék Kötelező" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Megakadályozza gyártási rendelés készítését ha nincsen az Alkatrészjegyzék jóváhagyva" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Leszármazott Gyártásoknak Lezártnak Kell Lennie" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Amíg minden leszármazott gyártás le nincsen zárva nem lehet a szülő gyártást lezárni" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Külső Gyártási Rendelések" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Engedélyezze a külső gyártási rendelés funkciót" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blokkolás a tesztek sikeres végrehajtásáig" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Nem lehet gyártási tételt befejezni amíg valamennyi kötelező teszt sikeres nem lett" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Visszavétel engedélyezése" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Visszavételek engedélyezése a felületen" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Visszavétel azonosító minta" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Szükséges minta a visszavétel azonosító mező előállításához" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Befejezett visszavétel szerkesztése" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Visszavétel szerkesztésének engedélyezése befejezés után" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Vevői rendelés azonosító minta" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Szükséges minta a vevői rendelés azonosító mező előállításához" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Vevői rendeléshez alapértelmezett szállítmány" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Szállítmány automatikus létrehozása az új vevő rendelésekhez" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Befejezett vevői rendelés szerkesztése" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Vevői rendelések szerkesztésének engedélyezése szállítás vagy befejezés után" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "Szállítmány Ellenőrzést Igényel" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Megakadályozza a szállítmányok befejezését, amíg a tételeket nem ellenőrizték" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Leszállított Rendelések Készre jelölése" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Leszállítottnak jelölt Értékesítési rendelések automatikusan Kész-re lesznek állítva, a \"Leszállított\" állapot átugrásával" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Beszerzési rendelés azonosító minta" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Szükséges minta a beszerzési rendelés azonosító mező előállításához" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Befejezett beszerzési rendelés szerkesztése" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Beszérzési rendelések szerkesztésének engedélyezése kiküldés vagy befejezés után" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Jelenlegi pénznem" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Tétel érték bázis-pénznemre váltása készlet beérkezéskor" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Beszerzési rendelések automatikus befejezése" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "A beszerzési rendelés automatikus befejezése ha minden sortétel beérkezett" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Elfelejtett jelszó engedélyezése" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Elfelejtett jelszó funkció engedélyezése a bejentkező oldalon" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Regisztráció engedélyezése" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Felhaszálók önkéntes regisztrációjának engedélyezése a bejelentkező oldalon" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "SSO engedélyezése" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "SSO engedélyezése a bejelentkező oldalon" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "SSO regisztráció engedélyezése" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Felhaszálók önkéntes regisztrációjának engedélyezése SSO-n keresztül a bejelentkező oldalon" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "SSO csoport szinkronizálás engedélyezése" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Az InvenTree csoportok szinkronizálása a hitelesítésszolgáltatóhoz" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSO csoport kulcs" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "A csoportkérés tulajdonság neve amit a hitelesítésszolgáltató nyújt" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "SSO csoport hozzárendelés" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Az SSO csoportok hozzárendelése az InvenTree csoportokhoz. Ha a helyi csoport nem létezik, létre lesz hozva." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Az SSO-n kívüli csoportok eltávolítása" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Ha egy felhasználóhoz rendelt csoport nem létezik az azonosításszolgáltatóban azt eltávolítsuk el. Ennek a kikapcsolása biztonsági problémákhoz vezethet" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email szükséges" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Kötelező email megadás regisztrációkor" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "SSO felhasználók automatikus kitöltése" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Felhasználó adatainak automatikus kitöltése az SSO fiókadatokból" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Email kétszer" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Regisztráláskor kétszer kérdezze a felhasználó email címét" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Jelszó kétszer" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Regisztráláskor kétszer kérdezze a felhasználó jelszavát" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Engedélyezett domainek" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Feliratkozás korlátozása megadott domain-ekre (vesszővel elválasztva, @-al kezdve)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Csoport regisztráláskor" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Ehhez a csoporthoz lesznek az új felhasználók rendelve. Ha az SSO csoport szinkronizálás engedélyezve van, akkor ez a csoport csak akkor lesz hozzárendelve a felhasználóhoz ha az azonosítás szolgáltató semmilyen csoportot nem rendelt hozzá." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Többfaktoros hitelesítés kényszerítése" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "A felhasználóknak többfaktoros hitelesítést kell használniuk." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Pluginok ellenőrzése indításkor" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Ellenőrizze induláskor hogy minden plugin telepítve van - engedélyezd konténer környezetben (docker)" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Plugin frissítések ellenőrzése" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Frissítések periódikus ellenőrzésének engedélyezése a telepített pluginokra" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "URL integráció engedélyezése" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "URL útvonalalak hozzáadásának engedélyezése a pluginok számára" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Navigációs integráció engedélyezése" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Navigációs integráció engedélyezése a pluginok számára" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "App integráció engedélyezése" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "App hozzáadásának engedélyezése a pluginok számára" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Ütemezés integráció engedélyezése" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Háttérben futó feladatok hozzáadásának engedélyezése a pluginok számára" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Esemény integráció engedélyezése" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Belső eseményekre reagálás engedélyezése a pluginok számára" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Interfész integráció engedélyezése" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Pluginok felhasználói felületbe épülésének engedélyezése" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Email integráció engedélyezése" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Pluginok bejövő/kimenő levelekhez hozzáférésének engedélyezése" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Projektszámok engedélyezése" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Projectek nyomkövetéséhez projekt kódok engedélyezése" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "A készletek korábbi mennyiségének és értékének naplózásának engedélyezés" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Külső helyek nélkül" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Automatikus leltár időpontja" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "Készlettörténet törlési gyakoriság" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Felhasználók teljes nevének megjelenítése" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Felhasználói név helyett a felhasználók teljes neve jelenik meg" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Felhasználói profilok megjelenítése" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Felhasználói profilok megjelenítése a profil oldalukon" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Teszt állomás adatok engedélyezése" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Tesztállomás adatok gyűjtésének teszt eredménybe gyűjtésének engedélyezése" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "Gép Ping Engedélyezése" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Időszakos ping feladat engedélyezése a regisztrált gépekhez az állapotuk ellenőrzésére" @@ -3882,213 +4113,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "A keresési előnézetben megjelenítendő eredmények száma szekciónként" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Regex keresés" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Reguláris kifejezések engedélyezése a keresésekben" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Teljes szó keresés" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "A keresések csak teljes szóra egyező találatokat adjanak" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Megjegyzések keresése" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "A keresések a tétel jegyzeteiben is keresnek" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "ESC billentyű zárja be a formot" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "ESC billentyű használata a modális formok bezárásához" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Rögzített menüsor" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "A menü pozíciója mindig rögzítve a lap tetején" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "Fix táblázat fejlécek" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Táblázat fejlécek rögzítve vannak a táblázat tetejéhez" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Reflektorfény megjelenítése" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Reflektorfény navigációs funkció engedélyezése" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Navigációs ikonok" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Ikonok megjelenítése a navigációs sávon" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Dátum formátum" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Preferált dátum formátum a dátumok kijelzésekor" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Készlettörténet mutatása" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Készlet történet mutatása az alkatrész részletes nézetén" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Az utolsó navigációs morzsa megjelenítése" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Az aktuális oldal mutatása a morzsák közt" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Teljes készlethely mutatása a táblákban" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Letiltva: A teljes készlethely elérési út megjelenik tooltipben ha fölé megy az egér. Engedélyezve: a teljes elérési út látszik szövegesen." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Teljes alkatrész kategória mutatása táblázatokban" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Letiltva: A teljes kategória elérési út megjelenik tooltipként. Engedélyezve: A teljes kategória elérési út megjelenik szövegként." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Hibariportok fogadása" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Értesítések fogadása a rendszerhibákról" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Utoljára használt nyomtató gépek" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Az utoljára használt nyomtató tárolása a felhasználóhoz" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Minden modell" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "A melléklethez nem tartozik model típus" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Érvénytelen melléklet model típus" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "A legkisebb helyiérték nem lehet nagyobb mint a legnagyobb helyiérték" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "A legnagyobb helyiérték nem lehet kisebb mint a legkisebb helyiérték" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Üres domain nem engedélyezett." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Érvénytelen domain név: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Csupa nagybetűs kell" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Az érték egy változó neve legyen" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Az alkatrész aktív" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "A Gyártó Aktív" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "A Szállítói Alkatrész Aktív" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "A saját alkatrész Aktív" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "A Beszállító Aktív" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Gyártó" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Cég" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Van készleten" @@ -4124,8 +4388,8 @@ msgstr "Kapcsolattartó telefonszáma" msgid "Contact email address" msgstr "Kapcsolattartó email címe" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Névjegy" @@ -4177,283 +4441,283 @@ msgstr "Adószám" msgid "Company Tax ID" msgstr "Céges adószám" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Cím" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Címek" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Cég kiválasztása" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Cím megnevezése" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Címhez tartozó leírás, megnevezés" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Elsődleges cím" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Beállítás elsődleges címként" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "1. sor" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Cím első sora" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "2. sor" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Cím második sora" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Irányítószám" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Város/Régió" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Irányítószám város/régió" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Állam/Megye" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Állam vagy megye" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Ország" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Cím országa" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Megjegyzés a futárnak" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Futárnak szóló megjegyzések" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Belső szállítási megjegyzések" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Szállítási megjegyzések belső használatra" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Link a címinformációkhoz (külső)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Gyártói alkatrész" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Kiindulási alkatrész" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Válassz alkatrészt" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Gyártó kiválasztása" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN (Gyártói cikkszám)" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Gyártói cikkszám" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL link a gyártói alkatrészhez" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Gyártói alkatrész leírása" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "A csomagolási egységnek kompatibilisnek kell lennie az alkatrész mértékegységgel" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Csomagolási mennyiségnek nullánál többnek kell lennie" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Kapcsolódó gyártói alkatrésznek ugyanarra a kiindulási alkatrészre kell hivatkoznia" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Beszállító" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Beszállító kiválasztása" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Beszállítói cikkszám" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Ez a szállítói termék aktív?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "Elsődleges" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Gyártói alkatrész kiválasztása" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL link a beszállítói alkatrészhez" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Beszállítói alkatrész leírása" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "alap költség" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimális díj (pl. tárolási díj)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Csomagolás" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Alkatrész csomagolás" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Csomagolási mennyiség" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Egy csomagban kiszállítható mennyiség, hagyd üresen az egyedi tételeknél." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "többszörös" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Többszörös rendelés" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Beszállítónál elérhető mennyiség" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Elérhetőség frissítve" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Utolsó elérhetőségi adat frissítés" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Beszállítói Ár Kedvezmény" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Beszállító által használt alapértelmezett pénznem" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Cégnév" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Készleten" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Árkategóriák" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Hiba történt adatexportálás közben" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Az adatexportáló plugin téves adatformátumot adott vissza" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Export formátum" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Export file formátum kiválasztása" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Export plugin" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Export plugin kiválasztása" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "További állapot információk erről a tételről" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Saját Állapot Kulcs" @@ -4477,123 +4741,152 @@ msgstr "Kiküldve" msgid "Invalid status code" msgstr "Érvénytelen állapotkód" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Adat fájl" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Importálandó adatfájl" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Oszlopok" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Cél model típus ehhez az import munkához" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Betöltés állapota" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Mező Alapértelmezett Érték" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Mező Felülbírálás" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Mező Szűrők" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Frissítse a létező rekordokat" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Ha engedélyezett a meglévő rekordok frissítve lesznek az új adatokkal" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Néhány kötelező mező nem került hozzárendelésre" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Létező adatbázis azonosító a rekordhoz" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "Oszlop már adatbázis mezőhöz lett rendelve" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Adatbázis mező már adatfájl oszlophoz lett rendelve" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Az oszlop összerendelésnek egy helyes importálási művelethez kell kapcsolódnia" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Az Oszlop nem létezik ebben a fájlban" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "A mező nem létezik a cél adatszerkezetben" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Kijelölt mező csak olvasható" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Importálási művelet" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Mező" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Oszlop" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Sor száma" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Eredeti sor adat" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Hibák" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Érvényes" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "ID-ra van szükség meglévő rekord frissítéshez." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Nem található rekord a megadott ID-vel" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Érvénytelen az ID formátuma" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "ID-ra van szükség meglévő rekord frissítéshez." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Nem támogatott adatfájl formátum" @@ -4601,43 +4894,47 @@ msgstr "Nem támogatott adatfájl formátum" msgid "Failed to open data file" msgstr "Adatfájl megnyitása sikertelen" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Az adatállomány méretei - szélessége nem megfelelő" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Érvénytelen mező alapértelmezések" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Érvénytelen mező felülbírálások" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Érvénytelen mező szűrések" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Sorok" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Az elfogadható azonosítók listája" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Nincs sor megadva" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "A sor nem az aktuális művelethez kapcsolódik" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "A Sor érvénytelen adatot tartalmaz" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "A sor már be lett fejezve" @@ -4673,115 +4970,115 @@ msgstr "Túl sok oszlop az adatfájlban" msgid "Data file contains too many rows" msgstr "Túl sok sor az adatfájlban" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Az értéknek a érvényes szótár elemnek kell lennie" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Másolatok" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Címkénkénti nyomtatandó mennyiség" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Csatlakoztatba" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Ismeretlen" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Nyomtatás" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Figyelmeztetés" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Nincs papír" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Elakadt a papír" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Nincs kapcsolat" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Hiba" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Címkenyomtató" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Közvetlen címkenyomtatás különféle tételekre." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Nyomtató helye" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Nyomtató korlátozása egy készlethelyhez" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Gép neve" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Géptípus" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Gép típusa" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Illesztőprogram" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Berendezéshez használható meghajtó" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "A berendezések letilthatók" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Meghajtó elérhető" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Nincsen hiba" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Inicializálva" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Gép állapot" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Gép" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Gép konfiguráció" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Konfiguráció típusa" @@ -4793,7 +5090,7 @@ msgstr "A tulajdonság kulcsa" msgid "Value of the property" msgstr "A tulajdonság értéke" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Csoport" @@ -4817,117 +5114,118 @@ msgstr "Maximális Előrehaladás" msgid "Maximum value for progress type, required if type=progress" msgstr "Maximális érték az előrehaladás típushoz, kötelező ha típus=előrehaladás" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Rendelés azonosítója" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Kintlévő" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Van projektszáma" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Készítette" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Ez előtt létrehozva" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Létrehozva ez után" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Van kezdeti dátum" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Kezdeti dátum ez előtt" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Kezdeti dátum ez után" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Van céldátum" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Céldátum ez előtt" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Céldátum ez után" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Van árazás" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Ez előtt befejezve" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Befejezve ez után" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Külső Gyártási Rendelés" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Rendelés" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "A rendelés teljesítve" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Belső alkatrész" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "A rendelés függőben" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Kész" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Van kiszállítás" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Beszerzési rendelés" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4935,782 +5233,891 @@ msgstr "Beszerzési rendelés" msgid "Sales Order" msgstr "Vevői rendelés" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Visszavétel" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Teljes ár" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "A rendelés teljes ára" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Rendelés pénzneme" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Megrendeléshez használt pénznem (hagyd üresen a cégnél alapértelmezetthez)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Egy a rendelés le van zárva és nem lehet módosítani" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "A kapcsolattartó nem egyezik a kiválasztott céggel" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "A kezdeti dátumnak meg kell előznie a céldátumot" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "A cím nem egyezik a kiválasztott vállalattal" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Rendelés leírása (opcionális)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Válassz projektszámot ehhez a rendeléshez" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Link külső weboldalra" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Kezdés dátuma" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "A tervezett kezdeti dátum ehhez a gyártáshoz" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Cél dátum" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Várt teljesítési dátuma a megrendelésnek. Ezután már késésben lévőnek számít majd." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Kiállítás dátuma" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Kiállítás dátuma" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "Frissítve" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Felhasználó vagy csoport aki felelőse ennek a rendelésnek" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Kapcsolattartó ehhez a rendeléshez" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Cég címei ehhez a rendeléshez" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Rendelés azonosító" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Állapot" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Beszerzési rendelés állapota" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Cég akitől a tételek beszerzésre kerülnek" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Beszállítói azonosító" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Beszállítói rendelés azonosító kód" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "érkeztette" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Rendelés teljesítési dátuma" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Cél" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Beérkezett tételek tárolója" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Az alkatrész beszállítója meg kell egyezzen a beszerzési rendelés beszállítójával" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Sortétel nem egyezik a beszerzési megrendeléssel" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "Sortételen hiányzik a kapcsolódó alkatrész" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Mennyiség pozitív kell legyen" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Vevő" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Cég akinek a tételek értékesítésre kerülnek" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Értékesítési rendelés állapot" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Vevői azonosító " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Megrendelés azonosító kódja a vevőnél" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Kiszállítás dátuma" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "szállította" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Sortétel nincs hozzárendelve ehhez a rendeléshez" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Nincs találat a következő sorozatszámokra" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Az alábbi sorozatszámok nem elérhetők" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Rendelés már teljesítve" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Rendelés már visszavonva" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Csak nyitott rendelés jelölhető késznek" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "A rendelés nem jelölhető késznek mivel függő szállítmányok vannak" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "A rendelést nem lehet befejezni mert hiányos foglalások vannak" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "A rendelés nem jelölhető késznek mivel nem teljesített sortételek vannak" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "A rendelés le van zárva és nem lehet módosítani" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Tétel mennyiség" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Sortétel azonosító" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Sortétel megjegyzései" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Cél dátuma ennek a sortételnek (hagyd üresen a rendelés céldátum használatához)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Sortétel leírása (opcionális)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "További kontextus ehhez a sorhoz" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Egységár" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Vevői Rendelés Sortétel" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Beszállítói alkatrésznek egyeznie kell a beszállítóval" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "Gyártási rendelést külsőnek kell jelölni" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Gyártási rendeléseket csak összeszerelhető alkatrészekhez lehet kapcsolni" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "Gyártási rendelés alkatrészének meg kell egyeznie a sortétel alkatrésszel" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Beszállítói alkatrész" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Beérkezett" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Érkezett tételek száma" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Beszerzési ár" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Beszerzési egységár" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Külső gyártási rendelés amit ez a sortétel teljesít" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Vevői Rendelés Extra Sor" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Vevői Rendelés Sortétel" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Csak értékesíthető alkatrészeket lehet vevői rendeléshez adni" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Eladási ár" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Eladási egységár" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Kiszállítva" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Szállított mennyiség" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Vevői Rendelés Szállítása" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "A szállítási címnek egyeznie kell az ügyféllel" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Szállítási cím ehhez a szállítmányhoz" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Szállítás dátuma" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Szállítási dátum" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Kézbesítés dátuma" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Ellenőrizte" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Felhasználó aki ellenőrizte ezt a szállítmányt" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Szállítmány" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Szállítmány száma" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Nyomkövetési szám" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Szállítmány nyomkövetési információ" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Számlaszám" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Hozzátartozó számla referencia száma" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Szállítmány már elküldve" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Szállítmány nem tartalmaz foglalt készlet tételeket" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "A szállítmányt ellenőrizni kell, mielőtt befejezhetné" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Vevői Rendelés Extra Sor" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Vevői rendeléshez foglalások" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Készlet tétel nincs hozzárendelve" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Nem foglalható készlet egy másik fajta alkatrész sortételéhez" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Nem foglalható készlet egy olyan sorhoz amiben nincs alkatrész" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "A lefoglalandó mennyiség nem haladhatja meg a készlet mennyiségét" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Lefoglalt mennyiségnek nullánál többnek kell lennie" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Egyedi követésre kötelezett tételeknél a menyiség 1 kell legyen" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Vevői rendelés nem egyezik a szállítmánnyal" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Szállítmány nem egyezik a vevői rendeléssel" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Sor" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Vevői rendelés szállítmány azonosító" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Tétel" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Válaszd ki a foglalásra szánt készlet tételt" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Készlet foglalási mennyiség megadása" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Visszavétel azonosító" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Cég akitől a tételek visszavételre kerülnek" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Visszavétel állapota" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Visszavétel sortétel" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Készlettételt meg kell adni" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Visszavétel mennyisége meghaladja a készletet" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "Visszavétel mennyisége nullánál nagyobb kell, hogy legyen" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Érvénytelen mennyiség szerializált készlettételnél" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Válaszd ki a vevőtől visszavenni kívánt tételt" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Visszavétel dátuma" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Kimenetel" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Sortétel végső kimenetele" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Sortétel visszaküldésének vagy javításának költsége" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Visszavétel extra tétel" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "Rendelés azonosító" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "A duplikálandó megrendelés száma" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Sorok másolása" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Sortételek másolása az eredeti rendelésről" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Extra sorok másolása" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Az eredeti rendelés extra tételeinek másolása" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Paraméterek másolása" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Sortételek" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Kész sorok" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Rendelés duplikálása" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Rendelés másolás beállításai" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Érvénytelen rendelés ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Beszállító neve" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "A rendelést nem lehet törölni" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Rendelés lezárása teljesítetlen sortételek esetén is" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "A rendelésben teljesítetlen sortételek vannak" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "A rendelés nem nyitott" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Automata árazás" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Beszerzési ár automatikus számítása a beszállítói alkatrész adatai alapján" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Beszérzési ár pénzneme" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Elemek összevonása" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Azonos forrás és cél dátumú Alkatrész tételeinek összevonása egy tételre" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU (leltári azonosító)" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Belső cikkszám" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Belső cikkszám" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Beszállítói alkatrészt meg kell adni" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Beszerzési rendelést meg kell adni" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "A beszállítónak egyeznie kell a beszerzési rendelésben lévővel" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "A beszerzési rendelésnek egyeznie kell a beszállítóval" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Sortétel" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Válassz cél helyet a beérkezett tételeknek" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Írd be a batch kódját a beérkezett tételeknek" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Lejárati dátum" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Írd be a beérkező készlet tételek lejárati dátumát" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Írd be a sorozatszámokat a beérkezett tételekhez" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Bejövő készlettételek csomagolási információjának felülbírálata" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Kiegészítő megjegyzés beérkező készlettételekhez" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Vonalkód" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Beolvasott vonalkód" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Ez a vonalkód már használva van" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Sortételt meg kell adni" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "A cél helyet kötelező megadni" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Megadott vonalkódoknak egyedieknek kel lenniük" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Szállítások" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Kész szállítmányok" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Eladási ár pénzneme" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Foglalt tételek" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Nincsenek szállítmány részletek megadva" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Sortétel nincs hozzárendelve ehhez a rendeléshez" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Mennyiség pozitív kell legyen" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Írd be a sorozatszámokat a kiosztáshoz" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Szállítmány kiszállítva" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Szállítmány nincs hozzárendelve ehhez a rendeléshez" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Nincs találat a következő sorozatszámokra" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Az alábbi sorozatszámok nem elérhetők" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Visszavétel sortétel" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Sortétel nem egyezik a visszavétellel" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "A sortétel már beérkezett" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Csak folyamatban lévő megrendelés tételeit lehet bevételezni" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Visszaküldési mennyiség" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Sortétel pénzneme" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Elveszett" @@ -5719,1279 +6126,1312 @@ msgstr "Elveszett" msgid "Returned" msgstr "Visszaküldve" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Folyamatban" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Visszavétel" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Javítás" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Csere" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Visszatérítés" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Elutasított" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Kiküldve" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Késésben lévő beszerzés" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "A {po} beszerzési rendelés most már késésben van" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Késésben lévő vevői rendelés" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "A {so} vevői rendelés most már késésben van" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Lejárt visszvételi utasítás" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "A {ro} Visszavételi utasítás már lejárt" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Csillagozott" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Csillagozottra szűrés" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Mélység" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Kategória mélységre szűrés" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Felső szint" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Csúcs készlethelyre szűrés" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Lépcsőzetes" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Szűrt eredmények tartalmazzák az alkategóriákat" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Szülő" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Szülő kategóriára szűrés" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Az adott kategória alkategóriáinak kihagyása" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Van találat" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Változat-e" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Változat" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Vannak Változatok" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "Alkatrészjegyzék ellenőrizve" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Kaszkád Kategóriák" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Ha igaz, tartalmazza az adott kategória alkategóriáiban lévő tételeket" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Szűrés numerikus kategória azonosító vagy a 'null' literál szerint" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Összeállított Alkatrész ellenőrizhető" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Összetevő alkatrész ellenőrizhető" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Használ" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Alkatrész kategória" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Alkatrész kategóriák" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Alapértelmezett hely" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Ebben a kategóriában lévő alkatrészek helye alapban" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Szerkezeti" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "A szerkezeti alkatrész kategóriákhoz nem lehet direktben alkatrészeket hozzáadni, csak az alkategóriáikhoz." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Alapértelmezett kulcsszavak" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Ebben a kategóriában évő alkatrészek kulcsszavai alapban" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ikon" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ikon (opcionális)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Nem lehet az alkatrészkategóriát szerkezeti kategóriává tenni, mert már vannak itt alkatrészek!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Alkatrészcsoport Paraméter Sablon" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Alapértelmezett érték" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Alapértelmezett paraméter érték" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Alkatrészek" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "Nem lehet törölni egy zárolt alkatrész paramétereit" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "Nem lehet módosítani egy zárolt alkatrész paramétereit" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Lezárt alkatrész nem törölhető" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Aktív alkatrész nem törölhető" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Összeállításban felhasznált alkatrész nem törölhető" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Az '{self}' alkatrész nem használható a '{parent}' alkatrészjegyzékében (mert rekurzív lenne)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Az '{parent}' alkatrész szerepel a '{self}' alkatrészjegyzékében (rekurzív)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "Az IPN belső cikkszámnak illeszkednie kell a {pattern} regex mintára" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Alkatrész nem lehes saját magának verziója" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Verziók csak összeállított alkatrészeknél engedélyezettek" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Nem lehet sablon alkatrészből új verziót csinálni" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "A szülő alkatrésznek azonos sablonra kell mutatnia" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Létezik már készlet tétel ilyen a sorozatszámmal" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Azonos IPN nem engedélyezett az alkatrészekre, már létezik ilyen" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Adott alkatrész verzióból már létezik egy." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Ilyen nevű, IPN-ű és reviziójú alkatrész már létezik." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Szerkezeti kategóriákhoz nem lehet alkatrészeket rendelni!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Alkatrész neve" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Sablon-e" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Ez egy sablon alkatrész?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Ez az alkatrész egy másik változata?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Ebből a sablonból" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Alkatrész leírása (opcionális)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Kulcsszavak" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Alkatrész kulcsszavak amik segítik a megjelenést a keresési eredményekben" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Alkatrész kategória" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN (Belső Cikkszám)" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Alkatrész változat vagy verziószám (pl. szín, hossz, revízió, stb.)" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Változat" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Ez egy másik alkatrész egy verziója?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Ennek a verziója" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Alapban hol tároljuk ezt az alkatrészt?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Alapértelmezett lejárat" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Lejárati idő (napban) ennek az alkatrésznek a készleteire" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimális készlet" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Minimálisan megengedett készlet mennyiség" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Alkatrész mértékegysége" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Gyártható-e ez az alkatrész más alkatrészekből?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Felhasználható-e ez az alkatrész más alkatrészek gyártásához?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Kell-e külön követni az egyes példányait ennek az alkatrésznek?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Lehet ehhez az alkatrészhez több ellenőrzési eredményt rögzíteni?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Rendelhető-e ez az alkatrész egy külső beszállítótól?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Értékesíthető-e önmagában ez az alkatrész a vevőknek?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Aktív-e ez az alkatrész?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Lezárt alkatrészt nem lehet szerkeszteni" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Ez egy virtuális nem megfogható alkatrész, pl. szoftver vagy licenc?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "Alkatrészjegyzék ellenőrizve" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Az alkatrész anyagjegyzéke érvényes?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Alkatrészjegyzék ellenőrző összeg" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Tárolt alkatrészjegyzék ellenőrző összeg" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Alkatrészjegyzéket ellenőrizte" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Alkatrészjegyzék ellenőrzési dátuma" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Létrehozó" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Alkatrész felelőse" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Több értékesítése" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Árszámítások gyorstárazásához használt pénznem" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimum alkatrészjegyzék költség" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Összetevők minimum költsége" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maximum alkatrészjegyzék költség" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Összetevők maximum költsége" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimum beszerzési ár" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Eddigi minimum beszerzési költség" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maximum beszerzési ár" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Eddigi maximum beszerzési költség" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimum belső ár" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Minimum költség a belső ársávok alapján" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maximum belső ár" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Maximum költség a belső ársávok alapján" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Minimum beszállítói ár" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Minimum alkatrész ár a beszállítóktól" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Maximum beszállítói ár" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Maximum alkatrész ár a beszállítóktól" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Minimum alkatrészváltozat ár" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Alkatrészváltozatok számolt minimum költsége" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Maximum alkatrészváltozat ár" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Alkatrészváltozatok számolt maximum költsége" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimum költség" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Minimum költség felülbírálása" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maximum költség" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Maximum költség felülbírálása" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Számított általános minimum költség" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Számított általános maximum költség" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Minimum eladási ár" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Minimum eladási ár az ársávok alapján" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Maximum eladási ár" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Maximum eladási ár az ársávok alapján" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Minimum eladási költség" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Eddigi minimum eladási ár" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Maximum eladási költség" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Eddigi maximum eladási ár" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Leltározható alkatrész" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Tételszám" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Egyedi készlet tételek száma a leltárkor" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Teljes készlet a leltárkor" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Dátum" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Leltározva ekkor" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Minimum készlet érték" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Becsült minimum raktárkészlet érték" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maximum készlet érték" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Becsült maximum raktárkészlet érték" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Alkatrész értékesítési ársáv" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Alkatrész Teszt Sablon" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Hibás sablon név - legalább egy alfanumerikus karakter kötelező" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Teszt sablont csak ellenőrizhetőre beállított alkatrészhez lehet csinálni" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Már létezik ilyen azonosítójú Teszt sablon ehhez az alkatrészhez" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Teszt név" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Add meg a teszt nevét" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Teszt azonosító" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Egyszerűsített Teszt azonosító" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Teszt leírása" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Adj hozzá egy leírást ehhez a teszthez" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Teszt engedélyezve?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Kötelező" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Szükséges-e hogy ez a teszt sikeres legyen?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Kötelező érték" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Szükséges-e hogy ennek a tesztnek az eredményéhez kötelezően érték legyen rendelve?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Kötelező melléklet" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Szükséges-e hogy ennek a tesztnek az eredményéhez kötelezően fájl melléklet legyen rendelve?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Választható lehetőségek ehhez a Teszthez (vesszővel elválasztva)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "Alkatrészjegyzék nem szerkeszthető mert az összeállítás le van zárva" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Alkatrészjegyzék nem szerkeszthető mert az összeállítás változat le van zárva" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Szülő alkatrész kiválasztása" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Al alkatrész" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Válaszd ki az alkatrészjegyzékben használandó alkatrészt" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Alkatrészjegyzék mennyiség ehhez az alkatrészjegyzék tételhez" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Ez az alkatrészjegyzék tétel opcionális" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Ez az alkatrészjegyzék tétel fogyóeszköz (készlete nincs követve a gyártásban)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Beállítás mennyiség" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "A gyártáshoz szükséges extra mennyiség, a beállási veszteséggel együtt" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Veszteség" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Becsült veszteség egy gyártásnál, százalékban kifejezve (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Kerekítési többszörös" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "A szükséges termelési mennyiség az érték legközelebbi többszöröséhez kerekítése" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Alkatrészjegyzék tétel azonosító" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Alkatrészjegyzék tétel megjegyzései" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Ellenőrző összeg" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Alkatrészjegyzék sor ellenőrző összeg" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Jóváhagyva" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Ez a BOM tétel jóvá lett hagyva" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Öröklődött" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Ezt az alkatrészjegyzék tételt az alkatrész változatok alkatrészjegyzékei is öröklik" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Alkatrészváltozatok készlet tételei használhatók ehhez az alkatrészjegyzék tételhez" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "A mennyiség egész szám kell legyen a követésre kötelezett alkatrészek esetén" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Al alkatrészt kötelező megadni" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Alkatrészjegyzék tétel helyettesítő" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "A helyettesítő alkatrész nem lehet ugyanaz mint a fő alkatrész" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Szülő alkatrészjegyzék tétel" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Helyettesítő alkatrész" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "1.rész" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "2.rész" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Válassz kapcsolódó alkatrészt" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Kapcsolati megjegyzés" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Alkatrész kapcsolat nem hozható létre önmagával" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Már létezik duplikált alkatrész kapcsolat" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Szülő Kategória" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Felsőbb szintű alkatrész kategória" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Alkategóriák" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Eredmények" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Eszerint a sablon szerint rögzített eredmények száma" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Beszerzési pénzneme ennek a készlet tételnek" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "A fájl nem kép" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Eredeti alkatrész" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Válassz eredeti alkatrészt a másoláshoz" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kép másolása" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Kép másolása az eredeti alkatrészről" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Alkatrészjegyzék másolása" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Alkatrészjegyzék másolása az eredeti alkatrészről" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Paraméterek másolása az eredeti alkatrészről" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Megjegyzések másolása" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Megjegyzések másolása az eredeti alkatrészről" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Teszt másolása" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "Teszt sablonok másolása az eredeti alkatrészről" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Kezdeti készlet mennyiség" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Add meg a kezdeti készlet mennyiséget. Ha nulla akkor nem lesz készlet létrehozva." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Kezdeti készlet hely" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Add meg a kezdeti készlet helyét" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Válassz beszállítót (hagyd üresen ha nem kell létrehozni)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Válassz gyártót (hagyd üresen ha nem kell létrehozni)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Gyártói cikkszám" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "A kiválasztott cég nem érvényes beszállító" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "A kiválasztott cég nem érvényes gyártó" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Van már ilyen gyártói alkatrész" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Van már ilyen beszállítói alkatrész" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Kategória neve" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Gyártásban" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Az alkatrészből jelenleg ennyi van gyártás alatt" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Már beütemezett de még nem kész gyártási mennyiség" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Készlet tételek" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Verziók" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Teljes készlet" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Nem lefoglalt készlet" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Variánsok Raktárkészlet" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Alkatrész másolása" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Kezdeti adatok másolása egy másik alkatrészről" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kép másolása" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Kép másolása az eredeti alkatrészről" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Alkatrészjegyzék másolása" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Alkatrészjegyzék másolása az eredeti alkatrészről" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Megjegyzések másolása" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Megjegyzések másolása az eredeti alkatrészről" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Teszt másolása" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Teszt sablonok másolása az eredeti alkatrészről" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Kezdeti készlet" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Kezdeti készlet mennyiség létrehozása" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Beszállító információ" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Kezdeti beszállító adatok hozzáadása" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Kategória paraméterek másolása" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Paraméter sablonok másolása a kiválasztott alkatrész kategóriából" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Meglévő kép" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "A meglévő alkatrész képfájl neve" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "A képfájl nem létezik" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Teljes alkatrészjegyzék jóváhagyása" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Gyártható" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Gyártásokhoz szükséges" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Gyártási rendelésekhez foglalva" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Értékesítési rendeléshez szükséges" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Értékesítési rendeléshez lefoglalva" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Minimum ár" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Számított minimum ár felülbírálása" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Minimum ár pénzneme" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Maximum ár" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Számított maximum ár felülbírálása" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Maximum ár pénzneme" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Frissítés" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Alkatrész árak frissítése" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Megadott pénznem átváltása {default_currency}-re sikertelen" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "A Minimum ár nem lehet nagyobb mint a Maximum ár" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "A Maximum ár nem lehet kisebb mint a Minimum ár" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Szülő összeállítás kiválasztása" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Összetevő alkatrész kijelölése" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Válassz alkatrészt ahonnan az alkatrészjegyzéket másoljuk" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Létező adat törlése" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Meglévő alkatrészjegyzék tételek törlése a másolás előtt" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Örököltekkel együtt" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Sablon alkatrészektől örökölt alkatrészjegyzék tételek használata" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Hibás sorok kihagyása" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Engedély a hibás sorok kihagyására" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Helyettesítő alkatrészek másolása" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Helyettesítő alkatrészek másolása az alkatrészjegyzék tételek másolásakor" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Alacsony készlet értesítés" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "A {part.name} alkatrész rendelkezésre álló készlete a megadott minimum alá csökkent" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "Álló készlet értesítés" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "1 készlet tétel közelít a lejárati idejéhez" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "{item_count} készlet tétel közelít a lejáratához" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "Nincs lejárati dátuma" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "{abs(days_diff)} napja lejárt" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Ma jár le" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} nap" @@ -7012,7 +7452,7 @@ msgstr "Minta" msgid "Installed" msgstr "Beépítve" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Plugin nem törölhető mivel még aktív" @@ -7024,23 +7464,23 @@ msgstr "Nincs megadva művelet" msgid "No matching action found" msgstr "Nincs egyező művelet" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Nincs egyező vonalkód" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Egyezés vonalkódra" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Model nem támogatott" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Model példány hiányzik" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Ez a vonalkód már egy másik tételé" @@ -7056,51 +7496,67 @@ msgstr "Nem található megfelelő beszállítói alkatrész" msgid "Multiple matching supplier parts found" msgstr "Több beszállítói alkatrész található" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Nincsen vonalkód adathoz illeszkedő plugin" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Beszállítói alkatrész található" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Ez a termék már bevételezve" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "A szállítói vonalkódhoz nincsen plugin találat" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Több egyező sortétel is található" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Nincs egyező sortétel" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Nincs értékesítési rendelés biztosítva" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Vonalkód nem egyezik egy létező készlet tétellel sem" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Készlet tétel nem egyezik a sortétellel" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Nincs elegendő" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Készlet tétel lefoglalva egy vevői rendeléshez" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Nincs elég információ" @@ -7109,23 +7565,23 @@ msgstr "Nincs elég információ" msgid "Found matching item" msgstr "Megtalált tétel" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Szállítói alkatrész nem illik a sortételhez" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Sortétel már elkészült" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "A tétel bevételezéséhez további információ szükséges" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Beszerzési rendelés tétele bevételezve" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Nem sikerült a sortételt érkeztetni" @@ -7262,21 +7718,21 @@ msgid "Provides native support for barcodes" msgstr "Alapvető vonalkód támogatást ad" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7306,11 +7762,11 @@ msgstr "Rövid Vonalkód Előtag" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "A rövid vonalkódok előtagjának beállítása hasznos lehet, ha több InvenTree példányt is használnak egy környezetben" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "Automatikus Gyártás létrehozás" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "Összeszerelésekhez automatikus gyártási rendelés készítése" @@ -7508,74 +7964,82 @@ msgid "Include Variant Items" msgstr "A változatos alkatrészeket is tartalmazza" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "Az alkatrész változatok készleteit is beleértse az árazási számításokba" +msgid "Include part variant stock in stocktake data" +msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "Készlet leltár exportáló" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "Készlet leltározási adatok exportálója" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "Minimum egység költség" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "Maximum egység költség" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "Minimum teljes költség" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "Maximum teljes költség" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "InvenTree UI Értesítések" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "InvenTree UI Értesítési módok" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree Email Értesítések" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "InvenTree Email Értesítési módok" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "Email értesítések engedélyezése" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "Email értesítések engedélyezése ennek az usernek" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree slack értesítések" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "InvenTree slack értesítési módok" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL az üzenetek küldéséhez egy a slack channel-re" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Link megnyitása" @@ -7629,12 +8093,12 @@ msgid "Provides native support for printing PDF labels" msgstr "PDF címkék nyomtatásához beépített támogatás" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Debug mód" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Debug mód engedélyezése - nyers HTML-t ad vissza PDF helyett" @@ -7654,55 +8118,55 @@ msgstr "utoljára használva" msgid "Options" msgstr "Opciók" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Címke oldal méret" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Címkék kihagyása" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Hagyjon ki ennyi számú címkét a címke ívek nyomtatásakor" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Szegély" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Az egyes címkék körüli margó" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Fekvő" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Fekvő módban nyomtatás" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Oldalmargó" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Oldal körüli margó mm-ben" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "Inventree Címke Ív Nyomtató" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Több címke egy ívre helyezése" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Címke túl nagy a lapmérethez képest" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Nem készült címke" @@ -7754,77 +8218,85 @@ msgstr "TME vonalkódok támogatása" msgid "The Supplier which acts as 'TME'" msgstr "A 'TME' beszállító" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Plugin telepítés letiltva" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Plugin telepítése sikeres" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin telepítve ide: {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Ez a plugin nem található a tárolóban" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "A plugin nem egy csomagolt plugin" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Plugin csomag neve nem található" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Csak a személyzeti felhasználók adminisztrálhatják a pluginokat" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Plugin eltávolítás letiltva" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Plugin nem eltávolítható mivel még aktív" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Kötelező plugint nem lehet uninstallálni" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Plugin nem uninstallálható mert mintaplugin" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "Plugin nem uninstallálható mert beépített plugin" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Plugin nincs telepítve" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Plugin telepítés nem található" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Plugin eltávolítása sikeres" @@ -7872,25 +8344,25 @@ msgstr "Kötelező plugin" msgid "Package Plugin" msgstr "Csomag plugin" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Bővítmény" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Nincs szerző" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "A '{p}' plugin nem kompatibilis az aktuális applikáció verzióval {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "A pluginhoz minimum {v} verzió kell" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "A pluginhoz maximum {v} verzió kell" @@ -8115,176 +8587,184 @@ msgstr "Konfiguráció törlése" msgid "Delete the plugin configuration from the database" msgstr "Plugin konfiguráció törlése az adatbázisból" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "Melyik felhasználóra érvényes ez a beállítás" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Tételek" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Plugin nem található" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Plugin nem támogatja a címkenyomtatást" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Érvénytelen címke méretek" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Nincs érvényes tétel megadva a sablonhoz" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Jogi információk" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "„Letter” méret" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Ilyen nevű Sablon fájl már létezik" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Sablon neve" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Sablon leírása" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Verziószám (automatikusan nő)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "A nyomtatáson a modelhez kapcsolás" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Jelentés kimenetének mentése mellékletként a kapcsolt model példányhoz nyomtatáskor" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Fájlnév minta" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Minta a fájlnevek előállításához" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Sablon engedélyezve" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "A sablon által célzott model típus" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Szűrők" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Sablon lekérdezés szűrők (vesszővel elválasztott kulcs=érték párok)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Sablon file" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Lapméret a PDF riportokhoz" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Jelentés fekvő nézetben" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "Összevonás" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "Jelentés renderelése a kiválasztott tételekhez" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Jelentés a {self.name} sablon alapján" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "Szintaxis hiba a sablonban" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "Hiba a jelentés renderelésekor" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Hiba a jelentés generálása során" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "Hiba a jelentés kimenetének összefésülése során" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Szélesség [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Címke szélessége, mm-ben" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Magasság [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Címke magassága, mm-ben" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Címkenyomtatási hiba" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Részlet" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Riport részlet fájl" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Részlet fájl leírása" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Eszköz" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Riport asset fájl" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Asset fájl leírása" @@ -8292,23 +8772,23 @@ msgstr "Asset fájl leírása" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Riport sablon kiválasztása" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "A jelentésben levő tételek azonosítója" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Címke sablon választás" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Nyomtató plugin" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Címkenyomtató plugin kiválasztása" @@ -8339,13 +8819,10 @@ msgstr "Szükséges alapanyagok" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Alkatrész képe" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Kiküldve" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Szükséges ehhez" @@ -8381,8 +8858,8 @@ msgstr "Összesen" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Sorozatszám" @@ -8406,7 +8883,7 @@ msgstr "Készlet tétel teszt riport" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Beépített tételek" @@ -8439,810 +8916,922 @@ msgstr "Nincs eredmény (szükséges)" msgid "No result" msgstr "Nincs eredmény" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "A képfile nem található" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image elem csak alkatrész példánynál használható" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image elem csak cég példánynál használható" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Hely mélységre szűrés" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Csúcs készlethelyre szűrés" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Szűrt eredmények tartalmazzák az alhelyeket" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Szülő hely" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Szülő helyre szűrés" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Alkatrész neve (kisbetű/nagybetű nem számít)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Az alkatrész neve tartalmazza (kisbetű/nagybetű nem számít)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Alkatrész neve (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "Alkatrész IPN (kisbetű/nagybetű nem számít)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "Alkatrész IPN tartalmazza (kisbetű/nagybetű nem számít)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "Alkatrész IPN (regexp)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Minimális készlet" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Maximális készlet" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Státuszkód" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Külső hely" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Felhasználva Gyártási Rendelésben" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Más készlettételbe beépítve" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Alkatrész fa" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Módosítva ezelőtt" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Frissítve ez után" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Leltárazva ezelőtt" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Leltárazva ezután" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Lejárat előtt" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Lejárat után" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Állott" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "Adj meg egy készlettétel azonosítót - PK-t - hogy a tétel és leszármazottai kihagyásához" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "Készlethelyek alábontása" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "Az al-készlethelyeket is beleértve" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Készlethely azonosító alapján szűrés vagy a 'null'-ra" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Mennyiség megadása kötelező" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Egy érvényes alkatrészt meg kell adni" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "A megadott beszállítói alkatrész nem létezik" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "A beszállítói alkatrészhez van megadva csomagolási mennyiség, de a use_pack_size flag nincs beállítva" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Sorozatszámot nem lehet megadni nem követésre kötelezett alkatrész esetén" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "Beépítettek Belefoglalása" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Ha igaz, tartalmazza a megadott készlettétel alá beépített tételek teszteredményeit" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "Szűrés numerikus készlettétel azonosító szerint" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "A(z) {id} azonosítójú készlettétel nem létezik" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Készlethely típus" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Készlethely típusok" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Alapértelmezett ikon azokhoz a helyekhez, melyeknek nincs ikonja beállítva (válaszható)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Készlet hely" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Készlethelyek" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Tulajdonos" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Tulajdonos kiválasztása" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "A szerkezeti raktári helyekre nem lehet direktben raktározni, csak az al-helyekre." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Külső" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Ez egy külső készlethely" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Helyszín típusa" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Tárolóhely típus" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Nem lehet ezt a raktári helyet szerkezetivé tenni, mert már vannak itt tételek!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "a(z) {field} nem létezik" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Alkatrész kiválasztása kötelező" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "A szerkezeti raktári helyre nem lehet készletet felvenni!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Virtuális alkatrészből nem lehet készletet létrehozni" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "A beszállítói alkatrész típusa ('{self.supplier_part.part}') mindenképpen {self.part} kellene, hogy legyen" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Mennyiség 1 kell legyen a sorozatszámmal rendelkező tételnél" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Nem lehet sorozatszámot megadni ha a mennyiség több mint egy" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "A tétel nem tartozhat saját magához" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "A tételnek kell legyen gyártási azonosítója ha az is_bulding igaz" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Gyártási azonosító nem ugyanarra az alkatrész objektumra mutat" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Szülő készlet tétel" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Kiindulási alkatrész" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Válassz egy egyező beszállítói alkatrészt ehhez a készlet tételhez" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Hol található ez az alkatrész?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "A csomagolása ennek a készlet tételnek itt van tárolva" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Beépítve ebbe" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Ez a tétel be van építve egy másik tételbe?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Sorozatszám ehhez a tételhez" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Batch kód ehhez a készlet tételhez" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Készlet mennyiség" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Forrás gyártás" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Gyártás ehhez a készlet tételhez" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Felhasználva ebben" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Felhasználva ebben a gyártásban" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Forrás beszerzési rendelés" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Beszerzés ehhez a készlet tételhez" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Cél vevői rendelés" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Készlet tétel lejárati dátuma. A készlet lejártnak tekinthető ezután a dátum után" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Törlés ha kimerül" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Készlet tétel törlése ha kimerül" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Egy egység beszerzési ára a beszerzés időpontjában" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Alkatrésszé alakítva" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "Mennyiség meghaladja az elérhető készletet" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "Nem lehet készletet strukturális helyre rendelni" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Az alkatrész nem követésre kötelezett" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Mennyiség egész szám kell legyen" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "A mennyiség nem haladhatja meg az elérhető készletet ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Sorozatszámokat listában kell megadni" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "A mennyiség nem egyezik a megadott sorozatszámok számával" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "Nem lehet készletet strukturális helyre rendelni" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Ez a Teszt sablon nem létezik" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Készlet tétel hozzárendelve egy vevői rendeléshez" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Készlet tétel beépül egy másikba" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "A készlet tétel más tételeket tartalmaz" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Készlet tétel hozzárendelve egy vevőhöz" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Készlet tétel gyártás alatt" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Követésre kötelezett készlet nem vonható össze" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Duplikált készlet tételek vannak" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "A készlet tétel ugyanarra az alkatrészre kell vonatkozzon" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "A készlet tétel ugyanarra a beszállítói alkatrészre kell vonatkozzon" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Készlet tételek állapotainak egyeznie kell" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Készlet tétel nem mozgatható mivel nincs készleten" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Készlettörténet" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Bejegyzés megjegyzései" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Készlet Tétel Ellenőrzés Eredménye" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Ehhez a teszthez meg kell adni értéket" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Ehhez a teszthez fel kell tölteni mellékletet" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "A teszt eredménye érvénytelen" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Teszt eredménye" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Teszt kimeneti értéke" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Teszt eredmény melléklet" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Tesztek megjegyzései" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Teszt állomás" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "A tesztet elvégző tesztállomás azonosítója" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Elkezdődött" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "A teszt indításának időpontja" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Befejezve" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "A teszt befejezésének időpontja" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Generált köteg kód" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Gyártási rendelés kiválasztása" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Készlettétel amihez a köteg kódot generáljuk" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Készlethely amihez a köteg kódot generáljuk" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Alkatrész amihez a köteg kódot generáljuk" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Beszerzési rendelés kiválasztása" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Adja meg a mennyiséget a köteg kódhoz" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Generált sorozatszám" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Válassza ki az alkatrészt amihez sorozatszámot akar generálni" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Hány sorozatszámot generáljunk" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Az eredmény Teszt sablonja" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "Ehhez az alkatrészhez nem tartozik ellenőrzés" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "Sablon azonosító vagy Teszt név szükséges" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "A tesztet nem lehet a kezdésnél hamarabb befejezni" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Szülő tétel" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Szülő készlet tétel" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Csomagolási mennyiség használata: a megadott mennyiség ennyi csomag" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "Csomagméret használata" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Írd be a sorozatszámokat az új tételekhez" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Beszállítói Cikkszám" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Lejárt" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Gyermek tételek" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Nyilvántartott tételek" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Készlet tétel beszerzési ára, per darab vagy csomag" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Add meg hány készlet tételt lássunk el sorozatszámmal" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "Nincsen készlettétel megadva" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "A mennyiség nem lépheti túl a rendelkezésre álló készletet ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Cél készlet hely" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Sorozatszámokat nem lehet hozzárendelni ehhez az alkatrészhez" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "A sorozatszámok már léteznek" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Válaszd ki a beépítésre szánt készlet tételt" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Beépítendő mennyiség" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Adja meg a beépítendő mennyiséget" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Tranzakció megjegyzés hozzáadása (opcionális)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "A beépítendő mennyiség legalább 1 legyen" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Készlet tétel nem elérhető" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "A kiválasztott alkatrész nincs az alkatrészjegyzékben" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "A beépítendő mennyiség nem haladhatja meg az elérhető mennyiséget" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Cél hely a kiszedett tételeknek" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Válassz alkatrészt amire konvertáljuk a készletet" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "A kiválasztott alkatrész nem megfelelő a konverzióhoz" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Készlet tétel hozzárendelt beszállítói alkatrésszel nem konvertálható" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Készlet tétel státusz kódja" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Válassz alkatrészt amire konvertáljuk a készletet" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "A kiválasztott alkatrész nem megfelelő a konverzióhoz" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Készlet tétel hozzárendelt beszállítói alkatrésszel nem konvertálható" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Válaszd ki a státuszváltásra szánt készlet tételeket" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Nincs készlet tétel kiválasztva" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Alhelyek" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Felsőbb szintű készlet hely" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Az alkatrésznek értékesíthetőnek kell lennie" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "A tétel egy vevő rendeléshez foglalt" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "A tétel egy gyártási utasításhoz foglalt" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Vevő akihez rendeljük a készlet tételeket" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "A kiválasztott cég nem egy vevő" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Készlet hozzárendelés megjegyzései" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "A készlet tételek listáját meg kell adni" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Készlet összevonás megjegyzései" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Nem egyező beszállítók megengedése" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Különböző beszállítói alkatrészekből származó készletek összevonásának engedélyezése" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Nem egyező állapotok megjelenítése" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Különböző állapotú készletek összevonásának engedélyezése" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Legalább két készlet tételt meg kell adni" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Nincs változás" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Készlet tétel elsődleges kulcs értéke" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Készlettétel nincs készleten" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "Készlettétel már készleten van" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "Mennyiség nem lehet negatív" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Készlet tranzakció megjegyzései" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "Meglévő készletbe olvasztás" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Készlet tranzakció megjegyzései" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "Visszaérkezett tételek beolvasztása a készlettételekbe ha lehetséges" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Következő sorozatszám" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Előző Sorozatszám" @@ -9343,42 +9932,50 @@ msgid "Merged stock items" msgstr "Összevont készlet tétel" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Alkatrészváltozattá alakítva" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Gyártási utasítás kimenete elkészült" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Gyártási utasítás kimenete kész" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Gyártási utasítás kimenete elutasítva" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Gyártásra felhasználva" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Vevői rendelésre kiszállítva" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Megrendelésre érkezett" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Visszavéve" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Vevőnek kiszállítva" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Vevőtől visszaérkezett" @@ -9528,19 +10125,19 @@ msgstr "Felhasználók" msgid "Select which users are assigned to this group" msgstr "Válaszd ki mely felhasználók tartoznak ehhez a csoporthoz" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Személyes adatok" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Jogosultságok" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Fontos dátumok" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "A token visszavonva" @@ -9548,279 +10145,283 @@ msgstr "A token visszavonva" msgid "Token has expired" msgstr "A token lejárt" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API Token" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API Tokenek" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Token név" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Egyedi token név" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Token lejárati dátum" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Utolsó tevékenység" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Token utolsó használata" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Visszavonva" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Jogosultságok" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Nézet" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Jogosultság tételek megtekintéséhez" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Hozzáad" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Jogosultság tételek hozzáadásához" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Módosítás" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Jogosultság tételek szerkesztéséhez" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Törlés" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Jogosultság tételek törléséhez" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Robot" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Belső" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Vendég" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Nyelv" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Felhasználó által preferált nyelv" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Téma" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Web UI JSON beállításai - kézzel nem szabad szerkeszteni!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Widgetek" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Dashboard widgetek JSON beállításai - kézzel szerkeszteni tilos!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Megjelenítendő név" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Felhasználó választott megjelenítési neve" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Pozíció" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Fő munkakör vagy pozíció" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Felhasználói állapot üzenet" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Felhasználó földrajzi helye" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "A felhasználó éppen használja a rendszert" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Javasolt elérhetőségek" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Felhasználó típusa" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "Milyen típusú ez a felhasználó?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Szervezet" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Felhasználó elsődleges szervezete/kötődése" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Elsődleges csoport" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Felhasználó elsődleges csoportja" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Adminisztrátor" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Beszerzési rendelések" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Vevői rendelések" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Visszavételek" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Felhasználónév" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Keresztnév" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "A felhasználó keresztneve" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Vezetéknév" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "A felhasználó vezetékneve" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "A felhasználó e-mail címe" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Rendszergazda" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "A felhasználó rendszergazda-e" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Aktív a felhasználói fiók" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Csak rendszergazda szerkesztheti ezt a mezőt" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Jelszó" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Felhasználó jelszava" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "Figyelmezetés felülbírálása" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "A jelszó szabályok figyelmeztetésének felülbírálata" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Nincs jogosultsága felhasználót létrehozni" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "A fiókod sikeresen létrejött." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Kérlek használd a jelszó visszállítás funkciót a belépéshez" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Üdvözlet az InvenTree-ben" diff --git a/src/backend/InvenTree/locale/id/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/id/LC_MESSAGES/django.po index 028aec99e2..fb86ebb7e3 100644 --- a/src/backend/InvenTree/locale/id/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/id/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Indonesian\n" "Language: id_ID\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API endpoint tidak ditemukan" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Barang harus disediakan sebagai daftar" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Pengguna tidak memiliki izin untuk melihat model ini" @@ -65,150 +69,155 @@ msgstr "Konfirmasi alamat email" msgid "You must type the same email each time." msgstr "Masukkan email yang sama." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Alamat surel utama yang diberikan tidak valid." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Domain surel yang diberikan tidak perbolehkan." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nilai tidak tersedia" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Jumlah yang diberikan tidak valid" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Detail terkait galat dapat dilihat di panel admin" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Masukkan tanggal" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Catatan" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Nilai yang diberikan tidak sesuai dengan pola yang ditentukan: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Nomor seri kosong" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Gandakan Nomor Seri" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Tidak ada nomor seri ditemukan" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Hapus tag-tag HTML dari nilai ini" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Koneksi Galat" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Ukuran gambar terlalu besar" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "URL yang diberikan bukan file gambar yang valid" @@ -216,159 +225,203 @@ msgstr "URL yang diberikan bukan file gambar yang valid" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Surel" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Anda harus mengaktifkan autentikasi dua faktor sebelum melakukan hal lainnya." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Pilihan tidak valid" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nama" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Keterangan" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Keterangan (opsional)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Direktori" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Data Barcode" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Data barcode pihak ketiga" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hash unik data barcode" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Sudah ada barcode yang sama" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Terjadi Kesalahan Server" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Sebuah kesalahan telah dicatat oleh server." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Harus berupa angka yang valid" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Mata Uang" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Nilai tidak valid" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Salin Baris" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Bahasa Arab" @@ -521,46 +574,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Bukan kode mata uang yang valid" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Produksi Induk" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Bagian" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Pesanan harus dibatalkan sebelum dapat dihapus" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Tersedia" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Order Produksi" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Lokasi" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Order Produksi" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Referensi Order Produksi" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referensi" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Pilih bagian untuk diproduksi" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referensi Order Penjualan" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Lokasi Sumber" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Pilih dari lokasi mana stok akan diambil untuk produksi ini (kosongkan untuk mengambil stok dari mana pun)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Lokasi Tujuan" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Pilih lokasi di mana item selesai akan disimpan" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Jumlah Produksi" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Jumlah item stok yang akan dibuat" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Item selesai" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Jumlah stok item yang telah diselesaikan" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Status pembuatan" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Kode status pembuatan" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Kode Kelompok" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Kode kelompok untuk hasil produksi ini" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Tanggal Pembuatan" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Target tanggal selesai" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Target tanggal selesai produksi. Produksi akan menjadi terlambat setelah tanggal ini." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Tanggal selesai" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "diselesaikan oleh" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Diserahkan oleh" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Pengguna yang menyerahkan order ini" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Penanggung Jawab" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Tautan eksternal" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Tautan menuju URL eksternal" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Tidak ada hasil produksi yang ditentukan" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Hasil produksi sudah selesai" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Hasil produksi tidak sesuai dengan order produksi" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Jumlah harus lebih besar daripada nol" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Jumlah tersedia ({q}) terlampaui" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Jumlah" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Item produksi harus menentukan hasil produksi karena bagian utama telah ditandai sebagai dapat dilacak" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Jumlah harus 1 untuk stok dengan nomor seri" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Item stok teralokasikan terlalu banyak" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Stok Item" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Sumber stok item" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Jumlah stok yang dialokasikan ke produksi" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Pasang ke" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Tujuan stok item" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Hasil Produksi" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Hasil produksi tidak sesuai dengan produksi induk" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Hasil bagian tidak sesuai dengan bagian dalam order produksi" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Hasil produksi ini sudah diselesaikan" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Hasil produksi tidak dialokasikan sepenuhnya" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Masukkan jumlah hasil pesanan" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Jumlah bagian yang dapat dilacak harus berupa angka bulat" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Jumlah harus angka bulat karena terdapat bagian yang dapat dilacak dalam daftar barang" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Nomor Seri" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Masukkan nomor seri untuk hasil pesanan" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Alokasikan nomor seri secara otomatis" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Alokasikan item yang diperlukan dengan nomor seri yang sesuai secara otomatis" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Nomor-nomor seri berikut sudah ada atau tidak valid" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Daftar hasil pesanan harus disediakan" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Lokasi hasil pesanan yang selesai" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Terima Alokasi Tidak Lengkap" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Tidak diizinkan" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Terima Tidak Teralokasikan" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Terima bahwa stok item tidak teralokasikan sepenuhnya ke pesanan ini" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Stok yang diperlukan belum teralokasikan sepenuhnya" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Terima Tidak Selesai" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Terima bahwa jumlah hasil produksi yang diperlukan belum selesai" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Jumlah produksi yang diperlukan masih belum cukup" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Order memiliki hasil produksi yang belum dilengkapi" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Hasil produksi" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Hasil pesanan harus mengarah ke pesanan yang sama" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part harus mengarah ke bagian yang sesuai dengan order produksi" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Item harus tersedia dalam stok" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Jumlah tersedia ({q}) terlampaui" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Hasil produksi harus ditentukan untuk mengalokasikan bagian yang terlacak" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Hasil produksi tidak dapat ditentukan untuk alokasi barang yang tidak terlacak" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Item yang dialokasikan harus disediakan" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Lokasi stok, dari mana bahan/bagian akan diambilkan (kosongkan untuk mengambil dari lokasi mana pun)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Lokasi tidak termasuk" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Jangan ambil stok item dari lokasi yang dipilih" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Stok bergantian" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Item stok di beberapa lokasi dapat digunakan secara bergantian" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Stok pengganti" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Izinkan alokasi bagian pengganti" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Item tagihan material" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Tertunda" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Produksi" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Dibatalkan" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Selesai" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Stok dibutuhkan untuk order produksi" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Pengguna" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Harga" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktif" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Pengguna" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Harga" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Judul" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Tautan" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Kesimpulan" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Berkas Gambar" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Lampiran" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "File tidak ditemukan" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Tautan eksternal tidak ditemukan" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Pilih file untuk dilampirkan" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Komentar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "Ukuran Berkas" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Ukuran Berkas" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Label" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Terbuat" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Pilihan" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Aktif" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Respon" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Barang diterima" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nama File" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "Hari" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,800 +2921,790 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponen" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Aktifkan Laporan" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "Ukuran Halaman" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" -msgstr "" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" +msgstr "Ukuran Halaman" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "Surel diperlukan" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" +msgstr "Surel diperlukan" + +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1111 @@ -3561,146 +3712,230 @@ msgid "Enable interface integration" msgstr "Aktifkan Integrasi Antarmuka" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +#: common/setting/system.py:1174 +msgid "Enable interface integration" +msgstr "Aktifkan Integrasi Antarmuka" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4116,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Perusahaan" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4391,8 @@ msgstr "" msgid "Contact email address" msgstr "Kontak alamat surel" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontak" @@ -4176,283 +4444,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Kode Pos" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4744,152 @@ msgstr "Diletakkan" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "File data" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4897,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4973,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Tersalin" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Tidak diketahui" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Jaringan Terputus" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5093,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5117,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Selesai" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5236,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Total Harga" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Pelanggan" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Harga Jual" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Dikirim" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Jumlah yang dialokasikan harus lebih dari nol" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "Order ID" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Salin Baris" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Hilang" @@ -5718,1279 +6129,1312 @@ msgstr "Hilang" msgid "Returned" msgstr "Dikembalikan" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Ganti" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Tolak" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Tanggal" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Harga Minimal" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Harga Maksimal" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Perbarui" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7455,7 @@ msgstr "" msgid "Installed" msgstr "Terpasang" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7467,23 @@ msgstr "Tidak ada tindakan yang ditentukan" msgid "No matching action found" msgstr "Aksi tidak ditemukan" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7499,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Tidak cukup informasi" @@ -7108,23 +7568,23 @@ msgstr "Tidak cukup informasi" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7721,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7765,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7967,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Buka Laman" @@ -7628,12 +8096,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8121,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8221,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8347,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8590,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Letter" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8775,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8822,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8861,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Nomor Seri" @@ -8405,7 +8886,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8919,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Lampiran perlu diunggah untuk tes ini" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9935,50 @@ msgid "Merged stock items" msgstr "Stok item digabungkan" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Dikonversi ke variasi" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Output order produksi dibuat" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Order output produksi selesai" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Terpakai oleh order produksi" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Terkirim ke pelanggan" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Dikembalikan pelanggan" @@ -9527,19 +10128,19 @@ msgstr "Pengguna" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Data pribadi" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10148,283 @@ msgstr "" msgid "Token has expired" msgstr "Token telah kadaluarsa" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Nama Token" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Terakhir diliat" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Ganti" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Nama Pengguna" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Nama Depan" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Nama depan dari pengguna" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Nama Belakang" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Nama belakang dari pengguna" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Alamat surel dari pengguna" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Selamat Datang di InvenTree" diff --git a/src/backend/InvenTree/locale/it/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/it/LC_MESSAGES/django.po index 72f0bcb43d..024928863e 100644 --- a/src/backend/InvenTree/locale/it/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/it/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Endpoint API non trovato" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Gli articoli devono essere forniti come elenco" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Lista elementi fornita non valida" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Tutti i filtri devono essere usati solo con true" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Nessun elemento corrisponde ai criteri forniti" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Nessun dato fornito" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Questo campo deve essere unico." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "L'utente non ha i permessi per vedere questo modello" @@ -65,150 +69,155 @@ msgstr "Conferma indirizzo email" msgid "You must type the same email each time." msgstr "È necessario digitare la stessa e-mail ogni volta." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "L'indirizzo email principale fornito non è valido." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "L'indirizzo di posta elettronica fornito non è approvato." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Unità fornita non valida ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nessun valore specificato" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Impossibile convertire {original} in {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Quantità inserita non valida" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "I dettagli dell'errore possono essere trovati nel pannello di amministrazione" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Inserisci la data" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Valore decimale non valido" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Note" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Il valore '{name}' non è nel formato del pattern" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Il valore fornito non corrisponde al modello richiesto: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Impossibile serializzare più di 1000 elementi contemporaneamente" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Numero seriale vuoto" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Seriale Duplicato" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Gruppo non valido: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "L'intervallo di gruppo {group} supera la quantità consentita ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Nessun numero di serie trovato" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Il numero dei numeri seriali univoci ({n}) deve essere uguale alla quantità ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Rimuovi i tag HTML da questo valore" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "I dati contengono un contenuto in markdown proibito" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Errore di connessione" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Il server ha risposto con un codice di stato non valido" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Si è verificata un'eccezione" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Il server ha risposto con valore Content-Length non valido" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Immagine troppo grande" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Il download dell'immagine ha superato la dimensione massima" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Il server remoto ha restituito una risposta vuota" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "L'URL fornito non è un file immagine valido" @@ -216,159 +225,203 @@ msgstr "L'URL fornito non è un file immagine valido" msgid "Log in to the app" msgstr "Accedi all'app" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Devi abilitare l'autenticazione a due fattori prima di fare qualsiasi altra cosa." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Errore nell'eseguire la convalida del plugin" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "I metadati devono essere un oggetto python dict" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metadati Plugin" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Campo di metadati JSON, da utilizzare con plugin esterni" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Schema formattato impropriamente" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Formato chiave sconosciuta" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Formato chiave mancante" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Il campo di riferimento non può essere vuoto" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Il campo deve corrispondere al modello richiesto" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Numero di riferimento troppo grande" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Scelta non valida" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nome" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Descrizione" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Descrizione (opzionale)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Percorso" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Nomi duplicati non possono esistere sotto lo stesso genitore" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Note di Markdown (opzionale)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Dati del Codice a Barre" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Dati Codice a Barre applicazioni di terze parti" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Codice a Barre" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Codice univoco del codice a barre" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Trovato codice a barre esistente" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Errore del server" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Un errore è stato loggato dal server." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Immagine" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Deve essere un numero valido" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Selezionare la valuta dalle opzioni disponibili" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Questo campo non può essere nullo." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Valore non valido" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Formato tipo di contenuto non valido" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Tipo di Contenuto non trovato" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "Il tipo di contenuto non corrisponde alla classe mixin richiesta" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Copia parametri" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Copia Linee" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Copia gli elementi di riga dall'ordine originale" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Copia Linee Extra" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Copia gli elementi di riga extra dall'ordine originale" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabo" @@ -521,46 +574,48 @@ msgstr "Cinese (Semplificato)" msgid "Chinese (Traditional)" msgstr "Cinese (Tradizionale)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Aggiornamento disponibile" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "È disponibile un aggiornamento per InvenTree" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Unità fisica non valida" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Non è un codice valuta valido" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Stato dell'ordine" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Produzione Genitore" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Includi Varianti" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Includi Varianti" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Includi Varianti" msgid "Part" msgstr "Articolo" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Categoria" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Produzione Antenata" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Assegnato a me" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Assegnato a" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Creato prima" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Creato dopo" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Ha data d'inizio" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Data d'inizio prima" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Data d'inizio dopo" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Ha data di fine" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Data obiettivo prima" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Data obiettivo dopo" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Completato prima" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Completato dopo" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Data minima" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Data massima" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Escludi Albero" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "La produzione deve essere annullata prima di poter essere eliminata" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Consumabile" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opzionale" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Assemblaggio" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Monitorato" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testabile" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Ordine In Corso" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Allocato" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Utilizzato" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Disponibile" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Ordinato" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Ordine di Produzione" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Posizione" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Output" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Filtra per ID articolo stock di output. Usa 'null' per trovare elementi di produzione disinstallati." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Ordini di Produzione" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Assembly BOM non è stato convalidato" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "L'ordine di generazione non può essere creato per una parte inattiva" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "L'ordine di compilazione non può essere creato per una parte sbloccata" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Gli ordini di costruzione possono essere eseguiti solo esternamente per gli articoli acquistabili" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "L'utente o il gruppo responsabile deve essere specificato" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "L'ordine di costruzione della parte non può essere cambiata" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "La data di scadenza deve essere successiva alla data d'inizio" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Riferimento Ordine Di Produzione" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Riferimento" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Breve descrizione della build (facoltativo)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Ordine di produzione a cui questa produzione viene assegnata" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Selezionare parte da produrre" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Numero di riferimento ordine di vendita" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Ordine di vendita a cui questa produzione viene assegnata" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Posizione Di Origine" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Seleziona la posizione da cui prelevare la giacenza (lasciare vuoto per prelevare da qualsiasi posizione di magazzino)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Build Esterno" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Questo ordine di produzione è eseguito esternamente" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Posizione Della Destinazione" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Seleziona il luogo in cui gli articoli completati saranno immagazzinati" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Quantità Produzione" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Numero di articoli da costruire" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Articoli completati" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Numero di articoli di magazzino che sono stati completati" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Stato Produzione" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Codice stato di produzione" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Codice Lotto" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Codice del lotto per questa produzione" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Data di creazione" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Data inizio produzione" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Data d'inizio programmata per questo ordine di produzione" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Data completamento obiettivo" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Data di completamento della produzione. Dopo tale data la produzione sarà in ritardo." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Data di completamento" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "Completato da" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Rilasciato da" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Utente che ha emesso questo ordine di costruzione" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsabile" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Utente o gruppo responsabile di questo ordine di produzione" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Collegamento esterno" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link a URL esterno" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Priorità di produzione" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Priorità di questo ordine di produzione" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Codice del progetto" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Codice del progetto per questo ordine di produzione" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Impossibile finalizzare l'ordine di produzione con ordini secondari aperti" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Impossibile finalizzare l'ordine di produzione con articolo incompleti" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Impossibile scaricare l'attività per completare le allocazioni di build" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "L'ordine di produzione {build} è stato completato" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "L'ordine di produzione è stato completato" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Deve essere fornita un numero di serie per gli articoli rintracciabili" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nessun output di produzione specificato" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "La produzione è stata completata" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "L'output della produzione non corrisponde all'ordine di compilazione" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "La quantità deve essere maggiore di zero" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "La quantità non può essere maggiore della quantità in uscita" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "La produzione non ha superati tutti i test richiesti" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "L'output della build {serial} non ha superato tutti i test richiesti" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Impossibile completare parzialmente un build output con gli elementi assegnati" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Quantità disponibile ({q}) superata" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Elemento di Riga Ordine di Produzione" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Crea oggetto" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Crea oggetto" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantità" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Quantità richiesta per l'ordine di costruzione" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Quantità di articoli magazzino consumate" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "L'elemento di compilazione deve specificare un output poiché la parte principale è contrassegnata come rintracciabile" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "L'articolo in stock selezionato non corrisponde alla voce nella BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "La quantità assegnata deve essere maggiore di zero" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "La quantità deve essere 1 per lo stock serializzato" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "La quantità assegnata ({q}) non deve essere maggiore della quantità disponibile ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "L'articolo in giacenza è sovrallocato" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Articoli in magazzino" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Origine giacenza articolo" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Quantità di magazzino da assegnare per la produzione" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Installa in" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Destinazione articolo in giacenza" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Livello Produzione" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Nome Articolo" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Genera Output" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "L'output generato non corrisponde alla produzione principale" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "L'output non corrisponde alle parti dell'ordine di produzione" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Questa produzione è stata già completata" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Questo output non è stato completamente assegnato" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Inserisci la quantità per l'output di compilazione" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Quantità totale richiesta per articoli rintracciabili" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Quantità totale richiesta, poiché la fattura dei materiali contiene articoli rintracciabili" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Codice Seriale" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Inserisci i numeri di serie per gli output di compilazione (build option)" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Posizione dello stock per l'output della produzione" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Numeri di Serie Assegnazione automatica" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Assegna automaticamente gli articoli richiesti con i numeri di serie corrispondenti" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "I seguenti numeri di serie sono già esistenti o non sono validi" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Deve essere fornito un elenco dei risultati di produzione" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Posizione dello stock per l'output di produzione rimosso" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Scarta Assegnazioni" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Scartare tutte le assegnazioni di magazzino per gli output rimossi" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Motivo dell'eliminazione degli output di compilazione" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Posizione per gli output di build completati" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Accetta Assegnazione Incompleta" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Completa l'output se le scorte non sono state interamente assegnate" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Consuma Giacenze Allocate" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Consuma tutte le scorte che sono già state assegnate a questa produzione" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Rimuovi Output Incompleti" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Elimina gli output di produzione che non sono stati completati" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Non permesso" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Accetta come consumato da questo ordine di produzione" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Non assegnare prima di aver completato questo ordine di produzione" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Giacenza in eccesso assegnata" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Come si desidera gestire gli elementi extra giacenza assegnati all'ordine di produzione" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Alcuni articoli di magazzino sono stati assegnati in eccedenza" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Accetta Non Assegnato" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Accetta che gli elementi in giacenza non sono stati completamente assegnati a questo ordine di produzione" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "La giacenza richiesta non è stata completamente assegnata" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Accetta Incompleta" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Accetta che il numero richiesto di output di produzione non sia stato completato" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "La quantità di produzione richiesta non è stata completata" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "L'ordine di costruzione ha ancora degli ordini di costruzione figli" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "L'ordine di costruzione deve essere in stato di produzione" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "L'ordine di produzione ha output incompleti" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Linea di produzione" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Genera Output" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "L'output di produzione deve puntare alla stessa produzione" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Articolo linea di produzione" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "gli elementi degli articoli della distinta base devono puntare alla stessa parte dell'ordine di produzione" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "L'articolo deve essere disponibile" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Quantità disponibile ({q}) superata" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "L'output di produzione deve essere specificato per l'ubicazione delle parti tracciate" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "L'output di produzione non deve essere specificato per l'ubicazione delle parti non tracciate" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Deve essere indicata l'allocazione dell'articolo" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Posizione dello stock in cui le parti devono prelevate (lasciare vuoto per prelevare da qualsiasi luogo)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Escludi Ubicazione" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Escludi gli elementi stock da questa ubicazione selezionata" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Scorte Intercambiabili" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Gli elementi in magazzino in più sedi possono essere utilizzati in modo intercambiabile" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Sostituisci Giacenze" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Consenti l'allocazione delle parti sostitutive" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Articoli Opzionali" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Assegna gli elementi opzionali della distinta base all'ordine di produzione" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Riferimento BOM" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "Identificativo dell'Articolo BOM" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Nome Articolo BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Costruzione" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Articolo Fornitore" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Quantità assegnata" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Riferimento Ordine Di Costruzione" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Nome Categoria Articolo" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Tracciabile" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Ereditato" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Consenti Le Varianti" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Distinta base (Bom)" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "In Produzione" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Pianificato per la produzione" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Scorte esterne" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Disponibilità in magazzino" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Disponibili scorte alternative" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Disponibili varianti delle scorte" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "La quantità consumata supera la quantità assegnata" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Note facoltative per il consumo di magazzino" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "L'articolo prodotto deve puntare all'ordine di produzione corretto" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Duplica l'allocazione degli articoli da produrre" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "La riga di produzione deve puntare all'ordine di produzione corretto" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Duplica l'allocazione della riga di produzione" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Deve essere fornita almeno un articolo o riga" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "In attesa" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Produzione" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "In Attesa" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Annullato" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Completo" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "L'ordine di produzione {build} è stato completato" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "L'ordine di produzione è stato completato" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Giacenza richiesta per l'ordine di produzione" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "L'ordine di produzione {build} richiede articoli aggiuntivi" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Ordine di produzione in ritardo" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "L'ordine di produzione {bo} è in ritardo" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "È Un Connegamento" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "E' un file" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "L'utente non ha il permesso di eliminare questi allegati" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "L'utente non ha il permesso di eliminare questo allegato" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Lista di selezione bloccata" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Codice valuta non valido" @@ -1539,15 +1641,20 @@ msgstr "Nessun codice valuta valido fornito" msgid "No plugin" msgstr "Nessun plugin" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Etichetta Codice Progetto" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Aggiornato" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Orario dell'ultimo aggiornamento" @@ -1567,794 +1674,844 @@ msgstr "Codice unico del progetto" msgid "Project description" msgstr "Descrizione del progetto" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Utente o gruppo responsabile di questo progetto" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Tasto impostazioni" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Valore impostazioni" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Il valore specificato non è un opzione valida" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Il valore deve essere un valore booleano" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Il valore deve essere un intero" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Il valore deve essere un numero valido" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Il valore non supera i controlli di convalida" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "La stringa chiave deve essere univoca" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Utente" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Quantità prezzo limite" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Prezzo" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Prezzo unitario in quantità specificata" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Scadenza" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Scadenza in cui questa notifica viene ricevuta" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Nome per questa notifica" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Attivo" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Utente o gruppo responsabile di questo progetto" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Tasto impostazioni" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Valore impostazioni" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Il valore specificato non è un opzione valida" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Il valore deve essere un valore booleano" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Il valore deve essere un intero" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Il valore deve essere un numero valido" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Il valore non supera i controlli di convalida" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "La stringa chiave deve essere univoca" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Utente" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Quantità prezzo limite" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Prezzo" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Prezzo unitario in quantità specificata" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Scadenza" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Scadenza in cui questa notifica viene ricevuta" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Nome per questa notifica" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "È questa notifica attiva" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token per l'accesso" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Segreto" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Segreto condiviso per HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID Messaggio" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Identificatore unico per questo messaggio" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Host" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Host da cui questo messaggio è stato ricevuto" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Intestazione" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Intestazione di questo messaggio" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Contenuto" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Contenuto di questo messaggio" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Scadenza in cui questo messaggio è stato ricevuto" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Lavorato il" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Il lavoro su questo messaggio è terminato?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Titolo" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Collegamento" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Pubblicato" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autore" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Riepilogo" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Letto" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Queste notizie sull'elemento sono state lette?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "File immagine" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Tipo di modello di destinazione per questa immagine" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "ID modello di destinazione per questa immagine" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Unità Personalizzata" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Il simbolo dell'unità deve essere univoco" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Il nome dell'unità deve essere un identificatore valido" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Nome dell'unità" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Simbolo" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Simbolo unità opzionale" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definizione" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definizione unità" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Allegato" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "File mancante" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Link esterno mancante" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Tipo modello" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Tipo di modello di destinazione per l'immagine" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Seleziona file da allegare" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Commento" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Commento allegato" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Data caricamento" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Data di caricamento del file" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Dimensione file" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Dimensioni file in byte" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Tipo di modello specificato per l'allegato non valido" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Stato Personalizzato" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Stati Personalizzati" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Imposta Stato Di Riferimento" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Set di stato esteso con questo stato personalizzato" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Chiave Logica" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Chiave logica dello stato che è uguale a questo stato personalizzato nella logica commerciale" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Valore" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Valore numerico che verrà salvato nel database dei modelli" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Nome dello Stato" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etichetta" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Etichetta che verrà visualizzata nel frontend" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Colore" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Colore che verrà visualizzato nel frontend" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Modello" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Modello a cui questo stato è associato" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Il modello deve essere selezionato" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "La chiave deve essere selezionata" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "La chiave logica deve essere selezionata" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "La chiave deve essere diversa dalla chiave logica" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Deve essere fornita una classe di stato di riferimento valida" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "La chiave deve essere diversa dalle chiavi logiche dello stato di riferimento" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "La chiave logica deve essere nelle chiavi logiche dello stato di riferimento" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Il nome deve essere diverso dai nomi dello stato di riferimento" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Elenco Selezioni" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Elenchi di Selezione" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Nome dell'elenco di selezione" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Descrizione della lista di selezione" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Bloccato" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Questa lista di selezione è bloccata?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Questo elenco di selezione può essere utilizzato?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Plugin Sorgente" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Plugin che fornisce l'elenco di selezione" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Stringa Sorgente" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Stringa opzionale che identifica il sorgente usato per questa lista" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Voce Predefinita" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Voce predefinita per questo elenco di selezione" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Creato" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Data e ora in cui è stato creato l'elenco di selezione" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Ultimo aggiornamento" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Data e ora in cui l'elenco di selezione è stato aggiornato" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Voce Lista Selezione" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Voci Lista Selezione" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Elenco di selezione a cui appartiene questa voce" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Valore della voce della lista di selezione" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Etichetta per la voce elenco di selezione" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Descrizione della voce della lista di selezione" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Questa voce della lista di selezione è attiva?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Modello Parametro" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "Modelli parametro" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "I parametri della casella di controllo non possono avere unità" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "I parametri della casella di controllo non possono avere scelte" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Le scelte devono essere uniche" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Il nome del modello del parametro deve essere univoco" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "Tipo di modello di destinazione per questo modello di parametro" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Nome Parametro" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Unità" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Unità fisiche per questo parametro" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Descrizione del parametro" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Casella di spunta" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Questo parametro è una casella di spunta?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Scelte" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Scelte valide per questo parametro (separato da virgola)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Lista di selezione per questo parametro" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Abilitato" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "Questo modello di parametro è abilitato?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "Parametro" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "Parametri" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Scelta non valida per il valore del parametro" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "Tipo di modello specificato per parametro non valido" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "ID Modello" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "ID del modello di destinazione per questo parametro" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Modello" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "Modello Parametro" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Dati" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Valore del Parametro" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Nota" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Note opzionali elemento" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Scansione Codice A Barre" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Dati del Codice a Barre" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Utente che ha scannerizzato il codice a barre" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Data e ora" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Data e ora della scansione del codice a barre" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Endpoint URL che ha elaborato il codice a barre" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Contesto" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Dati contestuali per la scansione del codice a barre" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Risposta" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Dati di risposta dalla scansione del codice a barre" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Risultato" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "La scansione del codice a barre è riuscita?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Si è verificato un errore" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: La cancellazione del log email è protetta. Imposta INVENTREE_PROTECT_EMAIL_LOG a Falso per consentire la cancellazione." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "Messaggio email" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "Messaggi email" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Annunciato" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Inviato" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Fallito" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Consegnato" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Confermato" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Ricevuti" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "In uscita" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Nessuna risposta" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Traccia La Consegna" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Conferma di lettura" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Tracciare i clic delle email" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "ID Globale" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Identificatore per questo messaggio (potrebbe essere fornito da un sistema esterno)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "ID discussione" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Identificatore per questo thread del messaggio (potrebbe essere fornito da un sistema esterno)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Discussione" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Thread collegato a questo messaggio" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "Priorità" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "Discussione Email" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "Discussioni Email" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Chiave" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Chiave univoca per questa discussione (usata per identificare la discussione)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Identificatore univoco per questa discussione" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Avviato internamente" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Questa discussione è iniziata internamente?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Data e ora in cui la discussione è stata creata" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Data e ora in cui la discussione è stata aggiornata" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} cancellato" msgid "A order that is assigned to you was canceled" msgstr "Un ordine assegnato a te è stato annullato" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Elemento ricevuto" @@ -2388,104 +2545,100 @@ msgstr "Gli elementi sono stati ricevuti a fronte di un ordine di acquisto" msgid "Items have been received against a return order" msgstr "Gli articoli sono stati ricevuti contro un ordine di reso" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "Indica se modificare questa impostazione richiede conferma" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "Questa impostazione richiede conferma prima di cambiare. Si prega di confermare la modifica." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Indica se l'impostazione è sovrascritta da una variabile ambiente" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Sovrascrivi" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "In Esecuzione" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Attività in sospeso" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Attività pianificate" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Attività Fallite" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID Attività" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "ID attività univoco" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Blocco" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Tempo di blocco" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Nome attività" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funzione" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nome della funzione" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argomenti" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argomenti attività" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Argomenti Parole Chiave" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Argomenti parole chiave attività" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nome del file" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Tipo di modello" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "L'utente non ha il permesso di creare o modificare allegati per questo modello" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "L'utente non ha il permesso di creare o modificare parametri per questo modello" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Lista di selezione bloccata" - #: common/setting/system.py:97 msgid "No group" msgstr "Nessun gruppo" @@ -2614,13 +2767,13 @@ msgstr "Intervallo Aggiornamento Valuta" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Quanto spesso aggiornare i tassi di cambio (impostare a zero per disabilitare)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "giorni" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Plugin di aggiornamento valuta da usare" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Convalida URL rigoroso" @@ -2760,947 +2921,1017 @@ msgstr "Plugin Generazione Codice A Barre" msgid "Plugin to use for internal barcode data generation" msgstr "Plugin da usare per la generazione interna di codice a barre" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Revisioni Articolo" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Abilita il campo revisione per l'articolo" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Solo revisione assemblaggio" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Consenti revisioni solo per articoli di assemblaggio" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Consenti l'eliminazione dall'assemblaggio" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Permetti l'eliminazione degli articoli che sono usati in un assemblaggio" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Schema di espressione regolare per l'articolo corrispondente IPN" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Consenti duplicati IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Permetti a più articoli di condividere lo stesso IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Permetti modifiche al part number interno (IPN)" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Consenti di modificare il valore del part number durante la modifica di un articolo" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Copia I Dati Della distinta base dell'articolo" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Copia i dati della Distinta Base predefinita quando duplichi un articolo" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Copia I Dati Parametro dell'articolo" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Copia i dati dei parametri di default quando si duplica un articolo" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Copia I Dati dell'Articolo Test" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Copia i dati di prova di default quando si duplica un articolo" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Copia Template Parametri Categoria" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Copia i modelli dei parametri categoria quando si crea un articolo" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Gli articoli sono modelli per impostazione predefinita" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Gli articoli possono essere assemblate da altri componenti per impostazione predefinita" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Componente" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Gli articoli possono essere assemblati da altri componenti per impostazione predefinita" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Acquistabile" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Gli articoli sono acquistabili per impostazione predefinita" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Vendibile" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Gli articoli sono acquistabili per impostazione predefinita" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Gli articoli sono tracciabili per impostazione predefinita" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuale" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Gli articoli sono virtuali per impostazione predefinita" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Mostra articoli correlati" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Visualizza parti correlate per ogni articolo" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Dati iniziali dello stock" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Consentire la creazione di uno stock iniziale quando si aggiunge una nuova parte" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Dati iniziali del fornitore" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Consentire la creazione dei dati iniziali del fornitore quando si aggiunge una nuova parte" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Formato di visualizzazione del nome articolo" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formato per visualizzare il nome dell'articolo" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Icona predefinita Categoria Articolo" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Icona predefinita Categoria Articolo (vuoto significa nessuna icona)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Prezzi Minimi Decimali" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Numero minimo di decimali da visualizzare quando si visualizzano i dati dei prezzi" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Prezzi Massimi Decimali" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Numero massimo di decimali da visualizzare quando si visualizzano i dati dei prezzi" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Usa Prezzi Fornitore" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Includere le discontinuità di prezzo del fornitore nei calcoli generali dei prezzi" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Ignora la Cronologia Acquisti" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Cronologia dei prezzi dell'ordine di acquisto del fornitore superati con discontinuità di prezzo" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Utilizzare i prezzi degli articoli in stock" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Utilizzare i prezzi dei dati di magazzino inseriti manualmente per il calcolo dei prezzi" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Età dei prezzi degli articoli in stock" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Escludere dal calcolo dei prezzi gli articoli in giacenza più vecchi di questo numero di giorni" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Utilizza Variazione di Prezzo" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Includi la variante dei prezzi nei calcoli dei prezzi complessivi" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Solo Varianti Attive" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Utilizza solo articoli di varianti attive per calcolare i prezzi delle varianti" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Aggiornamento Automatico Prezzi" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Aggiorna automaticamente il prezzo degli articoli quando i dati interni cambiano" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Intervallo Di Ricostruzione Dei Prezzi" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Numero di giorni prima che il prezzo dell'articolo venga aggiornato automaticamente" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Prezzi interni" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Abilita prezzi interni per gli articoli" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Sovrascrivi Prezzo Interno" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Se disponibile, i prezzi interni sostituiscono i calcoli della fascia di prezzo" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Abilita stampa etichette" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Abilita la stampa di etichette dall'interfaccia web" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Etichetta Immagine DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Risoluzione DPI quando si generano file di immagine da fornire ai plugin di stampa per etichette" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Abilita Report di Stampa" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Abilita generazione di report di stampa" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Modalità Debug" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Genera report in modalità debug (output HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Registro errori" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Errori di log che si verificano durante la generazione dei report" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Dimensioni pagina" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Dimensione predefinita della pagina per i report PDF" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Forza Unità Parametro" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Se le unità sono fornite, i valori dei parametri devono corrispondere alle unità specificate" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Seriali Unici Globali" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "I numeri di serie per gli articoli di magazzino devono essere univoci" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Elimina scorte esaurite" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Determina il comportamento predefinito quando un articolo a magazzino è esaurito" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Modello Codice a Barre" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Modello per la generazione di codici batch predefiniti per gli elementi stock" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Scadenza giacenza" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Abilita funzionalità di scadenza della giacenza" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Vendi giacenza scaduta" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Consenti la vendita di stock scaduti" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Tempo di Scorta del Magazzino" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Numero di giorni in cui gli articoli in magazzino sono considerati obsoleti prima della scadenza" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Crea giacenza scaduta" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Permetti produzione con stock scaduto" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Controllo della proprietà della giacenza" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Abilita il controllo della proprietà sulle posizioni e gli oggetti in giacenza" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Icona Predefinita Ubicazione di Magazzino" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Icona Predefinita Ubicazione di Magazzino (vuoto significa nessuna icona)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Mostra articoli a magazzino installati" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Visualizza gli articoli a magazzino installati nelle tabelle magazzino" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Verificare la distinta base durante l'installazione degli articoli" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Gli articoli di magazzino installati devono esistere nella distinta base per l'articolo principale" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Consenti trasferimento magazzino esaurito" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Consenti il trasferimento di articoli non disponibili a magazzino tra le diverse ubicazioni di magazzino" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Modello Di Riferimento Ordine Di Produzione" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Modello richiesto per generare il campo di riferimento ordine di produzione" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "È richiesto il Proprietario Responsabile" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "A ogni ordine deve essere assegnato un proprietario responsabile" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Richiede Articolo Attivo" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Impedisci la creazione di ordini di produzione per gli articolo inattivi" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Richiede Articolo Bloccato" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Impedisci la creazione di ordini di costruzione per le parti sbloccate" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Richiede un BOM valido" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Previene la creazione di ordini di costruzione a meno che BOM non sia stato convalidato" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Richiedi Ordini Dei Figli Chiusi" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Impedisci il completamento dell'ordine di costruzione fino alla chiusura di tutti gli ordini figli" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Ordini di Produzione Esterni" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Abilita funzionalità ordini di produzione esterni" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blocca Fino Al Passaggio Dei Test" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Impedisci che gli output di costruzione siano completati fino al superamento di tutti i test richiesti" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Abilita Ordini Di Reso" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Abilita la funzionalità ordine di reso nell'interfaccia utente" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Motivo di Riferimento per ordine di reso" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Modello richiesto per generare il campo di riferimento ordine di reso" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Modifica Ordini Di Reso Completati" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Consenti la modifica degli ordini di reso dopo che sono stati completati" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Modello Di Riferimento Ordine Di Vendita" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Modello richiesto per generare il campo di riferimento ordine di vendita" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Spedizione Predefinita Ordine Di Vendita" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Abilita la creazione di spedizioni predefinite con ordini di vendita" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Modifica Ordini Di Vendita Completati" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Consenti la modifica degli ordini di vendita dopo che sono stati spediti o completati" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "La Spedizione Richiede Controllo" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Impedire il completamento delle spedizioni fino a quando gli articoli sono stati controllati" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Segna gli ordini spediti come completati" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Gli ordini di vendita contrassegnati come spediti saranno automaticamente completati, bypassando lo stato \"spedito\"" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Modello di Riferimento Ordine D'Acquisto" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Modello richiesto per generare il campo di riferimento ordine di acquisto" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Modifica Ordini Di Acquisto Completati" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Consenti la modifica degli ordini di acquisto dopo che sono stati spediti o completati" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Converti Valuta" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Converti il valore dell'elemento in valuta base quando si riceve lo stock" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Completa Automaticamente Gli Ordini D'Acquisto" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Contrassegna automaticamente gli ordini di acquisto come completi quando tutti gli elementi della riga sono ricevuti" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Abilita password dimenticata" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Abilita la funzione password dimenticata nelle pagine di accesso" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Abilita registrazione" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Abilita auto-registrazione per gli utenti nelle pagine di accesso" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "SSO abilitato" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Abilita SSO nelle pagine di accesso" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Abilita registrazione SSO" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Abilita l'auto-registrazione tramite SSO per gli utenti nelle pagine di accesso" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Abilita sincronizzazione dei gruppi SSO" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Abilita la sincronizzazione dei gruppi InvenTree con i gruppi forniti dall'IdP" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "Chiave gruppo SSO" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Il nome dell'attributo di richiesta di gruppi fornito dall'IdP" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "Mappa del gruppo SSO" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Una mappatura dai gruppi SSO ai gruppi InvenTree locali. Se il gruppo locale non esiste, verrà creato." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Rimuovere i gruppi al di fuori dell'SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Indica se i gruppi assegnati all'utente debbano essere rimossi se non sono backend dall'IdP. La disattivazione di questa impostazione potrebbe causare problemi di sicurezza" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email richiesta" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Richiedi all'utente di fornire una email al momento dell'iscrizione" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Riempimento automatico degli utenti SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Compila automaticamente i dettagli dell'utente dai dati dell'account SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Posta due volte" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Al momento della registrazione chiedere due volte all'utente l'indirizzo di posta elettronica" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Password due volte" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Al momento della registrazione chiedere agli utenti due volte l'inserimento della password" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Domini consentiti" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Limita la registrazione a determinati domini (separati da virgola, a partire da @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Gruppo iscrizione" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Gruppo a cui i nuovi utenti sono assegnati alla registrazione. Se la sincronizzazione di gruppo SSO è abilitata, questo gruppo è impostato solo se nessun gruppo può essere assegnato dall'IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Applica MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Gli utenti devono utilizzare la sicurezza a due fattori." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "Abilitare questa impostazione richiederà a tutti gli utenti di impostare l'autenticazione multi fattore. Tutte le sessioni saranno disconnesse immediatamente." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Controlla i plugin all'avvio" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Controlla che tutti i plugin siano installati all'avvio - abilita in ambienti contenitore" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Controlla gli aggiornamenti dei plugin" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Abilita controlli periodici per gli aggiornamenti dei plugin installati" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Abilita l'integrazione URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Attiva plugin per aggiungere percorsi URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Attiva integrazione navigazione" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Abilita i plugin per l'integrazione nella navigazione" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Abilita l'app integrata" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Abilita plugin per aggiungere applicazioni" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Abilita integrazione pianificazione" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Abilita i plugin per eseguire le attività pianificate" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Abilita eventi integrati" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Abilita plugin per rispondere agli eventi interni" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Abilita integrazione interfaccia" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Abilita i plugin per l'integrazione nell'interfaccia utente" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Abilita integrazione email" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Abilita i plugin per elaborare le email in uscita/in arrivo" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Abilita codici progetto" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Abilita i codici del progetto per tracciare i progetti" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Abilita la funzionalità per registrare i livelli storici e il valore del magazzino" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Escludi Posizioni Esterne" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Inventario periodico automatico" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Visualizza i nomi completi degli utenti" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Mostra nomi completi degli utenti invece che nomi utente" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Visualizza Profili Utente" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Visualizza i profili degli utenti sulla pagina del loro profilo" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Abilita Dati Stazione Di Prova" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Abilita la raccolta dati della stazione di prova per i risultati del test" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "Abilita Ping Macchina" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Abilita l'attività di ping periodico delle macchine registrate per controllarne lo stato" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Numero di risultati da visualizzare in ciascuna sezione della finestra di anteprima della ricerca" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Ricerca con regex" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Abilita le espressioni regolari nelle query di ricerca" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Ricerca Parole Intere" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Le query di ricerca restituiscono i risultati per intere corrispondenze di parola" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Ricerca Note" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Le query di ricerca restituiscono i risultati per le corrispondenze dalle note dell'elemento" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Il tasto Esc chiude i moduli" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Utilizzare il tasto Esc per chiudere i moduli modali" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Barra di navigazione fissa" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "La posizione della barra di navigazione è fissata nella parte superiore dello schermo" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "Intestazioni Fisse Della Tabella" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Le intestazioni della tabella sono fissate alla parte superiore della tabella" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Mostra Spotlight" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Abilita funzionalità di navigazione spotlight" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Icone per la Navigazione" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Visualizza le icone nella barra di navigazione" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Formato Data" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Formato predefinito per visualizzare le date" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Visualizza Cronologia Magazzino" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Mostra le informazioni sulla cronologia delle magazzino nella pagina dei dettagli articolo" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Mostra L'Ultimo Breadcrumb" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Mostra la pagina corrente nel Breadcrumb" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Mostra tutte lo posizioni del magazzino nelle tabelle" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Disabilitato: Mostra il percorso completo al passaggio del mouse. Abilitato: Mostra il percorso completo come testo." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Mostra tutte le categorie degli articoli nelle tabelle" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Disabilitato: Mostra il percorso completo delle categorie al passaggio del mouse. Abilitato: Mostra il percorso completo delle categorie come testo." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Ricevi segnalazioni di errore" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Ricevi notifiche per errori di sistema" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Ultime stampanti usate" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Salva le ultime stampanti usate da un'utente" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Tutti i modelli" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Nessun tipo di modello allegato fornito" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Tipo di modello allegato non valido" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "I posti minimi non possono essere superiori al massimo" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Il numero massimo di posti non può essere inferiore al minimo" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Un dominio vuoto non è consentito." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Nome dominio non valido: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Il valore deve essere maiuscolo" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Il valore deve essere un identificatore variabile valido" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "L'articolo è attivo" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Il produttore è attivo" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "L'articolo fornitore è attivo" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "L'articolo interno è attivo" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Il fornitore è attivo" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Produttore" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Azienda" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Ha Scorte" @@ -4123,8 +4387,8 @@ msgstr "Numero di telefono di contatto" msgid "Contact email address" msgstr "Indirizzo email" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Contatto" @@ -4176,283 +4440,283 @@ msgstr "Partita IVA" msgid "Company Tax ID" msgstr "Codice Fiscale Azienda" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Indirizzo" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Indirizzi" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Seleziona azienda" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Titolo indirizzo" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Titolo che descrive la voce indirizzo" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Indirizzo Principale" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Imposta come indirizzo primario" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Linea 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Indirizzo (linea 1)" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Linea 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Indirizzo (linea 2)" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "CAP" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Città/Regione" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Codice postale città/regione" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Stato/Provincia" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Stato o provincia" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Nazione" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Indirizzo Paese" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Note di spedizione del corriere" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Note per il corriere di spedizione" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Note di spedizione interne" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Note di spedizione per uso interno" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Collegamento alle informazioni sull'indirizzo (esterno)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Codice articolo produttore" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Articolo di base" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Seleziona articolo" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Seleziona Produttore" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "Codice articolo produttore (MPN)" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Codice articolo produttore" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL dell'articolo del fornitore" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Descrizione articolo costruttore" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Le unità del pacchetto devono essere compatibili con le unità dell'articolo base" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Le unità del pacchetto devono essere maggiori di zero" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "L'articolo del costruttore collegato deve riferirsi alla stesso articolo" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fornitore" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Seleziona fornitore" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Unità di giacenza magazzino fornitore" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Questo articolo fornitore è attivo?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Selezionare un produttore" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL dell'articolo del fornitore" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Descrizione articolo fornitore" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "costo base" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Onere minimo (ad esempio tassa di stoccaggio)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Confezionamento" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Imballaggio del pezzo" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Quantità Confezione" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Quantità totale fornita in una singola confezione. Lasciare vuoto per gli articoli singoli." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "multiplo" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Ordine multiplo" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Quantità disponibile dal fornitore" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Disponibilità Aggiornata" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Data dell’ultimo aggiornamento dei dati sulla disponibilità" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Sconto Prezzo Fornitore" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Valuta predefinita utilizzata per questo fornitore" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Nome Azienda" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "In magazzino" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Sconti a scalare" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Errore durante l'esportazione dei dati" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Il plugin di esportazione dati ha restituito un formato di dati errato" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Formato di esportazione" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Seleziona il formato del file di esportazione" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Esporta Plugin" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Seleziona plugin di esportazione" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Ulteriori informazioni sullo stato di questo articolo" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Chiave di stato personalizzata" @@ -4476,123 +4740,152 @@ msgstr "Inviato" msgid "Invalid status code" msgstr "Codice di stato non valido" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "File dati" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "File dati da importare" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Colonne" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Tipo di modello di destinazione per questa sessione di importazione" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Stato importazione" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Valori predefiniti del campo" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Sostituisci campo" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Filtri campo" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Aggiorna i record esistenti" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Se abilitato, i record esistenti verranno aggiornati con i nuovi dati" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Alcuni campi richiesti non sono stati mappati" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Identificatore del database esistente per il record" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "La colonna è già mappata a un campo del database" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Il campo è già mappato a una colonna di dati" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "La mappatura delle colonne deve essere collegata a una sessione di importazione valida" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "La colonna non esiste nel file dati" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Il campo non esiste nel modello di destinazione" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Il campo selezionato è di sola lettura" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Sessione d'importazione" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Campo" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Colonna" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Indice riga" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Dati riga originali" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Errori" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Valido" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "L'ID è richiesto per aggiornare i record esistenti." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Nessun record trovato con l'ID fornito" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Formato ID fornito non valido" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "L'ID è richiesto per aggiornare i record esistenti." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Formato file dati non supportato" @@ -4600,43 +4893,47 @@ msgstr "Formato file dati non supportato" msgid "Failed to open data file" msgstr "Apertura del file dati non riuscita" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Dimensioni file dati non valida" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Campi predefiniti non validi" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Sostituzione campo non valida" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Filtri campo non validi" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Righe" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Elenco degli ID delle righe da accettare" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Nessuna riga fornita" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "La riga non appartiene a questa sessione" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "La riga contiene dati non validi" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "La riga è già stata completata" @@ -4672,115 +4969,115 @@ msgstr "Il file dati contiene troppe colonne" msgid "Data file contains too many rows" msgstr "Il file di dati contiene troppe righe" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Il valore deve essere un oggetto dizionario valido" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Copie" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Numero di copie da stampare per ogni etichetta" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Connesso" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Sconosciuto" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Stampando" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Attenzione" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Nessun file multimediale" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Inceppamento della carta" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Disconnesso" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Errore" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Stampante Etichetta" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Stampa direttamente etichette per vari articoli." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Posizione Della Stampante" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Ambito della stampante a una posizione specifica" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Nome della macchina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Tipo di macchina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Tipo di macchina" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Driver" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Driver utilizzato per la macchina" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Le macchine possono essere disabilitate" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Driver disponibile" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Nessun errore" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Inizializzato" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Stato della Macchina" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Macchina" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Configurazione Macchina" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Tipo di configurazione" @@ -4792,7 +5089,7 @@ msgstr "Chiave della proprietà" msgid "Value of the property" msgstr "Valore della proprietà" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Gruppo" @@ -4816,117 +5113,118 @@ msgstr "Progresso Massimo" msgid "Maximum value for progress type, required if type=progress" msgstr "Valore massimo per il tipo di avanzamento, richiesto se tipo = progresso" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Riferimento ordine" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "In Sospeso" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Ha il codice del progetto" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Creato Da" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Creato prima" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Creato dopo" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Ha data d'inizio" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Data d'inizio prima" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Data d'inizio dopo" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Ha data di fine" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Data obiettivo prima" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Data obiettivo dopo" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Prezzo Articolo" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Completato prima" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Completato dopo" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Ordine di Produzione Esterno" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Ordine" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Ordine completato" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Articolo interno" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Ordine in sospeso" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Completato" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Ha Spedizione" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Ordine D'Acquisto" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Ordine D'Acquisto" msgid "Sales Order" msgstr "Ordini di Vendita" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Restituisci ordine" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Prezzo Totale" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Prezzo totale dell'ordine" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Valuta ordine" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Valuta per questo ordine (lasciare vuoto per usare il valore predefinito dell'azienda)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Questo ordine è bloccato e non può essere modificato" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Il contatto non corrisponde all'azienda selezionata" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "La data d'inizio deve essere precedente alla data di fine" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "L'indirizzo non corrisponde all'azienda selezionata" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Descrizione dell'ordine (opzionale)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Seleziona il codice del progetto per questo ordine" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Collegamento a un sito web esterno" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Data iniziale" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Data d'inizio programmata per questo ordine" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Data scadenza" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Data prevista per la consegna dell'ordine. L'ordine scadrà dopo questa data." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Data di emissione" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Data di emissione ordine" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Utente o gruppo responsabile di questo ordine" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Punto di contatto per questo ordine" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Indirizzo dell'azienda per questo ordine" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Riferimento ordine" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Stato" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Stato ordine d'acquisto" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Azienda da cui sono stati ordinati gli articoli" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Riferimento fornitore" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Codice di riferimento ordine fornitore" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "ricevuto da" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Data ordine completato" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Destinazione" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Destinazione per gli elementi ricevuti" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Il fornitore dell'articolo deve corrispondere al fornitore dell'ordine di produzione" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "L'elemento di riga non corrisponde all'ordine di acquisto" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "Manca un elemento collegato" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "La quantità deve essere un numero positivo" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Azienda da cui sono stati ordinati gli elementi" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Stato ordine di vendita" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Riferimento Cliente " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Codice di riferimento Ordine del Cliente" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Data di spedizione" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "spedito da" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "L'elemento di riga non è associato a questo ordine" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Nessuna corrispondenza trovata per i seguenti numeri di serie" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "I seguenti numeri di serie non sono disponibili" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "L'ordine è già stato completato" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "L'ordine è già stato annullato" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Solo un ordine aperto può essere contrassegnato come completo" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "L'ordine non può essere completato in quanto ci sono spedizioni incomplete" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "L'ordine non può essere completato perché ci sono allocazioni incomplete" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "L'ordine non può essere completato perché ci sono elementi di riga incompleti" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "L'ordine è bloccato e non può essere modificato" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Quantità Elementi" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Riferimento Linea Elemento" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Note linea elemento" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Data di destinazione per questa voce di riga (lasciare vuoto per utilizzare la data di destinazione dall'ordine)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Descrizione della parte (opzionale)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Contesto aggiuntivo per questa voce" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Prezzo unitario" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Riga ordine d'acquisto" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "L'articolo del fornitore deve corrispondere al fornitore" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "L'ordine di produzione deve essere contrassegnato come esterno" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Gli ordini di costruzione possono essere collegati solo alle parti di assemblaggio" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "L'articolo dell'ordine di produzione deve corrispondere all'articolo della riga" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Articolo Fornitore" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Ricevuto" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Numero di elementi ricevuti" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Prezzo di Acquisto" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Prezzo di acquisto unitario" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Ordine di produzione esterno che deve essere eseguito da questo articolo" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Riga Extra ordine di acquisto" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Articolo ordine di vendita" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Solo gli articoli vendibili possono essere assegnati a un ordine di vendita" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Prezzo di Vendita" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Prezzo unitario di vendita" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Spedito" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Quantità spedita" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Spedizione dell'ordine di vendita" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "L'indirizzo di spedizione deve corrispondere al cliente" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Indirizzo di consegna per questa spedizione" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Data di spedizione" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Data di consegna" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Data di consegna della spedizione" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Verificato Da" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Utente che ha controllato questa spedizione" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Spedizione" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Numero di spedizione" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Numero di monitoraggio" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Informazioni di monitoraggio della spedizione" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Numero Fattura" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Numero di riferimento per la fattura associata" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "La spedizione è già stata spedita" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "La spedizione non ha articoli di stock assegnati" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "La spedizione deve essere controllata prima che possa essere completata" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Riga Extra ordine di vendita" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Assegnazione Ordini Di Vendita" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "L'elemento di magazzino non è stato assegnato" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Impossibile allocare l'elemento stock a una linea con un articolo diverso" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Impossibile allocare stock a una riga senza un articolo" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "La quantità di ripartizione non puo' superare la disponibilità della giacenza" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "La quantità di assegnazione deve essere maggiore di zero" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "La quantità deve essere 1 per l'elemento serializzato" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "L'ordine di vendita non corrisponde alla spedizione" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "La spedizione non corrisponde all'ordine di vendita" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Linea" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Riferimento della spedizione ordine di vendita" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Elemento" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Seleziona elemento stock da allocare" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Inserisci la quantità assegnata alla giacenza" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Riferimento ordine di reso" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Società a cui vengono restituiti gli articoli" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Stato ordine di reso" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Articolo Linea Ordine Reso" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "L'elemento stock deve essere specificato" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Quantità di reso superiore alla quantità di scorta" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "La quantità di reso deve essere maggiore di zero" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Quantità non valida per l'elemento stock serializzato" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Seleziona l'elemento da restituire dal cliente" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Data di ricezione" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "La data in cui questo articolo restituito è stato ricevuto" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Risultati" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Risultato per questa voce di riga" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Costo associato alla restituzione o riparazione per questa voce di linea" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Riga Extra ordine di reso" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID Ordine" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID dell'ordine da duplicare" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Copia Linee" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Copia gli elementi di riga dall'ordine originale" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Copia Linee Extra" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Copia gli elementi di riga extra dall'ordine originale" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Copia parametri" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Elementi Riga" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Righe Completate" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Duplica Ordine" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Specifica le opzioni per duplicare questo ordine" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "ID dell'ordine non corretto" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Nome Fornitore" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "L'ordine non può essere cancellato" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Consenti di chiudere l'ordine con elementi di riga incompleti" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "L'ordine ha elementi di riga incompleti" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "L'ordine non è aperto" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Prezzo Automatico" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Calcola automaticamente il prezzo di acquisto in base ai dati del fornitore articolo" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Valuta prezzo d'acquisto" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Unisci elementi" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Unisce gli elementi con lo stesso articolo, destinazione e data di destinazione in una riga" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Codice articolo" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Numero Dell'articolo Interno" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Numero Articolo Interno" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "L'articolo del fornitore deve essere specificato" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "L'ordine di acquisto deve essere specificato" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Il fornitore deve essere abbinato all'ordine d'acquisto" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "L'ordine di acquisto deve essere abbinato al fornitore" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Elemento Riga" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Seleziona la posizione di destinazione per gli elementi ricevuti" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Inserisci il codice univoco per gli articoli in arrivo" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Data di Scadenza" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Inserisci la data di scadenza per gli articoli in arrivo" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Inserisci i numeri di serie per gli articoli stock in arrivo" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Sovrascrivi le informazioni d'imballaggio per gli articoli in arrivo" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Nota aggiuntiva per gli articoli in arrivo" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Codice a Barre" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Codice a barre scansionato" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Il codice a barre è già in uso" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Gli elementi di linea devono essere forniti" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "La destinazione deve essere specificata" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "I valori dei codici a barre forniti devono essere univoci" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Spedizioni" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Spedizioni Completate" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Valuta prezzo di vendita" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Elementi Assegnati" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Nessun dettaglio di spedizione fornito" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "L'elemento di riga non è associato a questo ordine" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "La quantità deve essere positiva" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Inserisci i numeri di serie da assegnare" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "La spedizione è già stata spedita" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "La spedizione non è associata con questo ordine" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Nessuna corrispondenza trovata per i seguenti numeri di serie" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "I seguenti numeri di serie non sono disponibili" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Articoli Linea Ordine Reso" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "L'elemento di riga non corrisponde all'ordine di reso" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "L'elemento di riga è già stato ricevuto" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Gli elementi possono essere ricevuti solo con ordini in corso" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Quantità da restituire" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Valuta del prezzo" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Perso" @@ -5718,1279 +6125,1312 @@ msgstr "Perso" msgid "Returned" msgstr "Reso" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "In corso" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Indietro" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Riparare" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Sostituire" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Rimborso" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Rifiuta" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Emesso" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Ordine D'Acquisto in ritardo" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "L'ordine d'acquisto {po} è in ritardo" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Ordini Di Vendita in ritardo" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "L'ordine di vendita {so} è ora in ritardo" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Ordini di Reso in Ritardo" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "L'ordine di reso {ro} è ora in ritardo" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Preferiti" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Filtra per categorie preferite" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Profondità" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filtra per profondità categoria" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Livello principale" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filtra per categorie di primo livello" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Cascata" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Includi sottocategorie nei risultati filtrati" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Genitore" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Filtra per categoria genitore" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Escludi sottocategorie sotto la categoria specificata" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Ha Risultati" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "È una Variante" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "E' una revisione" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Ha revisioni" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "BOM Valido" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Categorie a Cascata" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Se Vero, includere gli elementi nelle categorie figlie della categoria specificata" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Filtra per categoria ID numerica o per la stringa 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "L'articolo assemblato è provabile" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Il componente è provabile" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Utilizzi" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Categoria Articoli" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Categorie Articolo" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Posizione Predefinita" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Posizione predefinita per gli articoli di questa categoria" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Strutturale" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Le parti non possono essere assegnate direttamente a una categoria strutturale, ma possono essere assegnate a categorie subordinate." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Keywords predefinite" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Parole chiave predefinite per gli articoli in questa categoria" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Icona" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Icona (facoltativa)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Non puoi rendere principale questa categoria di articoli perché alcuni articoli sono già assegnati!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Modello Parametro Categoria Articolo" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Valore Predefinito" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Valore Parametro Predefinito" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Articoli" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "Impossibile eliminare i parametri di una parte bloccata" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "Impossibile modificare i parametri di una parte bloccata" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Impossibile eliminare questo articolo perché è bloccato" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Impossibile eliminare questo articolo perché è ancora attivo" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Non è possibile eliminare questo articolo in quanto è utilizzato in una costruzione" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "L'articolo '{self}' non può essere usata nel BOM per '{parent}' (ricorsivo)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "L'articolo '{parent}' è usato nel BOM per '{self}' (ricorsivo)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN deve corrispondere al modello regex {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "L'articolo non può essere una revisione di se stesso" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Le revisioni sono consentite solo per le parti di assemblaggio" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Non è possibile effettuare la revisione di un articolo modello" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "L'articolo genitore deve puntare allo stesso modello" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Esiste già un elemento stock con questo numero seriale" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Non è consentito duplicare IPN nelle impostazioni dell'articolo" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "La revisione dell'articolo duplicata esiste già." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Un articolo con questo Nome, IPN e Revisione esiste già." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Gli articoli non possono essere assegnati a categorie articolo principali!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Nome articolo" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "È Template" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Quest'articolo è un articolo di template?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Questa parte è una variante di un altro articolo?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variante Di" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Descrizione della parte (opzionale)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Parole Chiave" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Parole chiave per migliorare la visibilità nei risultati di ricerca" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Categoria articolo" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN - Numero di riferimento interno" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Numero di revisione o di versione" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revisione" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Questo articolo è una revisione di un altro articolo?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Revisione di" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Dove viene normalmente immagazzinato questo articolo?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Scadenza Predefinita" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Scadenza (in giorni) per gli articoli in giacenza di questo pezzo" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Scorta Minima" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Livello minimo di giacenza consentito" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Unita di misura per questo articolo" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Questo articolo può essere costruito da altri articoli?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Questo articolo può essere utilizzato per costruire altri articoli?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Questo articolo ha il tracciamento per gli elementi unici?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Questo articolo può avere delle prove registrate?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Quest'articolo può essere acquistato da fornitori esterni?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Questo pezzo può essere venduto ai clienti?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Quest'articolo è attivo?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Gli articoli bloccati non possono essere modificati" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "È una parte virtuale, come un prodotto software o una licenza?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "BOM Convalidata" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Il BOM per questa parte è valido?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Somma di controllo Distinta Base" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Somma di controllo immagazzinata Distinta Base" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Distinta Base controllata da" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Data di verifica Distinta Base" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Creazione Utente" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Utente responsabile di questo articolo" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Vendita multipla" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Valuta utilizzata per calcolare i prezzi" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Costo Minimo Distinta Base" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Costo minimo dei componenti dell'articolo" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Costo Massimo Distinta Base" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Costo massimo dei componenti dell'articolo" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Importo Acquisto Minimo" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Costo minimo di acquisto storico" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Importo massimo acquisto" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Costo massimo di acquisto storico" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Prezzo Interno Minimo" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Costo minimo basato su interruzioni di prezzo interne" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Prezzo Interno Massimo" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Costo massimo basato su interruzioni di prezzo interne" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Prezzo Minimo Fornitore" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Prezzo minimo articolo da fornitori esterni" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Prezzo Massimo Fornitore" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Prezzo massimo dell'articolo proveniente da fornitori esterni" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Variazione di costo minimo" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Costo minimo calcolato di variazione dell'articolo" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Massima variazione di costo" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Costo massimo calcolato di variazione dell'articolo" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Costo Minimo" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Sovrascrivi il costo minimo" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Costo Massimo" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Sovrascrivi il costo massimo" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Costo minimo totale calcolato" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Costo massimo totale calcolato" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Prezzo Di Vendita Minimo" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Prezzo minimo di vendita basato sulle interruzioni di prezzo" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Prezzo Di Vendita Massimo" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Prezzo massimo di vendita basato sulle interruzioni di prezzo" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Costo Di Vendita Minimo" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Prezzo storico minimo di vendita" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Costo Di Vendita Minimo" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Prezzo storico massimo di vendita" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Articolo per l'inventario" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Contatore Elemento" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Numero di scorte individuali al momento dell'inventario" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Totale delle scorte disponibili al momento dell'inventario" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Data" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Data in cui è stato effettuato l'inventario" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Costo Minimo Scorta" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Costo minimo stimato di magazzino a disposizione" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Costo Massimo Scorte" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Costo massimo stimato di magazzino a disposizione" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Aggiungi Prezzo Ribassato di Vendita dell'Articolo" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Modello Prove Articolo" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Nome modello non valido - deve includere almeno un carattere alfanumerico" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Il modello di prova può essere creato solo per gli articoli testabili" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Il modello di test con la stessa chiave esiste già per l'articolo" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Nome Test" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Inserisci un nome per la prova" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Chiave Di Prova" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Chiave semplificata per la prova" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Descrizione Di Prova" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Inserisci descrizione per questa prova" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Questo test è attivo?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Richiesto" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Questa prova è necessaria per passare?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Valore richiesto" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Questa prova richiede un valore quando si aggiunge un risultato di prova?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Allegato Richiesto" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Questa prova richiede un file allegato quando si aggiunge un risultato di prova?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Scelte valide per questo test (separate da virgole)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "L'articolo nella distinta base non può essere modificato - l'assemblaggio è bloccato" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "L'articolo nella distinta base non può essere modificato - l'assemblaggio della variante è bloccato" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Seleziona articolo principale" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Articolo subordinato" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Seleziona l'articolo da utilizzare nella Distinta Base" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Quantità Distinta Base per questo elemento Distinta Base" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Questo elemento della Distinta Base è opzionale" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Questo elemento della Distinta Base è consumabile (non è tracciato negli ordini di produzione)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Imposta quantità" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Quantità extra necessaria per una generazione, per tenere conto delle perdite di configurazione" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Logoramento" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Stima del logoramento per una build, espressa in percentuale (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Arrotondamento Multiplo" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Arrotonda la quantità di produzione richiesta al multiplo più vicino di questo valore" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Riferimento Elemento Distinta Base" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Note Elemento Distinta Base" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Codice di controllo" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Codice di controllo Distinta Base" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Convalidato" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Questo articolo della distinta base è stato validato" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Viene Ereditato" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Questo elemento della Distinta Base viene ereditato dalle Distinte Base per gli articoli varianti" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Gli elementi in giacenza per gli articoli varianti possono essere utilizzati per questo elemento Distinta Base" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "La quantità deve essere un valore intero per gli articoli rintracciabili" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "L'articolo subordinato deve essere specificato" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Elemento Distinta Base Sostituito" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "La parte sostituita non può essere la stessa dell'articolo principale" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Elemento principale Distinta Base" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Sostituisci l'Articolo" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Articolo 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Articolo 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Seleziona Prodotto Relativo" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Nota per questa relazione" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Non si può creare una relazione tra l'articolo e sé stesso" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "La relazione duplicata esiste già" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Categoria Superiore" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Categoria articolo principale" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Sottocategorie" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Risultati" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Numero di risultati registrati rispetto a questo modello" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Valuta di acquisto di questo articolo in stock" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Il file non è un immagine" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Articolo Originale" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Seleziona l'articolo originale da duplicare" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Copia immagine" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Copia immagine dall'articolo originale" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Copia Distinta Base" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Copia fattura dei materiali dall'articolo originale" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Copia i dati dei parametri dall'articolo originale" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Copia note" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Copia note dall'articolo originale" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Copia Test" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "Copia modelli di test dall'articolo originale" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Quantità iniziale" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Specificare la quantità iniziale disponibile per questo Articolo. Se la quantità è zero, non viene aggiunta alcuna quantità." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Ubicazione Iniziale Magazzino" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Specificare l'ubicazione iniziale del magazzino per questo Articolo" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Seleziona il fornitore (o lascia vuoto per saltare)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Seleziona il produttore (o lascia vuoto per saltare)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Codice articolo Produttore" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "L'azienda selezionata non è un fornitore valido" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "L'azienda selezionata non è un produttore valido" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "L'articolo del produttore che corrisponde a questo MPN esiste già" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "L'articolo del fornitore che corrisponde a questo SKU esiste già" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Nome Categoria" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "In Costruzione" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Quantità di questo articolo attualmente in produzione" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Eccezionale quantità di questa parte prevista da costruire" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Articoli in magazzino" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Revisioni" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Giacenze Totali" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Scorte Non Assegnate" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Scorta Variante" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Duplica articolo" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Copia i dati iniziali da un altro Articolo" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Copia immagine" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Copia immagine dall'articolo originale" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Copia Distinta Base" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Copia fattura dei materiali dall'articolo originale" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Copia note" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Copia note dall'articolo originale" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Copia Test" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Copia modelli di test dall'articolo originale" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Stock iniziale" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Crea Articolo con quantità di scorta iniziale" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Informazioni Fornitore" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Aggiungi le informazioni iniziali del fornitore per questo articolo" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Copia Parametri Categoria" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Copia i parametri dai modelli della categoria articolo selezionata" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Immagine esistente" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Nome del file di un'immagine articolo esistente" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Il file immagine non esiste" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Convalida l'intera Fattura dei Materiali" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Puoi produrre" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Richiesto per gli Ordini di Produzione" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Assegnato agli Ordini di Produzione" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Richiesto per gli Ordini di Vendita" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Assegnato agli Ordini di Vendita" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Prezzo Minimo" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Sovrascrivi valore calcolato per il prezzo minimo" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Valuta del prezzo minimo" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Prezzo Massimo" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Sovrascrivi valore calcolato per il prezzo massimo" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Valuta del prezzo massimo" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Aggiorna" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Aggiorna i prezzi per questo articolo" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Impossibile convertire dalle valute fornite in {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Il prezzo minimo non può essere maggiore del prezzo massimo" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Il prezzo massimo non può essere minore del prezzo minimo" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Seleziona l'assemblaggio padre" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Seleziona la componente" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Seleziona l'articolo da cui copiare la distinta base" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Rimuovi Dati Esistenti" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Rimuovi elementi distinta base esistenti prima di copiare" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Includi Ereditato" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Includi gli elementi Distinta Base ereditati da prodotti template" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Salta Righe Non Valide" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Abilita questa opzione per saltare le righe non valide" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Copia Articoli sostitutivi" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Copia articoli sostitutivi quando duplichi gli elementi distinta base" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Notifica di magazzino bassa" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Lo stock disponibile per {part.name} è sceso sotto il livello minimo configurato" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "Notifica di magazzino" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "Hai 1 oggetto in magazzino che si avvicina alla data di scadenza" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "Hai {item_count} oggetti in magazzino che si avvicinano alla data di scadenza" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "Nessuna data di scadenza." -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "Scaduto {abs(days_diff)} giorni fa" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Scade oggi" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} giorni" @@ -7011,7 +7451,7 @@ msgstr "Campione" msgid "Installed" msgstr "Installato" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Il plugin non può essere eliminato in quanto è attualmente attivo" @@ -7023,23 +7463,23 @@ msgstr "Nessuna azione specificata" msgid "No matching action found" msgstr "Nessuna azione corrispondente trovata" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Nessuna corrispondenza trovata per i dati del codice a barre" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Corrispondenza trovata per i dati del codice a barre" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Il modello non è supportato" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Istanza del modello non trovata" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Il codice a barre corrisponde a un elemento esistente" @@ -7055,51 +7495,67 @@ msgstr "Nessun fornitore articolo corrispondente trovato" msgid "Multiple matching supplier parts found" msgstr "Trovati più articoli fornitori corrispondenti" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Nessuna plugin corrispondente trovato per i dati del codice a barre" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Corrispondenza Articoli del Fornitore" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "L'articolo è già stato ricevuto" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Nessun plugin corrisponde al codice a barre del fornitore" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Trovati più articoli corrispondenti" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Nessun elemento corrispondente trovato" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Nessun ordine di vendita fornito" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Il codice a barre non corrisponde a un articolo di magazzino valido" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "L'elemento in magazzino non corrisponde alla riga" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Scorte insufficienti disponibili" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Articolo di magazzino assegnato all'ordine di vendita" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Informazioni non sufficienti" @@ -7108,23 +7564,23 @@ msgstr "Informazioni non sufficienti" msgid "Found matching item" msgstr "Trovato elemento corrispondente" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "L'articolo del fornitore non corrisponde alla riga" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "La riga è già stata completata" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Ulteriori informazioni richieste per ricevere la voce" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Ricevuta la linea dell'ordine d'acquisto" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Impossibile ricevere l'elemento della linea" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Fornisce supporto nativo per codici a barre" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Prefisso Codice A Barre Corto" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Personalizzare il prefisso utilizzato per codici a barre corti, può essere utile per ambienti con più istanze InvenTree" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "Creazione automatica di produzioni" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "Crea automaticamente ordini di produzione per gli assemblaggi" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "Questo URL è stato utilizzato per inviare messaggi a un canale rallentato" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Apri collegamento" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Modalità debug" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Salta Etichette" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Bordo" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Stampa un bordo intorno ad ogni etichetta" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Orizzontale" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Margine" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Margine intorno alla pagina in mm" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Etichetta troppo grande per la dimensione della pagina" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Nessuna etichetta generata" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "L'installazione dei plugin è disattivata" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Plugin installato con successo" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin installato in {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Nessun autore trovato" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Nome modello" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Descrizione del template" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Allega al Modello su Stampa" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Salva l'output del report come allegato contro l'istanza del modello collegato durante la stampa" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Formato del nome file" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtri" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Larghezza [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Larghezza dell'etichetta, specificata in mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Altezza [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Larghezza dell'etichetta, specificata in mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Snippet" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Report file snippet" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Descrizione file snippet" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Risorsa" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Report file risorsa" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "File risorsa descrizione" @@ -8291,23 +8771,23 @@ msgstr "File risorsa descrizione" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "Materiali necessari" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Emesso" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Richiesto Per" @@ -8380,8 +8857,8 @@ msgstr "Totale" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Numero Seriale" @@ -8405,7 +8882,7 @@ msgstr "Test Report Elemento Stock" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Elementi installati" @@ -8438,810 +8915,922 @@ msgstr "Nessun risultato (richiesto)" msgid "No result" msgstr "Nessun risultato" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "File immagine non trovato" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Nome della parte (maiuscole e minuscole)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Il nome della parte contiene (maiuscole e minuscole)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Nome della parte (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "IPN della parte (maiuscole e minuscole)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "IPN della parte contiene (maiuscole e minuscole)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "IPN della parte (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Giacenza minima" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Giacenza massima" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Codici di stato" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Ubicazione Esterna" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Obsoleto" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "La quantità è richiesta" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Deve essere fornita un articolo valido" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "I numeri di serie non possono essere forniti per un articolo non tracciabile" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Ubicazione magazzino" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Posizioni magazzino" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Proprietario" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Seleziona Owner" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Gli elementi di magazzino non possono essere direttamente situati in un magazzino strutturale, ma possono essere situati in ubicazioni secondarie." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Esterno" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Si tratta di una posizione esterna al magazzino" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Non puoi rendere strutturale questa posizione di magazzino perché alcuni elementi di magazzino sono già posizionati al suo interno!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "L'articolo deve essere specificato" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Gli articoli di magazzino non possono essere ubicati in posizioni di magazzino strutturali!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Non è possibile creare un elemento di magazzino per articoli virtuali" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "La quantità deve essere 1 per elementi con un numero di serie" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Il numero di serie non può essere impostato se la quantità è maggiore di 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "L'elemento non può appartenere a se stesso" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "L'elemento deve avere un riferimento di costruzione se is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Il riferimento di costruzione non punta allo stesso oggetto dell'articolo" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Elemento di magazzino principale" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Articolo base" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Seleziona un fornitore articolo corrispondente per questo elemento di magazzino" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Dove si trova questo articolo di magazzino?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Imballaggio di questo articolo di magazzino è collocato in" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Installato In" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Questo elemento è stato installato su un altro elemento?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Numero di serie per questo elemento" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Codice lotto per questo elemento di magazzino" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Quantità disponibile" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Genera Costruzione" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Costruisci per questo elemento di magazzino" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Origina Ordine di Acquisto" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Ordine d'acquisto per questo articolo in magazzino" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Destinazione Ordine di Vendita" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Data di scadenza per l'elemento di magazzino. Le scorte saranno considerate scadute dopo questa data" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Elimina al esaurimento" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Cancella questo Elemento di Magazzino quando la giacenza è esaurita" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Prezzo di acquisto unitario al momento dell’acquisto" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Convertito in articolo" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "L'articolo non è impostato come tracciabile" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "La quantità deve essere un numero intero" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "I numeri di serie devono essere forniti come elenco" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "La quantità non corrisponde ai numeri di serie" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "L'elemento di magazzino è stato assegnato a un ordine di vendita" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "L'elemento di magazzino è installato in un altro elemento" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "L'elemento di magazzino contiene altri elementi" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "L'elemento di magazzino è stato assegnato a un cliente" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "L'elemento di magazzino è attualmente in produzione" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Il magazzino serializzato non può essere unito" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Duplica elementi di magazzino" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Gli elementi di magazzino devono riferirsi allo stesso articolo" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Gli elementi di magazzino devono riferirsi allo stesso articolo fornitore" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "I codici di stato dello stock devono corrispondere" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Le giacenze non possono essere spostate perché non disponibili" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Note d'ingresso" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Il valore deve essere fornito per questo test" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "L'allegato deve essere caricato per questo test" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Risultato Test" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Test valore output" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Risultato della prova allegato" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Note del test" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Elemento principale" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Inserisci i numeri di serie per i nuovi elementi" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Scaduto" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Elementi secondari" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Inserisci il numero di elementi di magazzino da serializzare" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "La quantità non deve superare la quantità disponibile ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Posizione magazzino di destinazione" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Numeri di serie non possono essere assegnati a questo articolo" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Numeri di serie già esistenti" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Seleziona elementi di magazzino da installare" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Aggiungi nota di transazione (opzionale)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Elemento di magazzino non disponibile" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "L'articolo selezionato non è nella Fattura dei Materiali" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Posizione di destinazione per gli elementi disinstallati" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Seleziona l'articolo in cui convertire l'elemento di magazzino" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "L'articolo selezionato non è una valida opzione per la conversione" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Seleziona l'articolo in cui convertire l'elemento di magazzino" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "L'articolo selezionato non è una valida opzione per la conversione" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Sottoallocazioni" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "L'articolo deve essere vendibile" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "L'elemento è assegnato a un ordine di vendita" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Elemento assegnato a un ordine di costruzione" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Cliente a cui assegnare elementi di magazzino" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "L'azienda selezionata non è un cliente" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Note sull'assegnazione delle scorte" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Deve essere fornito un elenco degli elementi di magazzino" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Note di fusione di magazzino" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Consenti fornitori non corrispondenti" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Consenti di unire gli elementi di magazzino che hanno fornitori diversi" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Consenti stato non corrispondente" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Consenti di unire gli elementi di magazzino con diversi codici di stato" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Devono essere riforniti almeno due elementi in magazzino" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Nessun cambiamento" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Valore di chiave primaria StockItem" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Note sugli spostamenti di magazzino" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Note sugli spostamenti di magazzino" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Elemento stock raggruppato" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Convertito in variante" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Genera l'output dell'ordine creato" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Build order output completato" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Ordine di costruzione rifiutato" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Impegnato dall'ordine di costruzione" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Spedito contro l'ordine di vendita" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Ricevuto contro l'ordine di acquisto" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Restituito contro l'ordine di ritorno" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Inviato al cliente" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Restituito dal cliente" @@ -9527,19 +10124,19 @@ msgstr "Utenti" msgid "Select which users are assigned to this group" msgstr "Selezionare quali utenti sono assegnati a questo gruppo" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Informazioni personali" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Permessi" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Date Importanti" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Il token è stato revocato" @@ -9547,279 +10144,283 @@ msgstr "Il token è stato revocato" msgid "Token has expired" msgstr "Il token è scaduto" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "Token API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Token API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Nome Token" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Nome token personalizzato" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Data di scadenza token" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Ultimo accesso" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Revocato" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Impostazione autorizzazioni" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Visualizza" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Autorizzazione a visualizzare gli articoli" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Aggiungi" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Autorizzazione ad aggiungere elementi" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Modificare" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Permessi per modificare gli elementi" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Elimina" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Autorizzazione ad eliminare gli elementi" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Bot" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Interno" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Ospite" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Lingua" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Lingua preferita dell'utente" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Tema" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Widgets" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Nome Visualizzato" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Amministratore" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Ordine di acquisto" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Ordini di Vendita" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Ordini di reso" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Nome utente" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Nome" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Nome dell'utente" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Cognome" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Cognome dell'utente" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Indirizzo email dell'utente" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superuser" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Questo utente è un superutente" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Questo account utente è attivo" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Il tuo account è stato creato." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Si prega di utilizzare la funzione di reimpostazione password per accedere" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Benvenuto in InvenTree" diff --git a/src/backend/InvenTree/locale/ja/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/ja/LC_MESSAGES/django.po index 6dcbe5868d..1d80931525 100644 --- a/src/backend/InvenTree/locale/ja/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/ja/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Japanese\n" "Language: ja_JP\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "APIエンドポイントが見つかりません" -#: InvenTree/api.py:438 -msgid "List of items must be provided for bulk operation" -msgstr "" - #: InvenTree/api.py:445 +msgid "List of items must be provided for bulk operation" +msgstr "一括処理を行うには、部品リストを指示する必要があります" + +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "項目はリストとして提供されなければなりません" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "無効なアイテムリスト" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "すべてのフィルターは真の場合にのみ使用されなければならない" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "指定された条件に一致する項目がありません" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "データの提供がありません。" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "この項目は一意である必要があります。" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "ユーザーにこのモデルを表示する権限がありません" @@ -65,150 +69,155 @@ msgstr "メールアドレスの確認" msgid "You must type the same email each time." msgstr "毎回同じメールアドレスを入力する必要があります。" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "指定されたプライマリEメールアドレスは無効です。" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "指定されたメールドメインは承認されていません。" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "無効な単位 ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "値がありません" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "{original}を{unit}に変換できませんでした。" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "数量コードが無効です" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "エラーの詳細は管理者パネルで確認できます" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "日付を入力する" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "無効な10進数値" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "メモ" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "値 '{name}' はパターン形式で表示されません" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "指定された値が必要なパターンと一致しません: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "一度に1000以上のアイテムをシリアライズすることはできません。" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "シリアル番号は空です" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "重複シリアル" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "無効なグループです:{group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "グループ範囲 {group} が許容数量を超過 ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "シリアル番号が見つかりません" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "固有のシリアル番号の数({n})は数量({q})と一致する必要があります。" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "この値からHTMLタグを削除" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "データに禁止されているマークダウン・コンテンツが含まれています。" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" -msgstr "" +msgstr "無効なURL:ホスト名がありません" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" -msgstr "" +msgstr "無効なURL:ホスト名を解決できませんでした" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" -msgstr "" +msgstr "URLがプライベートIPアドレスまたは予約済みIPアドレスを指しています" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" -msgstr "" +msgstr "リダイレクトが多すぎます" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "接続エラー" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "サーバは無効なステータスコードで応答しました" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "例外が発生しました" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "サーバーが無効なContent-Length値で応答しました" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "画像サイズが大きすぎます" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "画像のダウンロードが最大サイズを超えました" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "リモートサーバーが空のレスポンスを返しました" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "指定されたURLは有効な画像ファイルではありません" @@ -216,159 +225,203 @@ msgstr "指定されたURLは有効な画像ファイルではありません" msgid "Log in to the app" msgstr "アプリにログイン" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "メールアドレス" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "CSRF検証に失敗しました。INVENTREE_SITE_URLとINVENTREE_TRUSTED_ORIGINSが正しく設定されていることを確認してください。" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "二要素認証を有効にする必要があります。" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "プラグイン検証の実行エラー" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "メタデータは python dict オブジェクトでなければなりません。" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "プラグインメタデータ" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "外部プラグインで使用するためのJSONメタデータフィールド" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "不適切な書式パターン" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "不明なフォーマットキーが指定されました" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "必要なフォーマットキーがありません" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "参照フィールドを空にすることはできません。" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "参照は必須パターンに一致する必要があります。" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "参照番号が大きすぎる" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "無効な選択です" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "お名前" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "説明" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "説明 (オプション)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "パス" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "同じ親に重複した名前は存在しません。" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "マークダウンメモ (オプション)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "バーコード情報" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "サードパーティ製バーコードデータ" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "バーコードハッシュ" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "バーコードデータのユニークなハッシュ" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "既存のバーコードが見つかりました" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "サーバーエラー" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "サーバーによってエラーが記録されました。" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "画像" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "有効な数字でなければなりません" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "通貨" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "利用可能なオプションから通貨を選択してください" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "この項目は空欄にできません。" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "無効な値です。" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "無効なコンテンツタイプ形式です" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "コンテンツタイプが見つかりません" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "コンテンツタイプが必須のミックスインクラスと一致しません" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "コピーパラメータ" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "コピーライン" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "元の注文から行項目をコピー" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "余分な行をコピー" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "元の注文から余分な項目をコピー" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "アラビア語" @@ -521,46 +574,48 @@ msgstr "中国語 (簡体字)" msgid "Chinese (Traditional)" msgstr "中国語 (繁体字)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "アップデートが利用可能" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "InvenTreeの更新版が利用可能になりました" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "無効な物理単位" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "有効な通貨コードではありません。" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "注文ステータス" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "親ビルド" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "バリアントを含む" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "バリアントを含む" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "バリアントを含む" msgid "Part" msgstr "パーツ" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "カテゴリ" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "祖先ビルド" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "担当" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "割り当て" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "作成前" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "の後に作成されました。" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "開始日あり" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "開始日 前" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "開始日 後" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "目標期日あり" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "目標期日" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "以降の目標日" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "完成前" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "終了後" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "最小日付" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "最大日付" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "ツリーを除く" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "削除するには、ビルドをキャンセルする必要があります。" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "消耗品" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "オプション" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "アセンブリ" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "追跡" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "テスト可能" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "受注残高" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "割り当てられた" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "消費されました" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "利用可能" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "注文中" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" -msgstr "" +msgstr "ビルドが見つかりません" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "組立注文" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "場所" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "出力" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "出力ストックアイテムIDでフィルタリングします。未インストールビルドアイテムを検索するには「null」をご使用ください。" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "組立注文" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "アセンブリBOMが検証されていません" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "非アクティブな部品にビルドオーダーを作成できません。" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "ロックされていない部品にビルドオーダーを作成できません。" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "ビルドオーダーを外部委託できるのは、購入可能部品のみです" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "担当ユーザーまたはグループを指定する必要があります。" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "ビルドオーダー部品は変更できません" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "目標期日は開始日以降であること" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "ビルド・オーダー・リファレンス" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "参照" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "建築の簡単な説明(任意)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" -msgstr "" +msgstr "このビルドが引き当てられているビルドオーダー" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "製造する部品の選択" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "セールス・オーダー・リファレンス" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" -msgstr "" +msgstr "このビルドが引き当てられている受注" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "ソース・ロケーション" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "このビルドで在庫を取得する場所を選択します(任意の在庫場所から取得する場合は空白のままにしてください)。" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "外部ビルド" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "このビルドオーダーは外部委託されます。" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "目的地" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "完成したアイテムの保管場所を選択" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "数量" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "構築するストックアイテムの数" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "完成品" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "完了した在庫アイテムの数" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "組立状況" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "ビルドステータスコード" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "バッチコード" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "このビルド出力のバッチコード" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "作成日時" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "ビルド開始日" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "この注文の開始予定日" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "完成目標日" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "ビルド完了目標日。この日付を過ぎると、ビルドは期限切れになります。" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "完了日" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "完了者" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "発行者" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "このビルドオーダーを発行したユーザー" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "責任" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "このビルドオーダーを担当するユーザーまたはグループ" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "外部リンク" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "外部 サイト へのリンク" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "組立優先度" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "建設順序の優先順位" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "プロジェクトコード" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "プロジェクトコード" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "製造中の子ビルドがあるため、ビルドオーダーを完了できません" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "不完全な出力があるため、ビルドオーダーを完了できません" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "ビルドの割り当てを完了するタスクのオフロードに失敗しました。" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "ビルドオーダー{build}が完了しました" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "建設発注が完了しました" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "追跡可能な部品については、シリアル番号の提示が必要です。" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "ビルド出力が指定されていません" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "ビルド出力はすでに完了しています" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "ビルド出力がビルド順序と一致しません" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "数量はゼロより大きくなければなりません" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "数量が出力数量を上回ることはできません" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "ビルド出力は、必要なすべてのテストを通過していません" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "ビルド出力 {serial} は、必要なすべてのテストに合格していません。" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "引き当て済みの在庫品は、現在生産中です" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "割り当てられた項目を含むビルド出力の一部のみを完了することはできません" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "使用可能数量({q})を超過" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "ビルドオーダーラインアイテム" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "ビルドオブジェクト" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "ビルドオブジェクト" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "数量" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "注文数量" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "消費された在庫の数量" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "ビルド項目は、ビルド出力を指定する必要があります。" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "選択された在庫品目が部品表に一致しません。" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" -msgstr "" +msgstr "引き当て数はゼロより大きくなければなりません" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "シリアル在庫の場合、数量は1でなければなりません。" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "割当数量({q})は在庫可能数量({a})を超えてはなりません。" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "在庫が過剰配分" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "在庫商品" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "ソース在庫品" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "建設に割り当てる在庫量" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "インストール" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "仕向け地在庫品" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "ビルドレベル" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "部品名" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "ビルド出力" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "ビルド出力が親ビルドと一致しません" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "出力部分が BuildOrder 部分と一致しません。" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "このビルド出力はすでに完了しています" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "このビルド出力は完全に割り当てられていません" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "ビルド出力の数量を入力" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "追跡可能な部品に必要な整数個数" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "部品表には追跡可能な部品が含まれるため、必要な数量は整数" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "シリアル番号" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "ビルド出力のためのシリアル番号の入力" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "ビルド出力のストック位置" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "シリアル番号の自動割り当て" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "シリアル番号が一致する必要なアイテムを自動的に割り当て" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "以下のシリアル番号は既に存在するか、無効です。" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "ビルド出力のリストを提供する必要があります。" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "スクラップされたアウトプットの在庫場所" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "廃棄割り当て" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "廃棄されたアウトプットに割り当てられた在庫の破棄" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "ビルドアウトプットを廃棄する理由" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "完成した建造物のアウトプットの場所" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "不完全割当の受入れ" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "在庫が完全に割り当てられていない場合は、出力を完了します。" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "割当在庫の消費" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "このビルドに割り当て済みのストックを消費します。" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "不完全な出力の削除" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "完了していないビルド出力を削除します。" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "不可" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "このビルド・オーダーで消費されるものとして受け入れます。" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "このビルドオーダーを完了する前に割り当てを解除します。" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "総合在庫" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "製造オーダーに割り当てられた余分な在庫品をどのように処理しますか?" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "一部の在庫品目は全体的に配分されています。" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "未割り当ての受け入れ" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "在庫アイテムがこのビルド・オーダーに完全に割り当てられていないことを受け入れます。" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "必要在庫の配分が完了していません" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "インコンプリートの受け入れ" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "必要な数のビルドアウトプットが完了していないことを受け入れます。" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "必要な構築数量が完了していません" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "ビルド・オーダーには未完成の子ビルド・オーダーがあります。" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "受注生産状態であること" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "ビルド・オーダーの出力が不完全" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "組立ライン" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "ビルド出力" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "ビルド出力は同じビルド" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "ビルドラインアイテム" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.partは、ビルドオーダーと同じパーツを指す必要があります。" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "在庫があること" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "使用可能数量({q})を超過" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "追跡部品の割り当てには、ビルド出力を指定する必要があります。" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "追跡されていない部品の割り当てでは、ビルド出力を指定できません。" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "割り当て項目の提供" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "部品を調達する在庫場所(任意の場所から調達する場合は空白にしてください。)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "場所を除く" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "この選択された場所から在庫商品を除外" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "交換可能ストック" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "複数の拠点にある在庫品を交換可能" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "代替ストック" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "代替部品の割り当て" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "オプション" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "オプションのBOMアイテムをビルドオーダーに割り当てます。" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" -msgstr "" +msgstr "すべてのアイテム" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" -msgstr "" +msgstr "非追跡対象部品" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" -msgstr "" +msgstr "追跡対象部品" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" -msgstr "" +msgstr "項目タイプ" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "自動引き当てを行なう部品種類を選択してください" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "在庫優先度" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "一致する在庫アイテムが消費される優先順位" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "組立明細" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "これらの組立明細に割当を制限します (すべての行を割り当てるには空白のままにしてください)" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "BOMリファレンス" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "BOMパーツID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "部品表 部品名" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" -msgstr "" +msgstr "インストール先" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "ビルド" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "サプライヤー" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "割当数量" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "ビルドリファレンス" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "部品分類名" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "追跡可能" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "継承" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "バリアントを許可" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "BOMアイテム" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "生産中" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "ビルド予定" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "外部在庫" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "在庫状況" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "利用可能な代替ストック" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "在庫状況" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "消費量が割り当て量を超過しています" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "在庫消費に関する任意の注記" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "ビルド項目は正しいビルドオーダーを指す必要があります" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "重複したビルド項目の割り当て" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "ビルドラインは正しいビルドオーダーを指す必要があります" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "重複したビルドラインの割り当て" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "少なくとも1つの項目または行を指示する必要があります" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "処理待ち" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "生産" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "保留中" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "キャンセル済" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "完了" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "ビルドオーダー{build}が完了しました" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "建設発注が完了しました" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "受注生産に必要な在庫" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "ビルドオーダー{build}には追加の在庫が必要となります" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "期限切れ注文" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "ビルドオーダー{bo}は現在期限切れです" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "サムネイルあり" + +#: common/api.py:773 msgid "Is Link" msgstr "リンク" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "ファイル" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "ユーザーにはこれらの添付ファイルを削除する権限がありません。" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "この添付ファイルを編集する権限がありません" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "ユーザーにはこの添付ファイルを削除する権限がありません" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "選択リストがロックされています" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "無効な通貨コード" @@ -1539,15 +1641,20 @@ msgstr "有効な通貨コードはありません" msgid "No plugin" msgstr "プラグインなし" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "タグ" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "プロジェクトコードラベル" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "更新しました" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "最終更新のタイムスタンプ" @@ -1567,794 +1674,844 @@ msgstr "独自のプロジェクトコード" msgid "Project description" msgstr "プロジェクトの説明" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "このプロジェクトを担当するユーザーまたはグループ" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "設定キー" - -#: common/models.py:793 -msgid "Settings value" -msgstr "設定値" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "選択された値は有効なオプションではありません。" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "値はブール値でなければなりません。" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "値は整数値でなければなりません。" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "値は有効な数値でなければなりません。" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "値がバリデーション・チェックに合格しない" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "キー文字列は一意でなければなりません。" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "ユーザー" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "価格破壊数量" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "価格" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "指定数量での単価" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "エンドポイント" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "このウェブフックを受信するエンドポイント" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "このウェブフックの名前" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "有効" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "このプロジェクトコードは有効か?" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "このプロジェクトを担当するユーザーまたはグループ" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "設定キー" + +#: common/models.py:799 +msgid "Settings value" +msgstr "設定値" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "選択された値は有効なオプションではありません。" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "値はブール値でなければなりません。" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "値は整数値でなければなりません。" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "値は有効な数値でなければなりません。" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "値がバリデーション・チェックに合格しない" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "キー文字列は一意でなければなりません。" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "ユーザー" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "価格破壊数量" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "価格" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "指定数量での単価" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "エンドポイント" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "このウェブフックを受信するエンドポイント" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "このウェブフックの名前" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "このウェブフックはアクティブですか" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "トークン" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "アクセス用トークン" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "シークレット" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "HMACの共有秘密" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "メッセージ ID:" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "このメッセージの一意な識別子" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "ホスト" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "このメッセージを受信したホスト" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "ヘッダー" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "このメッセージのヘッダー" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "本文" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "メッセージ本文" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "このメッセージを受信したエンドポイント" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "作業内容" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "このメッセージに関する作業は終わったのですか?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "タイトル" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "リンク" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "公開済み" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "投稿者" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "概要" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "既読" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "このニュースは読まれましたか?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "画像ファイル" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "この画像の対象モデルタイプ" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "この画像の対象モデルID" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "カスタムユニット" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "単位記号は一意でなければなりません。" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "ユニット名は有効な識別子でなければなりません。" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "ユニット名" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "シンボル" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "オプションの単位記号" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "定義" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "ユニットの定義" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "添付ファイル" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "ファイルがありません" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "外部リンクが見つかりません。" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" -msgstr "" +msgstr "名前を変更するファイルがありません" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" -msgstr "" +msgstr "ファイル名は空にできません" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" -msgstr "" +msgstr "不正なファイル名" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" -msgstr "" +msgstr "ファイルの拡張子を変更できません" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" -msgstr "" +msgstr "この名前のファイルはすでに存在します" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" -msgstr "" +msgstr "ファイル名の変更後の保存に失敗しました" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "モデルタイプ" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "画像の対象モデルタイプ" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "添付ファイルを選択" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "サムネイル" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "この添付ファイルのサムネイル画像" + +#: common/models.py:2155 msgid "Comment" msgstr "コメント:" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "添付コメント" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "アップロード日" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "ファイルがアップロードされた日付" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "画像" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "この添付ファイルが有効な画像ファイルである場合、真となります" + +#: common/models.py:2183 msgid "File size" msgstr "ファイルサイズ" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "ファイルサイズ(バイト" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "添付ファイルに指定されたモデルタイプが無効です" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "カスタムステート" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "カスタムステート" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "リファレンス・ステータス・セット" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "このカスタム状態で拡張されたステータスセット" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "論理キー" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "ビジネスロジックでこのカスタムステートに等しいステート論理キー" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "値" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "モデルのデータベースに保存される数値" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "都道府県名" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "ラベル" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "フロントエンドに表示されるラベル" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "色" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "フロントエンドに表示される色" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "モデル" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "この状態が関連するモデル" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "モデルを選択する必要があります" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "キーを選択する必要があります。" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "論理キーを選択する必要があります。" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "キーは論理キーと異なる必要があります。" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "有効な参照ステータスクラスが提供されなければならない" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "キーは、参照ステータスの論理キーとは異なる必要があります。" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "論理キーは、参照ステータスの論理キーに含まれていなければなりません。" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "リファレンス・ステータスの名前とは異なっていなければならない。" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "セレクションリスト" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "セレクション・リスト" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "選択リストの名前" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "選択リストの説明" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "ロック中" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "この選択リストはロックされていますか?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "このセレクションリストは使えますか?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "ソースプラグイン" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "選択リストを提供するプラグイン" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "ソースストリング" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "このリストに使用されているソースを示すオプションの文字列" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "デフォルトエントリー" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "この選択リストのデフォルト項目" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "作成日" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "選択リストが作成された日時" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "最終更新" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "選択リストが最後に更新された日時" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "セレクションリスト入力" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "セレクションリスト" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "このエントリーが属する選択リスト" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "選択リストエントリーの値" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "選択リスト項目のラベル" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "選択リスト項目の説明" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "この選択リストはアクティブですか?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "パラメータテンプレート" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "パラメータテンプレート" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "チェックボックスのパラメータに単位を指定することはできません。" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "チェックボックスパラメータに選択肢を持たせることはできません。" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "選択肢はユニークでなければなりません" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "パラメータ・テンプレート名は一意でなければなりません。" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "このパラメータテンプレートにおける対象モデルタイプ" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "パラメータ名" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "単位" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "このパラメータの物理単位" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "パラメータの説明" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "チェックボックス" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "このパラメータはチェックボックスですか?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "選択肢" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "このパラメータの有効な選択肢(カンマ区切り)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "このパラメータの選択リスト" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "有効" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "このパラメータテンプレートは有効ですか?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "パラメータ" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "パラメータ" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "パラメータ値の選択が無効" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "パラメータに対して無効なモデルタイプが指定されています" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "モデルID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "このパラメータの対象となるモデルのID" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "テンプレート" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "パラメータテンプレート" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "データ" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "パラメータ値" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "備考" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "任意のメモ欄" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "バーコードスキャン" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "バーコードデータ" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "バーコードをスキャンしたユーザー" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "タイムスタンプ" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "バーコードスキャンの日時" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "バーコードを処理したURLエンドポイント" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "コンテキスト" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "バーコードスキャンのコンテキストデータ" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "返答" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "バーコードスキャンによるレスポンスデータ" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "結果" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "バーコードスキャンは成功しましたか?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "エラーが発生しました" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: メールログの削除は保護されています。削除を許可するには、INVENTREE_PROTECT_EMAIL_LOG を False に設定してください。" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "メールメッセージ" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "メールメッセージ" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "発表されました" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "送信" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "失敗" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "配送済み" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "確認済み" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "インバウンド" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "アウトバウンド" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "返信なし" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "配送状況を記録" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "読み取りを記録" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "クリックを記録" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "グローバルID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "このメッセージの識別子(外部システムから提供される場合があります)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "スレッドID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "このメッセージスレッドの識別子(外部システムから提供される場合があります)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "スレッド" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "このメッセージに関連するスレッド" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "優先順位" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "メールのスレッド" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "メールのスレッド" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "キー" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "このスレッドの固有キー(スレッドを識別するために使用されます)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "このスレッドの固有識別子" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "内部を開始しました" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "このスレッドは内部で開始されたものですか?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "スレッドが作成された日時" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "スレッドが最後に更新された日時" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} キャンセル" msgid "A order that is assigned to you was canceled" msgstr "あなたに割り当てられた注文がキャンセルされました。" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "受領品目" @@ -2388,104 +2545,100 @@ msgstr "発注書と照らし合わせて商品を受領" msgid "Items have been received against a return order" msgstr "返品注文に反して商品が届いた場合" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" -msgstr "" +msgstr "この設定を変更する際に確認が必要かどうかの指示" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." -msgstr "" +msgstr "この設定を変更するには、確認が必要です。変更内容をご確認ください。" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "環境変数によって設定が上書きされるかどうかを示します" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "上書き" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "走行中" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "保留タスク" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "スケジュールされたタスク" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "失敗したタスク" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "タスクID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "ユニークなタスクID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "ロック" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "ロック時間" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "タスク名" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "関数" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "機能名" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "引数" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "タスク引数" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "キーワード論争" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "タスクキーワード引数" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "ファイル名" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "モデルタイプ" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "このモデルの添付ファイルを作成または編集する権限がありません。" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "ユーザーは、このモデルのパラメータを作成または編集する権限がありません。" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "選択リストがロックされています" - #: common/setting/system.py:97 msgid "No group" msgstr "グループなし" @@ -2560,19 +2713,19 @@ msgstr "スーパーユーザーにのみ `about` モーダルを表示します #: common/setting/system.py:239 msgid "Show superuser banner" -msgstr "" +msgstr "スーパーユーザーバナーを表示" #: common/setting/system.py:240 msgid "Show a warning banner in the UI when logged in as superuser" -msgstr "" +msgstr "スーパーユーザーとしてログインした際、UIに警告バナーを表示します" #: common/setting/system.py:245 msgid "Show admin banner" -msgstr "" +msgstr "管理者用バナーを表示" #: common/setting/system.py:246 msgid "Show a warning banner in the UI when logged in as admin" -msgstr "" +msgstr "管理者としてログインした際に、UIに警告バナーを表示します" #: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" @@ -2614,13 +2767,13 @@ msgstr "通貨の更新間隔" msgid "How often to update exchange rates (set to zero to disable)" msgstr "為替レートの更新頻度 (ゼロに設定すると無効になります)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "日" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "通貨更新プラグイン" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "アップロードサイズ制限" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "画像およびファイルの最大アップロードサイズ" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "厳格なURLバリデーション" @@ -2760,947 +2921,1017 @@ msgstr "バーコード生成プラグイン" msgid "Plugin to use for internal barcode data generation" msgstr "内部バーコードデータ生成に使用するプラグイン" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "部品のロック" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "変更を防止するためにパーツのロックを有効にする" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "部品改訂" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "パートのリビジョンフィールドを有効にします。" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "アセンブリ改訂のみ" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "組立部品のみ修正可能" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "アセンブリからの削除を許可" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "アセンブリで使用されている部品の削除を許可します。" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN 正規表現" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "部分IPNにマッチする正規表現パターン" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "IPNの重複を許可" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "複数のパートが同じIPNを共有できるようにします。" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "IPNの編集を許可" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "部品編集中にIPN値の変更を許可" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "部品表データのコピー" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "部品複製時にBOMデータをデフォルトでコピー" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "部品パラメータデータのコピー" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "部品複製時にデフォルトでパラメータデータをコピー" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "コピー部品テストデータ" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "部品複製時にテストデータをデフォルトでコピー" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "カテゴリー・パラメーター・テンプレートのコピー" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "部品作成時のカテゴリー・パラメーター・テンプレートのコピー" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "パーツはデフォルトのテンプレートです" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "パーツはデフォルトで他のコンポーネントから組み立てることができます" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "コンポーネント" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "パーツはデフォルトでサブコンポーネントとして使用できます" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "購入可能" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "パーツはデフォルトで購入可能です" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "販売可能" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "パーツはデフォルトで販売可能です" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "パーツはデフォルトで追跡可能です" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "バーチャル" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "パーツはデフォルトでバーチャル" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "関連部品を表示" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "部品の関連部品を表示" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "初期在庫データ" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "新規部品追加時に初期在庫を作成可能" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "サプライヤー初期データ" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "新しい部品を追加する際に、最初のサプライヤーデータを作成できるようにします。" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "部品名表示形式" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "部品名の表示形式" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "パーツカテゴリー デフォルトアイコン" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "パートカテゴリのデフォルトアイコン(空はアイコンがないことを意味します)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "価格の最小桁数" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "価格データのレンダリング時に表示する最小小数点以下の桁数" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "価格の小数点以下の桁数" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "価格データのレンダリング時に表示する小数点以下の桁数の最大値" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "サプライヤー価格の利用" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "全体的な価格計算にサプライヤーの価格破壊を含めること" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "購入履歴の上書き" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "過去の発注価格がサプライヤーの価格変動を上書き" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "ストックアイテム価格を使用" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "手動入力された在庫データから価格計算を行います。" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "在庫商品の価格設定年齢" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "この日数より古い在庫品を価格計算から除外します。" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "バリアント価格を使用" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "全体的な価格計算にバリアント価格を含む" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "アクティブバリアントのみ" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "バリアント価格の計算には、アクティブなバリアントパーツのみを使用します。" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "自動更新の価格設定" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "内部データが変更された際に、部品価格を自動的に更新します。" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "価格の再構築間隔" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "部品価格が自動的に更新されるまでの日数" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "社内価格" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "部品の内部価格の有効化" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "内部価格オーバーライド" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "利用可能な場合、内部価格は価格帯の計算より優先されます。" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" -msgstr "" +msgstr "BOMの数量が0になることを許可" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" -msgstr "" +msgstr "部品のBOMアイテムについて、数量がゼロの場合も許可します。これにより、セットアップ数量を使用して、製造数量とは独立して、1回の製造ごとに必要な数量を定義できるようになります" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "ラベル印刷の有効化" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "ウェブインターフェースからラベル印刷を有効にします。" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "ラベル画像DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "ラベル印刷プラグインに供給する画像ファイルを生成する際のDPI解像度" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "レポートの有効化" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "レポートの作成" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "デバッグモード" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "デバッグモードでのレポート生成(HTML出力)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "レポートURLの取得" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "レポート生成時にリモート URL の取得を許可する" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "ログレポートエラー" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "レポート生成時に発生するエラーのログ" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "ページサイズ" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "PDFレポートのデフォルトのページサイズ" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "パラメータ単位の強制" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "単位が指定されている場合、パラメータ値は指定された単位に一致する必要があります。" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "世界的にユニークな連載" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "在庫品のシリアル番号はグローバルに一意でなければなりません。" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "枯渇在庫の削除" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "ストックアイテムが枯渇した場合のデフォルトの動作を決定します。" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" -msgstr "" +msgstr "シリアル番号の編集を許可" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" -msgstr "" +msgstr "在庫品のシリアル番号の編集を許可します" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" -msgstr "" +msgstr "シリアル化された在庫を削除" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" -msgstr "" +msgstr "シリアル番号が設定されている在庫品の削除を許可します" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "バッチコードテンプレート" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "ストックアイテムのデフォルトバッチコード生成用テンプレート" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "有効期限" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "在庫期限切れ機能の有効化" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "期限切れ株式の売却" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "期限切れ株式の売却を許可" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "在庫切れ時間" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "在庫品が期限切れとみなされるまでの日数" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "賞味期限切れ在庫の処理" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "期限切れの在庫を使用した建物の建築を許可" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "株式所有権" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "ストックロケーションとアイテムの所有権管理" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "在庫場所 デフォルトアイコン" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "在庫場所のデフォルトアイコン(空はアイコンがないことを意味します。)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "インストール済みストックアイテムの表示" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "ストックテーブルにインストールされたストックアイテムを表示" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "アイテム取り付けの際はBOMをチェック" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "親部品のBOMには、インストールされたストックアイテムが存在する必要があります。" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "在庫切れの転送を許可" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "在庫のないストックアイテムをストックロケーション間で移動可能" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "既定で、在庫転送時に既存の在庫とマージする" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "転送動作時の在庫のデフォルト状態(必要に応じて転送ごとに変更できます)" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "ビルド・オーダー参照パターン" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Build Order参照フィールドの生成に必要なパターン" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "責任ある所有者を要求" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "各注文には、責任ある所有者を指定する必要があります。" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "アクティブパートが必要" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "非稼動部品の製造オーダー作成を防止" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "ロックされた部分を要求" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "ロックされていない部品の製造オーダー作成を防止" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "有効なBOMが必要" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "BOMが検証されない限り、製造オーダーが作成されないようにします。" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "クローズド・チャイルド・オーダー" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "すべてのチャイルドオーダーが終了するまで、ビルドオーダーの完了を防止します。" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "外部ビルドオーダー" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "外部ビルドオーダー機能の有効化" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" -msgstr "" +msgstr "外部ビルドオーダーを必須とする" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" -msgstr "" +msgstr "外部サプライヤーから組み立て済み部品を発注する際は、外部ビルドオーダーを指定する必要があります" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "テストがパスするまでブロック" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "必要なテストがすべて合格するまで、ビルド出力が完了しないようにします。" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "返品注文の有効化" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "ユーザーインターフェイスで返品注文機能を有効にします。" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "リターンオーダー参照パターン" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "返品注文参照フィールドの生成に必要なパターン" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "完了した返品注文の編集" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "注文完了後の返品注文の編集が可能" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "販売注文参照パターン" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "販売注文参照フィールドの生成に必要なパターン" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "販売注文のデフォルト出荷" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "販売注文でデフォルト出荷を作成可能" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "完了した販売注文の編集" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "出荷または完了後の販売注文の編集を許可します。" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "出荷には確認が必要です" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "商品が確認されるまで、出荷の完了をお控えください。" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "出荷された注文を完了としてマーク" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "出荷済みと表示された販売注文は、「出荷済み」ステータスを回避して自動的に完了します。" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "在庫移動指示を有効" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "ユーザーインターフェースで在庫移動指示機能を有効にします" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "在庫移動指示コード採番フォーマット" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "在庫移動指示コードを自動採番するために使用するフォーマット(必須項目)" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" -msgstr "" +msgstr "未完了項目のテストのブロック" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" -msgstr "" +msgstr "必要な品目チェックが完了していない場合、販売注文への在庫品目の割り当てを防止します" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "発注書参照パターン" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "発注書参照フィールドの生成に必要なパターン" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "完了した発注書の編集" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "出荷後または完了後の発注書の編集が可能" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "通貨の変換" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "在庫を受け取る際、商品価値を基準通貨に変換" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "自動発注" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "すべての品目を受領した時点で、発注書を完了として自動的にマーク" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "パスワード忘れ" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "ログインページでのパスワード忘れ防止機能の有効化" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "登録の有効化" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "ログインページでユーザーの自己登録を可能にします。" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "SSOの有効化" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "ログインページでSSOを有効化" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "SSO登録の有効化" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "ログインページでSSOによるユーザーの自己登録を可能にします。" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "SSOグループ同期の有効化" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "InvenTreeグループとIdPが提供するグループの同期を有効にします。" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSOグループキー" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "IdP が提供する groups claim 属性の名前。" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "SSOグループマップ" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "SSOグループからローカルのInvenTreeグループへのマッピング。ローカル・グループが存在しない場合は、作成されます。" -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "SSO外のグループを削除" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "ユーザーに割り当てられたグループがIdPによってバックエンドされていない場合に削除するかどうか。この設定を無効にすると、セキュリティ上の問題が発生する可能性があります。" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "メールアドレスは必須です" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "サインアップ時にメールの入力を要求" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "SSOユーザーの自動入力" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "SSOアカウントデータからユーザー詳細を自動入力" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "メール2回" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "サインアップの際、ユーザーに2度メールを尋ねます。" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "パスワード2回" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "サインアップ時にパスワードを2回要求" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "許可ドメイン" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "特定のドメイン(@で始まるカンマ区切り)へのサインアップを制限します。" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "登録時のグループ" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "新規ユーザ登録時に割り当てられるグループ。SSOグループ同期が有効な場合、このグループはIdPからグループを割り当てられない場合にのみ設定されます。" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "MFAの実施" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "ユーザーは多要素セキュリティを使用する必要があります。" -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." -msgstr "" +msgstr "この設定を有効にすると、すべてのユーザーに多要素認証の設定が必須となります。すべてのセッションは直ちに切断されます。" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "起動時にプラグインをチェック" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "起動時にすべてのプラグインがインストールされていることを確認 - コンテナ環境では有効にします。" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "プラグインのアップデートの確認" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "インストールされているプラグインのアップデートを定期的にチェックします。" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "URL統合の有効化" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "プラグインがURLルートを追加できるようにします" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "ナビゲーション統合の有効化" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "プラグインをナビゲーションに統合可能" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "アプリとの統合" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "プラグインを有効にしてアプリを追加" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "スケジュール統合の有効化" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "スケジュールタスクを実行するプラグインの有効化" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "イベント統合の有効化" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "プラグインが内部イベントに応答できるようにします。" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "インターフェース統合の有効化" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "プラグインがユーザー・インターフェースに統合できるようにします。" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "メール連携を有効にする" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "プラグインを有効にして、送信/受信メールを処理できるようにします" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "プロジェクトコードの有効化" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "プロジェクトを追跡するためのプロジェクトコードの有効化" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" -msgstr "" +msgstr "棚卸機能を有効" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "過去の在庫数量および価値を記録する機能を有効にします" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "外部ロケーションを除く" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgstr "外部拠点にある在庫品を棚卸計算から除外します" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "自動引取期間" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" -msgstr "" +msgstr "自動棚卸記録の間隔(日数)" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" -msgstr "" +msgstr "古い棚卸の記録を削除" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +msgstr "指定した日数より古い棚卸し記録を削除します" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" -msgstr "" +msgstr "棚卸しの削除間隔" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" +msgstr "棚卸し記録は、指定された日数が経過すると削除されます" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" -msgstr "" +msgstr "古い在庫追跡記録を削除" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +msgstr "指定した日数より古い在庫追跡記録を削除します" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" -msgstr "" +msgstr "在庫追跡記録の削除間隔" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "" +msgstr "在庫追跡記録は、指定された日数が経過すると削除されます" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "ユーザーのフルネームを表示" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "ユーザー名の代わりにフルネームを表示" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "ユーザープロファイルの表示" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "プロフィールページにユーザーのプロフィールを表示" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" -msgstr "" +msgstr "週の始まり" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" -msgstr "" +msgstr "カレンダー表示における週開始曜日" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" -msgstr "" +msgstr "日曜日" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" -msgstr "" +msgstr "月曜日" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" -msgstr "" +msgstr "火曜日" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" -msgstr "" +msgstr "水曜日" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" -msgstr "" +msgstr "木曜日" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" -msgstr "" +msgstr "金曜日" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" -msgstr "" +msgstr "土曜日" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "カレンダー範囲" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "カレンダービューに表示される将来のヶ月数" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "ヶ月" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "テストステーションデータの有効化" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "テスト結果のテストステーションデータ収集の有効化" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "マシン ping を有効にする" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "登録されたマシンの状態を確認するため、定期的なpingタスクを有効にしてください" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "検索プレビューウィンドウの各セクションに表示する結果の数" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "正規表現検索" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "検索クエリでの正規表現の有効化" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "全単語検索" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "検索クエリは、単語全体が一致した結果を返します。" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "メモの検索" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "検索クエリは、アイテムのノートから一致する結果を返します。" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "エスケープキーでフォームを閉じる" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "モーダルフォームを閉じるには、エスケープキーを使用します。" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "固定ナビバー" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "ナビバーの位置は画面上部に固定されます。" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "固定された表の見出し" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "表の見出しは表の上部に固定されています" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "スポットライトを表示する" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "スポットライトナビゲーション機能を有効にする" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "ナビゲーション・アイコン" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "ナビゲーションバーにアイコンを表示" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "日付フォーマット" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "日付の表示形式" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "在庫履歴を表示する" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "部品詳細ページに在庫履歴情報を表示します" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "最後のパンくずを表示" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "現在のページをパンくずで表示" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "追加モデル情報の表示" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "モデル選択ドロップダウンに追加情報を表示します" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "表に在庫場所をすべて表示します" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "無効時:完全な場所のパスがホバーツールチップとして表示されます。有効時:完全な場所のパスがプレーンテキストとして表示されます。" -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "表内の全カテゴリを表示します" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "無効時:カテゴリの完全なパスがホバー時のツールチップとして表示されます。有効時:カテゴリの完全なパスがプレーンテキストとして表示されます。" -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" -msgstr "" +msgstr "BOMテーブルにサブアセンブリを表示" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" -msgstr "" +msgstr "BOMテーブルでサブアセンブリ表示を有効にします" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "エラー・レポートの受信" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "システムエラーの通知を受信" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "最後の中古印刷機" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "ユーザーの最後に使用した印刷機を保存" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" -msgstr "" +msgstr "最終階層の項目を表示" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" -msgstr "" +msgstr "子要素がない場所やカテゴリについては、サブレベルではなくアイテムやパーツを自動的にデフォルト表示にします" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "全モデル" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "アタッチメント型式なし" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "無効なアタッチメントモデルタイプ" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "ファイルサイズが{max_size} MBのアップロード上限を超えています" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "ファイル名が不正です" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "最小プレースは最大プレースより大きくできません。" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "最大定員が最小定員を下回ることはありません。" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "空のドメインは使用できません。" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "無効なドメイン名: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "値は大文字でなければならない" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "値は有効な変数識別名でなければならない。" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "パートはアクティブ" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "メーカーはアクティブ" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "サプライヤーが活動中" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" -msgstr "" +msgstr "主要サプライヤー部品" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "内部はアクティブ" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "サプライヤーの活動" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "製造元" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "会社名" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "在庫あり" @@ -4123,8 +4387,8 @@ msgstr "連絡先電話番号" msgid "Contact email address" msgstr "連絡先メールアドレス" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "お問い合わせ" @@ -4176,283 +4440,283 @@ msgstr "納税者番号" msgid "Company Tax ID" msgstr "法人税番号" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "住所" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "マイアカウント" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "会社を選択" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "住所" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "アドレスエントリを説明するタイトル" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "主な住所" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "プライマリアドレスに設定" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "1行目" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "丁目、番地、号など" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "2行目" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "建物名、部屋番号など" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "郵便番号" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "都市/地域" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "郵便番号 都市/地域" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "都道府県" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "都道府県" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "国" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "住所国" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "宅配便発送に関する注意事項" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "宅配便発送時の注意事項" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "社内出荷に関する注意事項" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "社内用出荷注意事項" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "住所情報へのリンク(外部)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "メーカー・パーツ" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "ベース部" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "部品を選択" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "メーカー選択" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "メーカー品番" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "外部メーカー部品リンク用URL" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "メーカー部品説明" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "パックユニットは、ベースユニットと互換性がある必要があります。" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "パック単位はゼロより大きくなければなりません。" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "リンクされたメーカー部品は、同じベース部品を参照する必要があります。" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "仕入先" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "サプライヤーを選択" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "サプライヤー在庫管理ユニット" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "このサプライヤーは活動していますか?" -#: company/models.py:792 -msgid "Primary" -msgstr "" - #: company/models.py:793 -msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgid "Primary" +msgstr "プライマリー" -#: company/models.py:803 +#: company/models.py:794 +msgid "Is this the primary supplier part for the linked Part?" +msgstr "これは、リンク先の部品に対する主要サプライヤーの部品でしょうか?" + +#: company/models.py:804 msgid "Select manufacturer part" msgstr "メーカー部品の選択" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "外部サプライヤー部品リンク用URL" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "サプライヤーの部品説明" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "基本料金" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "ミニマムチャージ(例:仕入れ手数料)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "パッケージング" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "部品梱包" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "パック数量" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "1パックに供給される総量。単品の場合は空のままにしてください。" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "複数" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "複数注文" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "サプライヤーから入手可能な数量" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "空席状況更新" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "アベイラビリティ・データの最終更新日" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "サプライヤーの価格破壊" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "このサプライヤーで使用されるデフォルト通貨" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "会社名" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "在庫あり" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "価格割り引き" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" -msgstr "" +msgstr "表示名" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "データのエクスポート中にエラーが発生しました" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "データエクスポートプラグインが不正なデータ形式を返しました" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "エクスポート形式" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "エクスポートファイル形式の選択" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "エクスポートプラグイン" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "エクスポートプラグインを選択" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "この項目の追加ステータス情報" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "カスタムステータスキー" @@ -4476,123 +4740,152 @@ msgstr "設置済" msgid "Invalid status code" msgstr "無効なステータスコード" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "データファイル" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "インポートするデータファイル" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "カラム" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "このインポートセッションのターゲットモデルタイプ" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "インポートの状態" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "フィールドのデフォルト" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "フィールドのオーバーライド" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "フィールドフィルター" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "既存の記録を更新する" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "有効にされた場合、既存のレコードは新しいデータで更新されます" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "一部の必須フィールドがマッピングされていません" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "完了行数の履歴" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "行数の履歴" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "レコードの既存データベース識別子" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "カラムはすでにデータベースのフィールドにマッピングされています。" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "フィールドはすでにデータ列にマッピングされています。" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "カラムマッピングは有効なインポートセッションにリンクされている必要があります。" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "カラムがデータファイルに存在しません。" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "対象モデルにフィールドが存在しない" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "選択されたフィールドは読み取り専用です。" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "ルックアップ列は、関連する(外部キー)列にのみ設定できます" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "無効なルックアップ列。有効なオプション: {options}" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "インポートセッション" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "フィールド" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "列" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "ルックアップ列" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "外部キー参照に使用するデータベースフィールドです。自動参照の場合は空白のままにしてください。" + +#: importer/models.py:674 msgid "Row Index" msgstr "行インデックス" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "元の行データ" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "エラー" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "有効" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "既存の記録を更新するにはIDが必要です。" +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "複数の一致が見つかりました - 値が一意であることを確認するか、特定の参照フィールドを選択してください" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "指定のIDで該当する記録は見つかりませんでした" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "無効なID形式が指定されました" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "既存の記録を更新するにはIDが必要です。" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "サポートされていないデータファイル形式" @@ -4600,43 +4893,47 @@ msgstr "サポートされていないデータファイル形式" msgid "Failed to open data file" msgstr "データファイルを開けませんでした" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "無効なデータファイルの寸法" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "無効なフィールドのデフォルト" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "無効なフィールドのオーバーライド" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "無効なフィールドフィルタ" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "行" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "受け付ける行IDのリスト" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "列はありません" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "行はこのセッションに属していません" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "行に無効なデータが含まれています。" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "列はすでに完成しています" @@ -4672,115 +4969,115 @@ msgstr "データファイルのカラム数が多すぎる" msgid "Data file contains too many rows" msgstr "データファイルの行数が多すぎます。" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "値は有効な辞書オブジェクトでなければなりません。" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "コピー" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "各ラベルの印刷部数" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "接続済み" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "不明" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "印刷" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "警告" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "メディアがありません" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "紙詰まり" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "ネットワーク接続なし" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "エラー" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "ラベルプリンター" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "さまざまなアイテムのラベルを直接印刷できます。" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "プリンタの場所" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "プリンターを特定の場所に設置" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "機械名" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "機種" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "機械の種類" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "ドライバー" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "マシンに使用されるドライバ" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "マシンを無効にすることができます" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "ドライバーあり" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "エラーなし" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "初期化" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "機械の状態" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "機械" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "マシン構成" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "設定タイプ" @@ -4792,7 +5089,7 @@ msgstr "プロパティーキー" msgid "Value of the property" msgstr "プロパティー値" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "グループ" @@ -4816,117 +5113,118 @@ msgstr "最大進捗" msgid "Maximum value for progress type, required if type=progress" msgstr "進行状況タイプの場合の最大値。type=progress の場合に必須です。" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "注文参照" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "並外れた" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "プロジェクトコード" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "作成者" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "作成前" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "の後に作成されました。" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "開始日あり" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "開始日 前" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "開始日 後" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "目標期日あり" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "目標期日" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "以降の目標日" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" -msgstr "" +msgstr "更新日(開始)" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" -msgstr "" +msgstr "更新日(終了)" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "価格" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "完成前" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "終了後" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "外部ビルドオーダー" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "注文" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "注文完了" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "内部パーツ" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "注文保留" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "完了" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "出荷あり" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" -msgstr "" +msgstr "配送が見つかりません" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "注文" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "注文" msgid "Sales Order" msgstr "セールスオーダー" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "リターンオーダー" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "在庫移動指示" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "合計金額" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "この注文の合計金額" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "注文通貨" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "この注文の通貨(会社のデフォルトを使用する場合は空白のままにしてください。)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "この注文はロックされており、変更できません。" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "連絡先が選択した会社と一致しません" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "開始日は目標期日より前でなければなりません。" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "指定の会社と住所が一致しません" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "ご注文内容(任意)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "この注文のプロジェクトコードを選択してください。" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "外部ページへのリンク" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "開始日" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "本注文の開始予定日" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "終了日に達したら" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "お届け予定日この期日を過ぎますと延滞となります。" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "発行日" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "オーダー発行日" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" -msgstr "" +msgstr "更新日" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "この注文を担当するユーザーまたはグループ" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "本注文に関する連絡先" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "本注文の会社住所" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "注文参照" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "ステータス" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "発注状況" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "注文元の会社" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "サプライヤー・リファレンス" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "サプライヤー注文参照コード" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "受信" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "注文完了日" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "目的地" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "入荷商品のお届け先" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "部品サプライヤーは、POサプライヤーと一致する必要があります。" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "品目が発注書と一致しません" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "行項目にリンクされた部品が不足しています" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "数量は正の数でなければなりません。" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" -msgstr "" +msgstr "仮想部品にはシリアル番号を割り当てることはできません" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "任意の在庫を許可 (シリアルまたは非シリアル)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "シリアル在庫のみ" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "非シリアル在庫のみ" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "顧客" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "販売先" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "販売注文状況" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "お客様リファレンス" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "顧客注文参照コード" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "出荷日" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "出荷元" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "ラインアイテムは、この注文に関連付けられていません。" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "以下のシリアル番号に該当するものは見つかりませんでした。" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "以下のシリアル番号はご利用いただけません。" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "注文はすでに完了しています。" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "注文はすでにキャンセルされました" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "未完了の注文にのみ完了マークを付けることができます。" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "出荷に不備があるため、注文を完了できません。" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "割り当てに不備があるため、注文を完了できません。" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "不完全な項目があるため、注文を完了できません。" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "注文はロックされ、変更できません。" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "品目数量" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" -msgstr "" +msgstr "項番" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" -msgstr "" +msgstr "この項目の行番号(任意)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "行項目参照" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "項目" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "この行項目の目標期日(注文の目標期日を使用する場合は空白のままにしてください。)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "行項目の説明(オプション)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "この行の補足説明" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "単価" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "発注書項目" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "サプライヤーの部品はサプライヤーと一致しなければなりません。" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "ビルドオーダーは外部としてマークする必要があります" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "ビルドオーダーはアセンブリ部品にのみリンクできます" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "ビルドオーダーの部品は、ラインアイテムの部品と一致する必要があります。" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" -msgstr "" +msgstr "組立部品には、外部ビルドオーダーが必要です" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "サプライヤー" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "受信" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "受領品目数" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "購入金額" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "購入単価" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "本品目により完成する外部ビルドオーダー" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "発注書追加行" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "販売注文明細" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "販売可能な部品のみを販売オーダーに割り当てることができます。" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "セール価格" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "販売単価" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "発送済み" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "出荷数量" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "販売注文の出荷" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "配送先住所はお客様と一致している必要があります" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "こちらの発送先住所" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "出荷日" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "配達日" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "貨物の引渡日" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "チェック済み" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "この貨物をチェックしたユーザー" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "発送" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "出荷番号" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "追跡番号" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "貨物追跡情報" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "請求書番号" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "関連する請求書の参照番号" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "発送済み" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "出荷品目に割り当てられた在庫がありません" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "出荷は完了前に必ず確認が必要となります" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "セールスオーダー追加ライン" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "販売注文の割り当て" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "在庫アイテムが割り当てられていません" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "在庫品を別部品のラインに割り当てることはできません。" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "部品のないラインに在庫を割り当てることはできません。" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "割当数量が在庫数量を超えることはできません" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "割当数量はゼロより大きくなければなりません" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "シリアル化された在庫品の場合、数量は1でなければなりません。" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "販売注文と出荷が一致しません" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "出荷が販売注文と一致しません" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "ライン" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "販売注文の出荷参照" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "アイテム" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "割り当てるストックアイテムを選択" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "在庫割当数量の入力" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "リターンオーダー参照" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "返品元の会社" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "返品状況" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "返品注文項目" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "在庫品の指定が必要です。" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "返品数量が在庫数量を超える場合" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "返品数量はゼロより大きくなければなりません。" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "シリアル化されたストックアイテムの数量が無効です。" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "お客様から返品する商品を選択" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "受領日" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" -msgstr "" +msgstr "この返品商品が到着した日付" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "転帰" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "この項目の成果" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "この品目の返品または修理に関連する費用" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "リターンオーダー追加ライン" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "注文ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "在庫移動指示コード" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "複製する注文のID" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "在庫移動指示の状態" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "コピーライン" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "移動元品" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "元の注文から行項目をコピー" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "移動先品" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "余分な行をコピー" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "在庫を消費する" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "元の注文から余分な項目をコピー" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "在庫を移動するのではなく、割り当てられた在庫品から移動数量を差し引くことで、それを「消費」します" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "コピーパラメータ" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "移動先が設定されるまで、指示を完了することはできません" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "指示は、完全に割り当てられるまで完了しません" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "在庫移動指示明細" + +#: order/models.py:4027 +msgid "transferred" +msgstr "移動されました" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "移動数" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "在庫移動指示の引き当て" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" msgstr "" -#: order/serializers.py:112 +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "ラインアイテム" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "完成路線" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "重複した注文" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "カスタムステータスキー" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "この注文を複製するためのオプションを指定します。" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "この論理値の注文ステータスをカスタム値に更新" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "無効なオーダーID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "カスタムステータスキーは整数でなければなりません" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "無効なカスタムステータスキーです" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "この注文ステータスには無効なカスタムステータスキーです" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "サプライヤー名" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "ご注文のキャンセルはできません。" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "未完了の行項目で注文を閉じることができます。" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "注文に不備がある場合" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "ご注文は受け付けておりません。" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "自動車価格" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "サプライヤーの部品データに基づいて購入価格を自動計算" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "購入価格通貨" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "アイテムのマージ" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "同じ品目、同じ仕向け地、同じ日付の品目を1つの品目に統合します。" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "内部部品番号" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "内部部品名" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "サプライヤー部品の指定が必要" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "注文書の指定が必要" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "サプライヤーは発注書と一致しなければなりません。" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "発注書はサプライヤーと一致している必要があります。" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "明細" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "受取商品の配送先選択" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "入荷在庫品のバッチコード入力" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "有効期限" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "入荷在庫の有効期限の入力" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "入荷した在庫品のシリアル番号の入力" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "入荷在庫品の包装情報の上書き" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "在庫品の入荷に関する注意事項" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "バーコード" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "スキャンされたバーコード" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "バーコードはすでに使用されています" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "項目は必ずご記入ください。" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "デスティネーション・ロケーションを指定する必要があります。" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "バーコードの値は一意でなければなりません。" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "発送" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "完了した出荷" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" -msgstr "" +msgstr "引き当て済み明細" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "販売価格通貨" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "割当項目" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "出荷の詳細は記載されていません" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "ラインアイテムは、この注文に関連付けられていません。" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "数量は正数でなければなりません。" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" -msgstr "" +msgstr "この在庫品は、必要なすべてのテストに合格していません" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "割り当てるシリアル番号を入力" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "出荷済み" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "この注文には出荷が関連付けられていません" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "以下のシリアル番号に該当するものは見つかりませんでした。" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "部品の供給元となる在庫場所(任意の場所を使用するには空白のままにしてください)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "以下のシリアル番号はご利用いただけません。" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "この場所から在庫アイテムを除外" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "この配送に割り当てます" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "1明細を満たすために複数の場所から在庫を使用することを許可する" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "シリアル在庫" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "シリアル在庫品を自動割当に含めるかどうかを制御します" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "これらの明細行に割り当てを制限します(すべての行を割り当てるには空白のままにしてください)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "明細行はこの注文に属していません" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "返品注文項目" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "ラインアイテムが返品オーダーと一致しません" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "ラインアイテムはすでに受領済み" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "商品の受け取りは、進行中の注文に対してのみ可能です。" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "返品数量" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "ライン価格通貨" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "引き当てが未完了でも指示を許可" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "指示に未完了の引き当てがあります" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "紛失" @@ -5718,1279 +6125,1312 @@ msgstr "紛失" msgid "Returned" msgstr "返品済" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "処理中" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "戻る" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "修理" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "置換" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "返金" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "拒否" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "発行済" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "期限切れ発注書" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "発注書{po}は現在期限切れです" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "期限切れ販売注文" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "セールスオーダー{so}は現在期限切れです。" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "期限切れ返品注文" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "リターンオーダー{ro}は現在期限切れです" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "スター付き" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "星の数で絞り込む" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "深さ" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "カテゴリの深さでフィルタリング" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "最多メンバーレベル" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "トップレベルカテゴリーによるフィルタリング" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "カスケード表示" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "フィルタリング結果にサブカテゴリーを含めることができます。" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "親" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "親カテゴリーによる絞り込み" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "指定したカテゴリの下にあるサブカテゴリを除外します。" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "最大レベル" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "カテゴリツリーの深さを制限する" + +#: part/api.py:442 msgid "Has Results" msgstr "実績あり" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "バリエーション?" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "改訂版" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "改定あり" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "BOM有効" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "カスケードカテゴリ" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "もし該当する場合には、指定されたカテゴリの子カテゴリ内のアイテムを含めてください。" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "数値カテゴリIDまたはリテラル'null'でフィルタリングしてください" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" -msgstr "" +msgstr "アセンブリ部品はアクティブです" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" -msgstr "" +msgstr "アセンブリ部品は追跡可能です" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "組み立て部分はテスト可能" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" -msgstr "" +msgstr "アセンブリ部品はロックされています" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" -msgstr "" +msgstr "コンポーネント部品はアクティブです" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" -msgstr "" +msgstr "コンポーネント部品は追跡可能です" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "コンポーネント部分はテスト可能" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" -msgstr "" +msgstr "コンポーネント部品はアセンブリです" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" -msgstr "" +msgstr "コンポーネント部品は仮想的なものです" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" -msgstr "" +msgstr "引き当て可能在庫あり" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "用途" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "パーツカテゴリ" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "パーツカテゴリ" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "デフォルトの場所" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "このカテゴリの部品のデフォルトの場所" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "構造に関するパターン" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "部品は構造カテゴリーに直接割り当てることはできませんが、子カテゴリーに割り当てることはできます。" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "デフォルトキーワード" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "このカテゴリの部品のデフォルトキーワード" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "アイコン" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "アイコン (オプション)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "いくつかの部品がすでに割り当てられているため、この部品カテゴリを構造化することはできません!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "部品分類パラメータテンプレート" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "初期値" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "パラメータのデフォルト値" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "パーツ" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "ロックされた部品のパラメータは削除できません" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "ロックされた部品のパラメータを変更することはできません" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "この部分はロックされているため削除できません" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "このパートはまだアクティブなので削除できません。" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "この部品はアセンブリで使用されているため、削除できません。" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "パート'{self}'は'{parent}'(再帰的)のBOMでは使用できません。" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "パート'{parent}'は'{self}'のBOMで使用(再帰的)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPNは正規表現パターン{pattern}に一致しなければなりません。" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "パートはそれ自体の改訂にはなりえません" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" -msgstr "" +msgstr "「改訂あり」に設定された部品には、版数の入力が必須です" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "修正が許されるのは組立部品のみ" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "テンプレート部品のリビジョンを作成できません" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "親部品は同じテンプレートを指す必要があります。" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "このシリアル番号の在庫品はすでに存在します" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "パート設定でIPNの重複が許可されていません。" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "重複する部品リビジョンが既に存在します。" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "この名前、IPN、リビジョンを持つ部品は既に存在します。" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "部品を構造部品のカテゴリーに割り当てることはできません!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "部品名" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "テンプレート" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "この部品はテンプレート部品ですか?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "この部品は他の部品の変形ですか?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "変種" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "部品の説明(オプション)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "キーワード" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "検索結果での視認性を向上させる部分キーワード" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "パーツカテゴリ" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "部品のリビジョンまたはバージョン番号" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "リビジョン" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "この部品は他の部品の改訂版ですか?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "改訂版" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "この商品は通常どこに保管されていますか?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "デフォルトの有効期限" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "この部品の在庫品の有効期限(日単位" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "最小在庫" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "最低許容在庫量" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" -msgstr "" +msgstr "最大在庫数" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" -msgstr "" +msgstr "許容最大在庫数" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "この部品の単位" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "この部品は他の部品から作ることができますか?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "この部品を使って他の部品を作ることはできますか?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "このパーツはユニークなアイテムの追跡が可能ですか?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "この部品にテスト結果を記録することはできますか?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "この部品は外部のサプライヤーから購入できますか?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "この部品は顧客に販売できますか?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "この部分はアクティブですか?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "ロックされた部分は編集できません" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "これは、ソフトウェア製品やライセンスなどの仮想部品ですか?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "部品表の検証が完了しました" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "こちらの部品の部品表(BOM)は有効でしょうか?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "BOMチェックサム" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "保存されたBOMのチェックサム" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOMチェック済み" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "BOMチェック日" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "作成ユーザー" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "この部分の責任者" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "複数販売" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "価格計算のキャッシュに使用される通貨" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "最小BOMコスト" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "構成部品の最低コスト" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "最大BOMコスト" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "構成部品の最大コスト" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "最低購入価格" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "過去の最低購入価額" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "最大購入費用" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "過去の最高購入価格" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "最低社内価格" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "社内価格ブレークに基づく最低コスト" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "社内最高価格" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "社内価格ブレークに基づく最大コスト" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "最低供給価格" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "外部サプライヤーからの部品の最低価格" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "サプライヤー最高価格" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "外部サプライヤーからの部品の最高価格" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "最小バリアントコスト" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "バリアントパーツの最小コストの計算" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "最大バリアントコスト" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "バリアント部品の最大コストの計算" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "最低料金" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "最低コストのオーバーライド" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "最大コスト" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "最大コストのオーバーライド" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "総合的な最小コストの計算" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "総合最大コストの計算" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "最低販売価格" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "価格破壊に基づく最低販売価格" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "最高販売価格" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "価格破壊に基づく最高販売価格" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "最低販売価格" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "過去の最低売却価格" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "最大販売価格" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "過去の最高売却価格" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "ストックテイク用部品" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "個数" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "棚卸時の個別在庫数" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "ストックテイク時の在庫可能量" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "日付" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "ストックテイク実施日" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "最低在庫コスト" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "手元在庫の最低見積原価" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "最大在庫コスト" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "手元在庫の最大見積原価" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "パーツセール価格" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "部品試験テンプレート" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "無効なテンプレート名 - 英数字を1文字以上含む必要があります。" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "テストテンプレートは、テスト可能な部分に対してのみ作成できます。" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "同じキーを持つテスト・テンプレートがパートに既に存在します。" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "試験名" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "テストの名前を入力します。" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "テストキー" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "テストの簡易キー" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "試験内容" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "このテストの説明を入力してください。" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "このテストは有効ですか?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "必須" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "このテストは合格するために必要ですか?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "価値が必要" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "このテストは、テスト結果を追加する際に値を必要としますか?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "アタッチメントが必要" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "この試験では、試験結果を追加する際にファイルの添付が必要ですか。" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "このテストで有効な選択肢(カンマ区切り)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" -msgstr "" +msgstr "数量が無効です - 部品に単位が指定されていません" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" -msgstr "" +msgstr "数量は0以上でなければなりません" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOMアイテムは変更できません - アセンブリがロックされています。" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM アイテムは変更できません - バリアントアセンブリがロックされています。" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "親部品を選択" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "サブパート" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "BOMで使用する部品を選択" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" -msgstr "" +msgstr "金額" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" -msgstr "" +msgstr "1つの部品を製造するために消費される副部品の量" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "このBOMアイテムのBOM数量" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "この部品表はオプションです。" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "このBOMアイテムは消耗品です。" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "設定数量" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "ビルドに必要な追加の必要量(セットアップ時の損失を考慮した分)" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "歩留まり損失" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "ビルドにおける推定歩留まり率(0~100%で表されます)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "丸め倍数" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "必要な生産数量を、この値の倍数に切り上げてください。" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "BOMアイテムリファレンス" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "BOMアイテムノート" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "チェックサムi" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "BOMラインのチェックサム" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "検証済み" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "このBOMアイテムは検証済みです" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "継承" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "この BOM アイテムは、バリアントパーツの BOM に継承されます。" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "このBOMアイテムには、バリアントパーツのストックアイテムを使用できます。" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "数量は追跡可能な部品の場合、整数値でなければなりません。" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "サブパーツの指定が必要" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "BOMアイテム代替" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "代用部品はマスター部品と同じにすることはできません。" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "親BOMアイテム" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "代用部品" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "パート #1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "パート #2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "関連部品を選択" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "この関係について" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "部品とそれ自身との間に部品関係を作ることはできません。" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "重複する関係が既に存在します。" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "サブカテゴリを削除" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "このカテゴリに含まれるすべてのサブカテゴリを削除します" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "パーツを削除" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "このカテゴリに含まれるすべてのパーツを削除します" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "親カテゴリ" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "親部品カテゴリー" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "サブカテゴリ" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "結果" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "このテンプレートに対して記録された結果の数" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "この在庫商品の購入通貨" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "ファイルが画像ではありません" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "オリジナルパート" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "複製する元の部品を選択" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "コピー画像" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "元の部分から画像をコピー" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "コピーBOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "元の部品から部品表をコピー" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "元の部品からパラメータデータをコピー" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "コピーノート" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "元のパートからメモをコピー" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "コピーテスト" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "元の部品からテスト用テンプレートをコピーしてください" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "初期在庫量" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "この部品の初期在庫数量を指定します。数量が0の場合、在庫は追加されません。" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "初期在庫場所" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "この部品の初期在庫場所を指定してください。" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "サプライヤーを選択してください。" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "メーカーを選択してください。" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "メーカー品番" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "選択された企業は有効なサプライヤーではありません。" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "選択された会社は有効な製造業者ではありません。" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "このMPNに一致するメーカー部品はすでに存在します。" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "このSKUに一致するサプライヤー部品は既に存在します。" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "カテゴリ名" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "建物" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "現在生産中の当該部品の数量" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "この部品の予定生産数量" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "在庫商品" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "リビジョン" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "総在庫" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "未割当株式" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "バリアントストック" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "重複部分" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "別のパートから初期データをコピー" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "コピー画像" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "元の部分から画像をコピー" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "コピーBOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "元の部品から部品表をコピー" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "コピーノート" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "元のパートからメモをコピー" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "コピーテスト" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "元の部品からテスト用テンプレートをコピーしてください" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "初期在庫" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "初期在庫数で部品を作成" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "サプライヤー情報" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "この部品の初期サプライヤー情報を追加します。" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "コピーカテゴリパラメータ" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "選択したパーツカテゴリーからパラメータテンプレートをコピー" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "既存イメージ" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "既存の部品画像のファイル名" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "画像ファイルが存在しません" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "部品表全体の検証" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "ビルド" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "ビルドオーダーに必要なもの" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "ビルドオーダーに割り当てられました" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "セールスオーダーに必要なもの" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "セールスオーダーに割り当てられました" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" -msgstr "" +msgstr "パートIPN" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" -msgstr "" +msgstr "部品の説明" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" -msgstr "" +msgstr "部品を選択すると、その部品(およびそのバリエーション部品)の棚卸し情報を作成します" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" -msgstr "" +msgstr "カテゴリを選択すると、そのカテゴリ(およびサブカテゴリ)に含まれるすべての部品が表示されます" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" -msgstr "" +msgstr "ロケーションを選択すると、そのロケーション(およびサブロケーション)にあるすべての部品が表示されます" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" -msgstr "" +msgstr "棚卸しデータを登録" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" -msgstr "" +msgstr "選択した部品の棚卸しデータを保存" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" -msgstr "" +msgstr "レポートを生成" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" -msgstr "" +msgstr "選択した部品の棚卸し明細を作成" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "最小価格" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "最低価格の計算値の上書き" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "最低価格通貨" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "最大価格" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "最高価格の計算値を上書き" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "最高価格通貨" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "更新" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "この部品の価格を更新" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "提供された通貨から{default_currency}に変換できませんでした。" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "最低価格は最高価格を超えてはなりません。" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "最高価格は最低価格を下回ってはなりません。" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" -msgstr "" +msgstr "この部品の必要数量(数量単位を含めることができます)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "親アセンブリを選択" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "構成部品の選択" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" -msgstr "" +msgstr "数量の形式が不正です" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "BOMをコピーする部品を選択します。" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "既存データの削除" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "コピー前に既存のBOMアイテムを削除" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "インクルード継承" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "テンプレート化された部品から継承されたBOM項目を含めます。" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "無効な行をスキップ" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "無効な行をスキップするには、このオプションを有効にします。" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "コピー代用部品" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "BOMアイテムの重複時に代替部品をコピー" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "在庫不足通知" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "{part.name}の在庫が設定された最低レベルを下回りました。" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "在庫切れ通知" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "在庫品1点について、有効期限が近づいています。" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "在庫品のうち、{item_count}点の商品がまもなく期限切れとなります。" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "有効期限なし" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "期限切れ {abs(days_diff)} 日前" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "本日が期限となります" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} 日" @@ -7011,7 +7451,7 @@ msgstr "サンプル" msgid "Installed" msgstr "インストール済み" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "プラグインは現在アクティブなので削除できません。" @@ -7023,23 +7463,23 @@ msgstr "アクションが指定されていません" msgid "No matching action found" msgstr "一致するアクションが見つかりませんでした" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "バーコードデータが見つかりません" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "バーコードデータとの一致が確認されました。" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "モデルはサポートされていません" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "モデルインスタンスが見つかりません" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "バーコードが既存のアイテムと一致" @@ -7055,51 +7495,67 @@ msgstr "一致するサプライヤー部品は見つかりませんでした" msgid "Multiple matching supplier parts found" msgstr "一致するサプライヤー部品が複数見つかりました" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "バーコードデータに一致するプラグインは見つかりませんでした" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "適合部品" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "商品はすでに受領済みです。" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "購買オーダーが見つかりました\\r仕入先パーツが一致しません" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "仕入先パーツが見つかりました\\r購買オーダーが一致しません" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "サプライヤーのバーコードに一致するプラグインがない" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "複数の一致する行項目が見つかりました" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "該当する項目が見つかりません" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "販売注文はありません" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "バーコードが既存の在庫品と一致しません" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "在庫品目が行品目と一致しません" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "在庫不足" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "販売注文に割り当てられた在庫品目" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "情報が不足しています" @@ -7108,23 +7564,23 @@ msgstr "情報が不足しています" msgid "Found matching item" msgstr "一致するアイテムが見つかりました" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "サプライヤーの部品が品目と一致しない" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "ライン・アイテムはすでに完了している" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "ライン・アイテムを受け取るために必要な詳細情報" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "受領済み発注書項目" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "ラインアイテムの受信に失敗" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "バーコードのネイティブサポートを提供" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "短いバーコードプレフィックス" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "複数のInvenTreeインスタンスがある環境で便利です。" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "自動ビルド作成" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "アセンブリのビルドオーダーを自動的に作成します" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "バリエーション品目を含める" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "価格計算に部品のバリエーション在庫を含める" +msgid "Include part variant stock in stocktake data" +msgstr "棚卸データにバリアントパーツ在庫を含める" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "在庫ゼロを除外する" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "エクスポートされたデータセットから在庫ゼロのパーツを除外する" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "部品在庫棚卸データ用エクスポーター" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "部品在庫棚卸データ用エクスポーター" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "最小単位コスト" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "最大単位コスト" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "最低総費用" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "最大総費用" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "InvenTree UI 通知" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "統合されたUI通知方法" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree メール通知" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "統合されたメール通知方法" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "メール通知を許可します" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "このユーザーへのメール通知を許可します" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree Slack通知" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "統合されたSlack通知方法" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" -msgstr "" +msgstr "Slackの受信Webhook URL" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "slack チャンネルにメッセージを送信する際に使用する URL。" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "リンクを開く" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "PDFラベルの印刷をネイティブでサポート" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "デバッグモード" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "デバッグモードを有効にする - PDFの代わりに生のHTMLを返します。" @@ -7653,55 +8117,55 @@ msgstr "最終使用" msgid "Options" msgstr "オプション" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "ラベルシートのページサイズ" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "ラベルをスキップ" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "ラベルシートの印刷時に、このラベル数をスキップします。" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "ボーダー" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "各ラベルの周囲に枠線を印刷します。" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "ランドスケープ" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "ラベルシートを横向きに印刷" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "ページ余白" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "ページの周囲の余白(単位:mm)" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree ラベルシート・プリンタ" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "複数のラベルを1枚のシートに配列" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "ラベルがページサイズに対して大きすぎる" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "ラベルは生成されませんでした" @@ -7753,77 +8217,85 @@ msgstr "TMEバーコードのスキャンをサポートします。" msgid "The Supplier which acts as 'TME'" msgstr "「TME」として活動するサプライヤー" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 -#: plugin/serializers.py:275 -msgid "Only superuser accounts can administer plugins" +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "プラグインの管理ができるのは、スーパーユーザーアカウントのみです" + +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "プラグインのインストールが無効" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" -msgstr "" +msgstr "インストール用のパッケージ名またはURLが指定されていません" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" -msgstr "" +msgstr "パッケージ名またはURLに無効な文字が含まれています" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "プラグインのインストールに成功しました" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "{path} にプラグインをインストール" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "プラグインがレジストリに見つかりませんでした" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "プラグインはパッケージ化されていません" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "プラグインパッケージ名が見つかりません" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "スタッフユーザーのみがプラグインを管理できます" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "プラグインのアンインストールが無効" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "プラグインがアクティブなため、アンインストールできません。" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "このプラグインは必須のため、アンインストールすることはできません。" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "このプラグインはサンプルプラグインのため、アンインストールすることはできません。" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "プラグインは組み込みプラグインのため、アンインストールすることはできません。" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "プラグインがインストールされていません" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "プラグインのインストールが見つかりません" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "プラグインのアンインストールに成功" @@ -7841,7 +8313,7 @@ msgstr "プラグインのキー" #: plugin/models.py:55 msgid "Name of the plugin" -msgstr "" +msgstr "プラグイン名" #: plugin/models.py:62 plugin/serializers.py:119 msgid "Package Name" @@ -7871,25 +8343,25 @@ msgstr "必須プラグイン" msgid "Package Plugin" msgstr "パッケージプラグイン" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "プラグイン" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "著者は見つかりませんでした" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "プラグイン'{p}'は現在のInvenTreeバージョン{v}と互換性がありません。" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "プラグインには少なくともバージョン {v} が必要です。" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "プラグインに必要なバージョンは最大で{v}です。" @@ -8068,7 +8540,7 @@ msgstr "設置未確認" #: plugin/serializers.py:152 msgid "Either packagename or URL must be provided" -msgstr "" +msgstr "パッケージ名またはURLのいずれかを指定する必要があります" #: plugin/serializers.py:191 msgid "Full reload" @@ -8114,200 +8586,208 @@ msgstr "設定の削除" msgid "Delete the plugin configuration from the database" msgstr "データベースからプラグイン設定を削除します" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "この設定が設定ファイルによって上書きされているかどうかを示します" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "この設定が適用されるユーザー" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "アイテム" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "プラグインが見つかりません" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "プラグインはラベル印刷をサポートしていません" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "このモデルを表示する権限がありません" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "無効なラベル寸法" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "テンプレートに有効な項目がありません" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "リーガル" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "文字" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "この名前のテンプレートファイルは既に存在します。" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "テンプレート名" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "テンプレート説明" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "リビジョン番号(自動インクリメント)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "プリントのモデルに装着" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "印刷時に、リンクされたモデルインスタンスに対してレポート出力を添付ファイルとして保存" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "ファイル名パターン" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "ファイル名生成パターン" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "テンプレートが有効" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "テンプレートの対象モデルタイプ" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "フィルター" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "テンプレートクエリフィルタ(key=valueペアのカンマ区切りリスト)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "テンプレートファイル" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "PDFレポートのページサイズ" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "レポートを横向きにレンダリング" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "統合" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "選択された項目に対して単一のレポートを生成します" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "テンプレート{self.name}から生成されたレポート" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "テンプレートの構文エラー" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "レポートの表示にエラーが発生しました" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "レポート生成エラー" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "レポート出力の統合エラー" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "幅 [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "ラベル幅(mm単位)" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "高さ [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "ラベルの高さ(mm単位)" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "ラベル印刷エラー" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "スニペット" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "レポートスニペットファイル" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "スニペットファイルの説明" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "資産" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "レポート資産ファイル" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "アセットファイルの説明" #: report/serializers.py:37 msgid "User must be authenticated to save report templates" -msgstr "" +msgstr "レポートテンプレートを保存するには、ユーザーが認証されている必要があります" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "レポートテンプレートの選択" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "レポートに含める項目の主キーのリスト" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "ラベルテンプレートの選択" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "印刷プラグイン" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "ラベル印刷に使用するプラグインを選択します。" @@ -8338,13 +8818,10 @@ msgstr "必要な材料" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "部品画像" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "発行済" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "必須" @@ -8380,8 +8857,8 @@ msgstr "合計" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "シリアル番号" @@ -8405,7 +8882,7 @@ msgstr "在庫品テストレポート" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "設置項目" @@ -8438,810 +8915,922 @@ msgstr "結果なし(必須)" msgid "No result" msgstr "何も結果はありません" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "転送されました" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" -msgstr "" +msgstr "メディアファイルのパスが不正です" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" -msgstr "" +msgstr "静的ファイルのパスが不正です" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" -msgstr "" +msgstr "アセットファイルが見つかりません" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "画像ファイルが見つかりません" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" -msgstr "" +msgstr "画像ファイルが指定されていません" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image タグには Part インスタンスが必要です。" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image タグには Company インスタンスが必要です。" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "場所の深さによる絞り込み" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "トップレベルのロケーションによるフィルタリング" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "フィルタリング結果にサブロケーションを含めることができます。" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "親の位置" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "親の所在地でフィルタリング" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "部品名(大文字・小文字を区別しません)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "パート名に含まれるもの(大文字・小文字を区別しません)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "部品名(正規表現)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "パートIPN(大文字と小文字を区別しません)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "パートIPNに含まれるもの(大文字と小文字は区別されません)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "パートIPN(正規表現)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "最小在庫" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "最大在庫" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "ステータスコード" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "外部ロケーション" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "ビルド・オーダーで消費" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "その他在庫品に装着" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "パートツリー" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "更新前" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "更新後" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "ストックテイク前" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "ストックテイク後" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "棚卸日あり" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "有効期限" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "有効期限" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "期限失効" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "そのアイテムおよびそのすべての子孫を除外するためのStockItemのプライマリキーをご提供ください。" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "カスケードの所在地" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "もし真であれば、指定された場所の子要素に含まれる項目を含めます" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "数値のロケーションID、またはリテラル文字列の「null」でフィルタリングしてください。" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "数量が必要です" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "有効な部品を供給する必要があります。" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "指定されたサプライヤの部品が存在しません。" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "サプライヤー部品にはパックサイズが定義されていますが、use_pack_sizeフラグが設定されていません。" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "追跡不可能な部品については、シリアル番号は提供できません。" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "組み込み済みを含める" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "もし真であれば、指定した在庫アイテムの中に組み込まれている構成部品のテスト結果を含める" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "数値による在庫品IDでの絞り込み" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "ID {id} の在庫品は存在しません" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" -msgstr "" +msgstr "部品のバリエーションを含める" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" -msgstr "" +msgstr "日付(終了)" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" -msgstr "" +msgstr "日付(開始)" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "在庫ロケーションタイプ" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "ストックロケーションの種類" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "アイコンが設定されていないすべての場所のデフォルトアイコン (オプション)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "ストックロケーション" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "在庫場所" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "所有者" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "所有者を選択" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "ストックアイテムは、構造的なストックロケーションに直接配置されることはありませんが、子ロケーションに配置されることはあります。" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "外部" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "これは外部の在庫場所です。" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "ロケーションタイプ" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "このロケーションのロケーションタイプ" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "いくつかのストックアイテムがすでにストックロケーションに配置されているため、このストックロケーションを構造化することはできません!" -#: stock/models.py:537 -msgid "Serialized stock items cannot be deleted" -msgstr "" +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "先入先出(FIFO)" -#: stock/models.py:674 +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "後入先出(LIFO)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "少ない順" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "多い順" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "有効期限順" + +#: stock/models.py:582 +msgid "Serialized stock items cannot be deleted" +msgstr "シリアル番号管理対象の在庫品は削除できません" + +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field}は存在しません" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "部品の指定が必要" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "在庫品は、構造的な在庫場所に配置することはできません!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "シリアル番号の編集はできません。この商品にはすでにシリアル番号が割り当てられています" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "仮想部品にストックアイテムを作成できません" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "パートタイプ('{self.supplier_part.part}')は{self.part}でなければなりません。" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "シリアル番号のある商品は数量が1でなければなりません。" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "数量が1以上の場合、シリアル番号は設定できません。" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "アイテムはそれ自身に属することはできません" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "is_building=Trueの場合、アイテムはビルド・リファレンスを持っていなければならない。" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "ビルド参照が同じ部品オブジェクトを指していません。" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "親株式" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "ベース部" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "この在庫品に一致するサプライヤー部品を選択してください" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "この在庫品はどこにありますか?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "この在庫品は以下の梱包で保管されています。" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "設置場所" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "このアイテムは他のアイテムにインストールされていますか?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "この商品のシリアル番号" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "このストックアイテムのバッチコード" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "在庫数" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "ソースビルド" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "このストックアイテムのビルド" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "消費者" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "このストックアイテムを消費したビルドオーダー" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "発注元" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "この在庫商品の購入注文" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "販売先オーダー" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "在庫品の有効期限。この日を過ぎると在庫は期限切れとなります。" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "この在庫アイテムが作成された日" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "枯渇時に削除" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "在庫がなくなったら、このストックアイテムを削除します。" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "購入時の単品購入価格" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "パートに変換" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "数量が在庫数を超えています" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "構造上ロケーションに在庫を割り当てることはできません" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "部品が追跡可能に設定されていません" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "数量は整数でなければなりません。" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "数量は在庫数 ({self.quantity}) を超えてはなりません。" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "シリアル番号はリストとして提供されなければなりません" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "数量がシリアル番号と一致しません" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "構造上ロケーションに在庫を割り当てることはできません" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "テストテンプレートが存在しません" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "在庫商品が販売注文に割り当てられました" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "ストックアイテムが他のアイテムに装着されている場合" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "在庫商品には他の商品が含まれています。" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "在庫商品が顧客に割り当てられました" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "在庫品は現在生産中です。" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "連番在庫の統合はできません" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "在庫品の重複" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "在庫品目は同じ部品を参照してください。" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "在庫品は同じサプライヤーの部品を参照する必要があります。" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "在庫状況コードが一致していること" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "在庫がないため移動できません。" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "ストックアイテムのトラッキング" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "記入上の注意" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "在庫品テスト結果" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "このテストには値を指定する必要があります。" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "このテストには添付ファイルをアップロードする必要があります。" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "このテストでは無効な値です。" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "試験結果" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "テスト出力値" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "試験結果添付" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "テストノート" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "テストステーション" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "試験が実施された試験ステーションの識別子。" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "開始" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "テスト開始のタイムスタンプ" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "修了済み" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "テスト終了のタイムスタンプ" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "生成バッチコード" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "製造順序の選択" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "バッチコードを生成するストックアイテムを選択します。" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "バッチコードを生成する場所を選択します。" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "バッチコードを生成する部品を選択します。" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "注文書の選択" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "バッチコードの数量を入力してください。" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "生成されたシリアル番号" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "シリアル番号を生成する部品を選択します。" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "生成するシリアル番号の数" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "この結果のテストテンプレート" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "この部品に該当するテストが見つかりませんでした" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "テンプレートIDまたはテスト名が必要です。" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "試験終了時刻を試験開始時刻より早くすることはできません。" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "親アイテム" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "親株式" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "数量はパック数です。" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "パッケージサイズを使用" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "新しい商品のシリアル番号の入力" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "サプライヤー品番" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "期限切れ" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "子供用品" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "追跡項目" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "この在庫品の購入価格、単位またはパックあたり" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "シリアル化するストックアイテムの数を入力" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "在庫品目がしていされていません" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "数量は在庫数 ({q}) を超えてはなりません。" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "仕向け地" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "この部品にシリアル番号を割り当てることはできません" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "シリアル番号が既に存在します" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "インストールするストックアイテムを選択" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "設置数量" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "インストールするアイテムの数量を入力してください。" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "取引メモの追加(オプション)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "設置数量は1台以上" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "在庫がありません" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "選択した部品が部品表にない" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "設置する数量は、利用可能な数量を超えてはなりません。" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "アンインストール先の場所" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "在庫品を変換する部品を選択" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "選択された部分は、変換のための有効なオプションではありません。" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "SupplierPartが割り当てられている在庫品を変換できません。" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "在庫商品ステータスコード" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "在庫品を変換する部品を選択" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "選択された部分は、変換のための有効なオプションではありません。" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "SupplierPartが割り当てられている在庫品を変換できません。" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "ステータスを変更するストックアイテムを選択" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "ストックアイテムが選択されていません" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "サブロケーション" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "在庫品を削除" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "このロケーションにあるすべての在庫品を削除します" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "サブロケーションを削除" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "このロケーションに含まれるすべてのサブロケーションを削除します" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "親株式所在地" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "パーツは販売可能でなければなりません" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "商品が販売オーダーに割り当てられています。" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "部品がが在庫移動指示にに引き当てられました" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "アイテムがビルドオーダーに割り当てられています。" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "在庫アイテムを割り当てるお客様" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "選択された企業は顧客ではありません" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "株式譲渡に関する注意事項" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "在庫品のリストが必要です。" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "株式併合に関する注意事項" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "不一致のサプライヤーを許可" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "異なるサプライヤの部品を持つ在庫品目をマージできるようにします。" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "不一致の状態を許可" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "異なるステータスコードを持つストックアイテムをマージすることができます。" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "少なくとも2つのストックアイテムを提供する必要があります。" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "変化なし" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "StockItem 主キー値" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "在庫がありません" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "在庫品目は既に在庫にあります" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "数量は負の数であってはなりません。" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "株式取引に関する注記" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "既存の在庫に統合します" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "可能な場合、このアイテムを宛先の既存の在庫にマージします" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "株式取引に関する注記" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "計数したアイテムの在庫場所を設定します(オプション)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "可能なら、返品された商品を既存の在庫商品に統合してください" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "次のシリアル番号" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "以前のシリアル番号" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "商品在庫をマージしました" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "バリアントに変換" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "組立注文の出力が作成されました" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "組立注文の出力が完了しました" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "ビルドオーダーの出力が拒否されました" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "ビルド・オーダーで消費" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "販売注文に対して出荷" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "発注書との照合" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "リターンオーダーに反して返品" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "顧客に送信されました" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "顧客からの返品" @@ -9527,19 +10124,19 @@ msgstr "ユーザー" msgid "Select which users are assigned to this group" msgstr "このグループに割り当てるユーザーを選択します" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "個人情報" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "許可" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "重要な日付" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "トークンは失効しました" @@ -9547,279 +10144,283 @@ msgstr "トークンは失効しました" msgid "Token has expired" msgstr "トークンの有効期限が切れました" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "APIトークン" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "APIトークン" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "トークン名" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "カスタムトークン名" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "トークンの有効期限" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "最終表示" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "トークンが最後に使用された時間" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "失効" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "パーミッション設定" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "表示" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "項目を表示する権限" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "追加" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "項目を追加する権限" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "変更" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "項目を編集する権限" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "削除" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "項目を削除する権限" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "ボット" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "内部" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "ゲスト" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "言語" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "ユーザーの希望言語" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "テーマ" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "JSONとしてのウェブUI用の設定 - 手動で編集しないでください!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "ウィジェット" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "JSONとしてのダッシュボード・ウィジェットの設定 - 手動で編集しないでください!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "表示名" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "ユーザーの表示名選択" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "位置" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "主な役職名" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "ユーザーのステータスメッセージ" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "ユーザーの位置情報" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "ユーザーが積極的にシステムを利用" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "希望の連絡先" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "ユーザータイプ" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "どのようなユーザーですか?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "組織" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "ユーザーの主な所属組織" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "プライマリーグループ" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "ユーザーのプライマリグループ" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "管理者" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" -msgstr "" +msgstr "部品表" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "購入注文" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "セールスオーダー" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "返品注文" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "在庫移動指示" + +#: users/serializers.py:196 msgid "Username" msgstr "ユーザー名" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "名" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "ユーザーの名" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "姓" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "ユーザーの姓" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "ユーザーのメールアドレス" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" -msgstr "" +msgstr "ユーザーは認証されている必要があります" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" -msgstr "" +msgstr "他のユーザー用トークンを作成できるのは、スーパーユーザーのみです" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" -msgstr "" +msgstr "管理者" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" -msgstr "" +msgstr "このユーザーには管理者権限がありますか" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "スーパーユーザー" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "このユーザーはスーパーユーザーですか?" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "このユーザーアカウントはアクティブですか" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "このフィールドを調整できるのはスーパーユーザーのみです。" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "パスワード" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "ユーザーのパスワード" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "警告を上書きします" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "パスワードルールに関する警告を無効にする" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" -msgstr "" +msgstr "スタッフ" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" -msgstr "" +msgstr "このユーザーにはスタッフ権限がありますか?" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "ユーザーを作成する権限がありません" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "アカウントが作成されました" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "パスワードリセット機能を使ってログインしてください" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "InvenTreeへようこそ" diff --git a/src/backend/InvenTree/locale/ko/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/ko/LC_MESSAGES/django.po index f7ea0862a1..40e30fcf16 100644 --- a/src/backend/InvenTree/locale/ko/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/ko/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Korean\n" "Language: ko_KR\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API 엔드포인트를 찾을 수 없습니다" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "일괄 작업을 위해 항목 목록을 제공해야 합니다" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "항목은 목록 형태로 제공되어야 합니다" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "잘못된 항목 목록이 제공되었습니다" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "all 필터는 true와 함께만 사용할 수 있습니다" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "제공된 조건과 일치하는 항목이 없습니다" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "데이터가 제공되지 않았습니다" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "이 필드는 고유해야 합니다." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "이 모델을 볼 수 있는 권한이 없습니다." @@ -65,150 +69,155 @@ msgstr "이메일 주소 확인" msgid "You must type the same email each time." msgstr "매번 동일한 이메일을 입력해야 합니다." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "제공된 기본 이메일 주소가 유효하지 않습니다." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "제공된 이메일 도메인이 승인되지 않았습니다." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "잘못된 단위가 제공되었습니다 ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "값이 제공되지 않았습니다" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "{original}을(를) {unit}(으)로 변환할 수 없습니다" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "잘못된 수량이 제공되었습니다" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "오류 상세 내용은 관리자 패널에서 확인할 수 있습니다" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "날짜 입력" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "잘못된 소수 값" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "메모" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "값 '{name}'이(가) 패턴 형식에 없습니다" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "제공된 값이 요구되는 패턴과 일치하지 않습니다: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "한 번에 1000개를 초과하여 직렬화할 수 없습니다" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "시리얼 번호 문자열이 비어 있습니다" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "중복된 시리얼" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "잘못된 그룹: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "그룹 범위 {group}이(가) 허용된 수량({expected_quantity})을 초과합니다" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "시리얼 번호를 찾을 수 없습니다" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "고유 시리얼 번호 개수({n})는 수량({q})과 일치해야 합니다" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "이 값에서 HTML 태그를 제거하세요" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "데이터에 금지된 마크다운 내용이 포함되어 있습니다" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "잘못된 URL: 호스트명이 없습니다" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "잘못된 URL: 호스트명을 확인할 수 없습니다" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "URL이 사설 또는 예약된 IP 주소를 가리킵니다" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "리디렉션이 너무 많습니다" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "연결 오류" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "서버가 잘못된 상태 코드를 반환했습니다" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "예외가 발생했습니다" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "서버가 잘못된 Content-Length 값을 반환했습니다" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "이미지 크기가 너무 큽니다!" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "이미지 다운로드가 최대 크기를 초과했습니다" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "원격 서버가 빈 응답을 반환했습니다" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "제공된 URL은 유효한 이미지 파일이 아닙니다" @@ -216,159 +225,203 @@ msgstr "제공된 URL은 유효한 이미지 파일이 아닙니다" msgid "Log in to the app" msgstr "앱에 로그인" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "이메일" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "CSRF 검증에 실패했습니다. INVENTREE_SITE_URL 및 INVENTREE_TRUSTED_ORIGINS가 올바르게 설정되었는지 확인하세요." + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "다른 작업을 하기 전에 먼저 2단계 인증을 활성화해야 합니다." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "플러그인 유효성 검사 실행 중 오류가 발생했습니다" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "메타데이터는 파이썬 dict 객체여야 합니다" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "플러그인 메타데이터" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "외부 플러그인에서 사용하는 JSON 메타데이터 필드" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "패턴 형식이 올바르지 않습니다" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "알 수 없는 형식 키가 지정되었습니다" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "필수 형식 키가 누락되었습니다" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "참조(Reference) 필드는 비워둘 수 없습니다" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "참조(Reference)는 요구되는 패턴과 일치해야 합니다" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "참조 번호가 너무 큽니다" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "잘못된 선택입니다" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "이름" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "설명" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "설명 (선택 사항)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "경로" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "같은 상위 항목 아래에는 중복된 이름이 있을 수 없습니다" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "마크다운 메모 (선택 사항)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "바코드 데이터" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "서드파티 바코드 데이터" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "바코드 해시" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "바코드 데이터의 고유 해시" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "기존 바코드를 찾았습니다" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "서버 오류" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "서버에 오류가 기록되었습니다." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "이미지" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "유효한 숫자여야 합니다" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "통화" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "사용 가능한 옵션에서 통화를 선택하세요" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "이 필드는 null일 수 없습니다." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "유효하지 않은 값" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "콘텐츠 타입 형식이 올바르지 않습니다" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "콘텐츠 타입을 찾을 수 없습니다" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "콘텐츠 타입이 필요한 믹스인 클래스와 일치하지 않습니다" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "매개변수 복사" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "원본 항목에서 매개변수 복사" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "라인 복사" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "원본 주문에서 라인 항목을 복사" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "추가 라인 복사" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "원본 주문에서 추가 라인 항목을 복사" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "복제 옵션" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "이 항목 복제를 위한 옵션 지정" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "원본" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "복제할 인스턴스 선택" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "아랍어" @@ -521,46 +574,48 @@ msgstr "중국어 (간체)" msgid "Chinese (Traditional)" msgstr "중국어 (번체)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "업데이트 사용 가능" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "InvenTree 업데이트가 있습니다" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "잘못된 물리 단위" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "유효한 통화 코드가 아닙니다" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "주문 상태" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "직상위 빌드" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "변형(Variant) 포함" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "변형(Variant) 포함" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "변형(Variant) 포함" msgid "Part" msgstr "부품" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "분류" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "상위 계층 빌드" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "나에게 할당 됨" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "할당 대상" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "생성일 이전" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "생성일 이후" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "시작일 있음" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "시작일 이전" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "시작일 이후" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "목표일 있음" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "목표일 이전" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "목표일 이후" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "완료일 이전" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "완료일 이후" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "최소 날짜" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "최대 날짜" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "트리 제외" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "빌드를 삭제하려면 먼저 취소해야 합니다" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "소모품" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "선택사항" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "조립품" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "추적됨" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "테스트 가능" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "미결 주문" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "할당됨" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "소모됨" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "사용 가능" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "주문 중" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "빌드를 찾을 수 없습니다" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "작업 지시서" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "위치" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "산출물" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "산출물 재고 항목 ID로 필터링합니다. 설치되지 않은 빌드 항목을 찾으려면 'null'을 사용하세요." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "작업 지시서" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "조립품 BOM이 검증되지 않았습니다" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "비활성 부품에 대해서는 작업 지시서를 생성할 수 없습니다" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "잠금 해제된 부품에 대해서는 작업 지시서를 생성할 수 없습니다" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "외부 이행은 구매 가능한 부품에 대해서만 가능합니다" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "담당 사용자 또는 그룹을 지정해야 합니다" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "작업 지시서 부품은 변경할 수 없습니다" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "목표일은 시작일 이후여야 합니다" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "작업 지시서 참조번호" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "참조" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "빌드에 대한 간단한 설명 (선택 사항)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "이 빌드가 할당된 작업 지시서" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "빌드할 부품을 선택하세요" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "판매 주문 참조" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "이 빌드가 할당된 판매 주문" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "원본 위치" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "이 빌드에 사용할 재고를 가져올 위치를 선택하세요 (비워두면 어떤 재고 위치에서든 가져옵니다)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "외주 생산" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "이 작업 지시서는 외주로 생산됩니다" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "대상 위치" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "완료된 항목이 보관될 위치를 선택하세요" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "빌드 수량" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "빌드할 재고 항목 수" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "완료된 항목" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "완료된 재고 항목 수" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "빌드 상태" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "빌드 상태 코드" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "배치 코드" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "이 빌드 산출물의 배치 코드" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "생성일" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "빌드 시작일" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "이 작업 지시서의 예정 시작일" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "목표 완료일" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "빌드 완료 목표일. 이 날짜 이후에는 빌드가 지연으로 처리됩니다." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "완료일" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "완료자" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "발행자" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "이 작업 지시서를 발행한 사용자" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "담당" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "이 작업 지시서를 담당하는 사용자 또는 그룹" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "외부 링크" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "외부 URL로 연결" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "빌드 우선순위" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "이 빌드 주문의 우선순위" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "프로젝트 코드" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "이 빌드 주문의 프로젝트 코드" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "진행 중인 하위 빌드가 있는 상태에서는 작업 지시서를 완료할 수 없습니다" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "미완료 산출물이 있는 상태에서는 작업 지시서를 완료할 수 없습니다" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "빌드 자재 할당 완료 처리를 위한 작업 실행에 실패했습니다" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "작업 지시서 {build}이(가) 완료되었습니다" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "작업 지시서가 완료되었습니다" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "추적 가능한 부품에는 시리얼 번호를 제공해야 합니다" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "생산 완제품이 지정되지 않았습니다" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "생산 완제품이 이미 완료되었습니다" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "생산 완제품이 작업 지시서와 일치하지 않습니다" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "수량은 0보다 커야 합니다" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "수량은 산출물 수량보다 클 수 없습니다" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "생산 완제품이 모든 필수 테스트를 통과하지 못했습니다" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "생산 완제품 {serial}이(가) 모든 필수 테스트를 통과하지 못했습니다" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "할당된 재고 항목이 아직 생산 중입니다" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "할당된 항목이 있는 빌드 산출물은 부분 완료할 수 없습니다" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "사용 가능한 수량({q})을 초과했습니다" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "소요 자재 품목" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "빌드 객체" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "빌드 객체" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "수량" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "작업 지시서에 필요한 수량" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "소모된 재고 수량" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "마스터 부품이 추적 가능으로 표시되어 있으므로, 빌드 항목은 생산 완제품을 지정해야 합니다" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "선택한 재고 항목이 BOM 라인과 일치하지 않습니다" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "할당 수량은 0보다 커야 합니다" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "시리얼이 있는 재고의 수량은 1이어야 합니다" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "할당 수량({q})은 사용 가능한 재고 수량({a})을 초과할 수 없습니다" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "재고 항목이 과다 할당되었습니다" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "재고 항목" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "원본 재고 항목" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "빌드에 할당할 재고 수량" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "설치 대상" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "대상 재고 항목" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "빌드 레벨" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "부품명" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "빌드 산출물" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "빌드 산출물이 상위 빌드와 일치하지 않습니다" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "산출물 부품이 빌드 주문 부품과 일치하지 않습니다" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "이 빌드 산출물은 이미 완료되었습니다" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "이 빌드 산출물은 완전히 할당되지 않았습니다" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "빌드 산출물 수량을 입력하세요" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "추적 가능한 부품에는 정수 수량이 필요합니다" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "BOM에 추적 가능한 부품이 포함되어 있으므로 정수 수량이 필요합니다" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "시리얼 번호 (일련번호)" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "빌드 산출물의 시리얼 번호를 입력하세요" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "빌드 산출물의 재고 위치" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "시리얼 번호 자동 할당" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "일치하는 시리얼 번호로 필요한 항목을 자동으로 할당합니다" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "다음 시리얼 번호는 이미 존재하거나 유효하지 않습니다" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "빌드 산출물 목록을 제공해야 합니다" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "폐기된 산출물의 재고 위치" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "할당 폐기" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "폐기된 산출물에 대한 모든 재고 할당을 폐기합니다" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "빌드 산출물 폐기 사유" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "완료된 빌드 산출물의 위치" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "구조적 위치에는 재고 항목을 할당할 수 없습니다" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "불완전한 할당 허용" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "재고가 완전히 할당되지 않았더라도 산출물을 완료합니다" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "할당된 재고 소모" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "이 빌드에 이미 할당된 모든 재고를 소모합니다" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "미완료 산출물 제거" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "완료되지 않은 모든 빌드 산출물을 삭제합니다" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "허용되지 않음" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "이 빌드 주문에 의해 소모된 것으로 수락" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "이 빌드 주문을 완료하기 전에 할당을 해제하세요" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "과다 할당된 재고" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "빌드 주문에 추가로 할당된 재고 항목을 어떻게 처리하시겠습니까" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "일부 재고 항목이 과다 할당되었습니다" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "미할당 수락" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "재고 항목이 이 빌드 주문에 완전히 할당되지 않았음을 수락합니다" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "필요한 재고가 완전히 할당되지 않았습니다" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "불완전 수락" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "필요한 개수의 빌드 산출물이 완료되지 않았음을 수락합니다" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "필요한 빌드 수량이 완료되지 않았습니다" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "작업 지시서에 진행 중인 하위 작업 지시서가 있습니다" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "작업 지시서는 생산 상태여야 합니다" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "작업 지시서에 미완료 산출물이 있습니다" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "빌드 라인" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "생산 완제품" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "생산 완제품은 동일한 빌드를 가리켜야 합니다" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "빌드 라인 항목" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part는 빌드 주문과 동일한 부품을 가리켜야 합니다" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "항목은 재고에 있어야 합니다" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "사용 가능한 수량({q})을 초과했습니다" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "추적 부품을 할당하려면 생산 완제품을 지정해야 합니다" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "비추적 부품 할당에는 생산 완제품을 지정할 수 없습니다" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "할당 항목을 제공해야 합니다" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "부품을 공급할 재고 위치 (비워두면 어떤 위치에서든 가져옵니다)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "위치 제외" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "선택한 위치의 재고 항목을 제외합니다" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "상호 대체 가능한 재고" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "여러 위치에 있는 재고 품목을 서로 대체하여 사용할 수 있습니다" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "대체 재고" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "대체 부품 할당을 허용합니다" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "선택 항목" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "빌드 주문에 선택 BOM 항목을 할당합니다" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "모든 항목" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "비추적 항목" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "추적 항목" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "항목 유형" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "자동 할당할 항목 유형을 선택하세요" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "재고 우선순위" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "일치하는 재고 항목을 소비하는 우선 순서" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "빌드 라인" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "할당을 이 빌드 라인으로 제한(모든 라인에 할당하려면 비워둠)" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "BOM 참조" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "BOM 부품 ID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "BOM 부품명" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "설치 대상" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "빌드" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "공급업체 부품" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "할당 수량" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "빌드 참조" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "부품 카테고리 이름" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "추적 가능" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "상속됨" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "변형(Variant) 허용" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "BOM 항목" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "생산 중" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "빌드 예정" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "외부 재고" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "사용 가능 재고" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "사용 가능 대체 재고" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "사용 가능 변형(Variant) 재고" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "소모 수량이 할당 수량을 초과합니다" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "재고 소모에 대한 선택 메모" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "빌드 항목은 올바른 빌드 주문을 가리켜야 합니다" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "빌드 항목 할당이 중복되었습니다" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "빌드 라인은 올바른 빌드 주문을 가리켜야 합니다" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "빌드 라인 할당이 중복되었습니다" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "최소 하나의 항목 또는 라인을 제공해야 합니다" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "대기 중" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "생산" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "보류" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "취소됨" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "완료" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "작업 지시서 {build}이(가) 완료되었습니다" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "작업 지시서가 완료되었습니다" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "빌드 주문에 재고가 필요합니다" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "빌드 주문 {build}에 추가 재고가 필요합니다" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "기한 초과 빌드 주문" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "빌드 주문 {bo}이(가) 기한을 초과했습니다" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "썸네일 있음" + +#: common/api.py:773 msgid "Is Link" msgstr "링크 여부" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "파일 여부" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "사용자에게 이 첨부파일들을 삭제할 권한이 없습니다" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "사용자에게 이 첨부 파일을 수정할 권한이 없습니다" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "사용자에게 이 첨부파일을 삭제할 권한이 없습니다" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "선택 목록이 잠겨 있습니다" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "유효하지 않은 통화 코드" @@ -1539,15 +1641,20 @@ msgstr "유효한 통화 코드가 제공되지 않았습니다" msgid "No plugin" msgstr "플러그인 없음" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "태그" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "프로젝트 코드 라벨" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "업데이트됨" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "마지막 업데이트 타임스탬프" @@ -1567,794 +1674,844 @@ msgstr "고유 프로젝트 코드" msgid "Project description" msgstr "프로젝트 설명" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "이 프로젝트의 담당 사용자 또는 그룹" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "설정 키" - -#: common/models.py:793 -msgid "Settings value" -msgstr "설정 값" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "선택한 값이 유효한 옵션이 아닙니다" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "값은 불리언(Boolean)이어야 합니다" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "값은 정수여야 합니다" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "값은 유효한 숫자여야 합니다" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "값이 유효성 검사 기준을 통과하지 못했습니다" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "키 문자열은 고유해야 합니다" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "사용자" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "가격 구간 수량" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "가격" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "지정 수량에서의 단가" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "엔드포인트" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "이 웹훅을 수신하는 엔드포인트" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "이 웹훅의 이름" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "활성" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "이 프로젝트 코드가 활성 상태입니까?" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "이 프로젝트의 담당 사용자 또는 그룹" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "설정 키" + +#: common/models.py:799 +msgid "Settings value" +msgstr "설정 값" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "선택한 값이 유효한 옵션이 아닙니다" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "값은 불리언(Boolean)이어야 합니다" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "값은 정수여야 합니다" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "값은 유효한 숫자여야 합니다" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "값이 유효성 검사 기준을 통과하지 못했습니다" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "키 문자열은 고유해야 합니다" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "사용자" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "가격 구간 수량" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "가격" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "지정 수량에서의 단가" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "엔드포인트" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "이 웹훅을 수신하는 엔드포인트" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "이 웹훅의 이름" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "이 웹훅이 활성 상태인가요" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "토큰" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "접근용 토큰" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "시크릿" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "HMAC용 공유 시크릿" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "메시지 ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "이 메시지의 고유 식별자" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "호스트" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "이 메시지를 수신한 호스트" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "헤더" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "이 메시지의 헤더" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "본문" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "이 메시지의 본문" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "이 메시지를 수신한 엔드포인트" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "처리됨" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "이 메시지 처리가 완료되었나요?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "ID" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "제목" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "링크" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "게시됨" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "작성자" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "요약" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "읽음" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "이 뉴스 항목을 읽었나요?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "이미지 파일" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "이 이미지의 대상 모델 유형" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "이 이미지의 대상 모델 ID" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "사용자 정의 단위" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "단위 기호는 고유해야 합니다" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "단위 이름은 유효한 식별자여야 합니다" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "단위 이름" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "기호" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "선택 단위 기호" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "정의" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "단위 정의" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "첨부파일" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "파일 누락" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "외부 링크 누락" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" -msgstr "" +msgstr "이름을 변경할 첨부 파일이 없습니다" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" -msgstr "" +msgstr "파일 이름은 비워둘 수 없습니다" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" -msgstr "" +msgstr "잘못된 파일 이름입니다" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" -msgstr "" +msgstr "파일 확장자를 변경할 수 없습니다" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" -msgstr "" +msgstr "이 이름의 파일이 이미 존재합니다" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" -msgstr "" +msgstr "이름이 변경된 파일을 저장하지 못했습니다" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "모델 유형" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "이미지의 대상 모델 유형" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "첨부할 파일을 선택하세요" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "썸네일" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "이 첨부파일의 썸네일 이미지" + +#: common/models.py:2155 msgid "Comment" msgstr "댓글" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "첨부파일 댓글" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "업로드 날짜" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "파일이 업로드된 날짜" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "이미지 여부" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "이 첨부 파일이 유효한 이미지 파일인지 여부" + +#: common/models.py:2183 msgid "File size" msgstr "파일 크기" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "바이트 단위의 파일 크기" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "첨부파일에 대해 유효하지 않은 모델 유형이 지정되었습니다" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "사용자 정의 상태" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "사용자 정의 상태" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "참조 상태 세트" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "이 사용자 정의 상태로 확장되는 상태 세트" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "논리 키" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "업무 로직에서 이 사용자 정의 상태와 동일한 상태 논리 키" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "값" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "모델 데이터베이스에 저장될 숫자 값" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "상태 이름" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "라벨" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "프론트엔드에 표시될 라벨" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "색상" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "프론트엔드에 표시될 색상" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "모델" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "이 상태가 연결된 모델" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "모델을 선택해야 합니다" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "키를 선택해야 합니다" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "논리 키를 선택해야 합니다" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "키는 논리 키와 달라야 합니다" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "유효한 참조 상태 클래스가 제공되어야 합니다" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "키는 참조 상태의 논리 키들과 달라야 합니다" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "논리 키는 참조 상태의 논리 키 목록에 포함되어야 합니다" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "이름은 참조 상태의 이름들과 달라야 합니다" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "선택 목록" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "선택 목록" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "선택 목록 이름" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "선택 목록 설명" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "잠김" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "이 선택 목록이 잠겨 있나요?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "이 선택 목록을 사용할 수 있나요?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "소스 플러그인" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "선택 목록을 제공하는 플러그인" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "소스 문자열" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "이 목록에 사용된 소스를 식별하는 선택 문자열" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "기본 항목" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "이 선택 목록의 기본 항목" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "생성됨" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "선택 목록이 생성된 날짜 및 시간" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "마지막 업데이트" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "선택 목록이 마지막으로 업데이트된 날짜 및 시간" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "선택 목록 항목" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "선택 목록 항목" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "이 항목이 속한 선택 목록" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "선택 목록 항목의 값" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "선택 목록 항목 라벨" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "선택 목록 항목 설명" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "이 선택 목록 항목이 활성 상태인가요?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "매개변수 템플릿" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "매개변수 템플릿" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "체크박스 매개변수에는 단위를 지정할 수 없습니다" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "체크박스 매개변수에는 선택지를 지정할 수 없습니다" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "선택지는 고유해야 합니다" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "매개변수 템플릿 이름은 고유해야 합니다" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "이 매개변수 템플릿의 대상 모델 유형" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "매개변수 이름" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "단위" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "이 매개변수의 물리 단위" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "매개변수 설명" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "체크박스" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "이 매개변수는 체크박스인가요?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "선택지" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "이 매개변수에 대한 유효한 선택지(쉼표로 구분)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "이 매개변수의 선택 목록" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "사용" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "이 매개변수 템플릿을 사용하나요?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "매개변수" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "매개변수" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "매개변수 값에 대한 선택지가 올바르지 않습니다" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "매개변수에 지정된 모델 유형이 올바르지 않습니다" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "모델 ID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "이 매개변수의 대상 모델 ID" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "템플릿" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "매개변수 템플릿" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "데이터" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "매개변수 값" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "메모" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "선택적 메모 필드" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "바코드 스캔" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "바코드 데이터" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "바코드를 스캔한 사용자" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "타임스탬프" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "바코드 스캔 날짜 및 시간" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "바코드를 처리한 URL 엔드포인트" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "컨텍스트" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "바코드 스캔의 컨텍스트 데이터" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "응답" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "바코드 스캔의 응답 데이터" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "결과" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "바코드 스캔이 성공했나요?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "오류가 발생했습니다" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: 이메일 로그 삭제가 보호되어 있습니다. 삭제를 허용하려면 INVENTREE_PROTECT_EMAIL_LOG를 False로 설정하세요." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "이메일 메시지" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "이메일 메시지" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "공지됨" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "전송됨" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "실패" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "전달됨" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "확인됨" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "수신" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "발신" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "회신 없음" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "전달 추적" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "읽음 추적" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "클릭 추적" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "전역 ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "이 메시지의 식별자(외부 시스템에서 제공될 수 있음)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "스레드 ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "이 메시지 스레드의 식별자(외부 시스템에서 제공될 수 있음)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "스레드" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "이 메시지에 연결된 스레드" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "우선순위" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "이메일 스레드" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "이메일 스레드" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "키" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "이 스레드의 고유 키(스레드 식별에 사용)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "이 스레드의 고유 식별자" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "내부 시작" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "이 스레드는 내부에서 시작되었나요?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "스레드가 생성된 날짜 및 시간" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "스레드가 마지막으로 업데이트된 날짜 및 시간" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} 취소됨" msgid "A order that is assigned to you was canceled" msgstr "귀하에게 할당된 주문이 취소되었습니다" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "항목 수령됨" @@ -2388,104 +2545,100 @@ msgstr "구매 주문에 대한 항목을 수령했습니다" msgid "Items have been received against a return order" msgstr "반품 주문에 대한 항목을 수령했습니다" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "이 설정 변경에 확인이 필요한지 여부를 나타냅니다" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "이 설정은 변경 전에 확인이 필요합니다. 변경을 확인해 주세요." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "이 설정이 환경 변수로 재정의되었는지 여부를 나타냅니다" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "재정의" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "실행 중" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "대기 중인 작업" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "예약된 작업" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "실패한 작업" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "작업 ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "고유 작업 ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "잠금" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "잠금 시간" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "작업 이름" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "함수" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "함수 이름" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "인수" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "작업 인수" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "키워드 인수" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "작업 키워드 인수" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "파일명" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "모델 유형" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "이 모델의 첨부파일을 생성하거나 편집할 권한이 없습니다" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "이 모델의 매개변수를 생성하거나 편집할 권한이 없습니다" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "선택 목록이 잠겨 있습니다" - #: common/setting/system.py:97 msgid "No group" msgstr "그룹 없음" @@ -2614,13 +2767,13 @@ msgstr "환율 업데이트 간격" msgid "How often to update exchange rates (set to zero to disable)" msgstr "환율을 업데이트하는 주기(0으로 설정하면 비활성화)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "일" @@ -2633,1028 +2786,1154 @@ msgid "Currency update plugin to use" msgstr "사용할 환율 업데이트 플러그인" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "업로드 크기 제한" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "이미지 및 파일의 최대 업로드 크기" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "엄격한 URL 검증" -#: common/setting/system.py:291 +#: common/setting/system.py:298 msgid "Require schema specification when validating URLs" msgstr "URL 검증 시 스키마 지정을 요구합니다" -#: common/setting/system.py:296 +#: common/setting/system.py:303 msgid "Update Check Interval" msgstr "업데이트 확인 간격" -#: common/setting/system.py:297 +#: common/setting/system.py:304 msgid "How often to check for updates (set to zero to disable)" msgstr "업데이트를 확인하는 주기(0으로 설정하면 비활성화)" -#: common/setting/system.py:303 +#: common/setting/system.py:310 msgid "Automatic Backup" msgstr "자동 백업" -#: common/setting/system.py:304 +#: common/setting/system.py:311 msgid "Enable automatic backup of database and media files" msgstr "데이터베이스 및 미디어 파일의 자동 백업을 활성화합니다" -#: common/setting/system.py:309 +#: common/setting/system.py:316 msgid "Auto Backup Interval" msgstr "자동 백업 간격" -#: common/setting/system.py:310 +#: common/setting/system.py:317 msgid "Specify number of days between automated backup events" msgstr "자동 백업 이벤트 사이의 일 수를 지정합니다" -#: common/setting/system.py:316 +#: common/setting/system.py:323 msgid "Task Deletion Interval" msgstr "작업 삭제 간격" -#: common/setting/system.py:318 +#: common/setting/system.py:325 msgid "Background task results will be deleted after specified number of days" msgstr "백그라운드 작업 결과는 지정한 일 수 이후 삭제됩니다" -#: common/setting/system.py:325 +#: common/setting/system.py:332 msgid "Error Log Deletion Interval" msgstr "오류 로그 삭제 간격" -#: common/setting/system.py:326 +#: common/setting/system.py:333 msgid "Error logs will be deleted after specified number of days" msgstr "오류 로그는 지정한 일 수 이후 삭제됩니다" -#: common/setting/system.py:332 +#: common/setting/system.py:339 msgid "Notification Deletion Interval" msgstr "알림 삭제 간격" -#: common/setting/system.py:334 +#: common/setting/system.py:341 msgid "User notifications will be deleted after specified number of days" msgstr "사용자 알림은 지정한 일 수 이후 삭제됩니다" -#: common/setting/system.py:341 +#: common/setting/system.py:348 msgid "Email Deletion Interval" msgstr "이메일 삭제 간격" -#: common/setting/system.py:343 +#: common/setting/system.py:350 msgid "Email messages will be deleted after specified number of days" msgstr "이메일 메시지는 지정한 일 수 이후 삭제됩니다" -#: common/setting/system.py:350 +#: common/setting/system.py:357 msgid "Protect Email Log" msgstr "이메일 로그 보호" -#: common/setting/system.py:351 +#: common/setting/system.py:358 msgid "Prevent deletion of email log entries" msgstr "이메일 로그 항목 삭제를 방지합니다" -#: common/setting/system.py:356 +#: common/setting/system.py:363 msgid "Barcode Support" msgstr "바코드 지원" -#: common/setting/system.py:357 +#: common/setting/system.py:364 msgid "Enable barcode scanner support in the web interface" msgstr "웹 인터페이스에서 바코드 스캐너 지원을 활성화합니다" -#: common/setting/system.py:362 +#: common/setting/system.py:369 msgid "Store Barcode Results" msgstr "바코드 결과 저장" -#: common/setting/system.py:363 +#: common/setting/system.py:370 msgid "Store barcode scan results in the database" msgstr "바코드 스캔 결과를 데이터베이스에 저장합니다" -#: common/setting/system.py:368 +#: common/setting/system.py:375 msgid "Barcode Scans Maximum Count" msgstr "바코드 스캔 최대 개수" -#: common/setting/system.py:369 +#: common/setting/system.py:376 msgid "Maximum number of barcode scan results to store" msgstr "저장할 바코드 스캔 결과의 최대 개수" -#: common/setting/system.py:374 +#: common/setting/system.py:381 msgid "Barcode Input Delay" msgstr "바코드 입력 지연" -#: common/setting/system.py:375 +#: common/setting/system.py:382 msgid "Barcode input processing delay time" msgstr "바코드 입력 처리 지연 시간" -#: common/setting/system.py:381 +#: common/setting/system.py:388 msgid "Barcode Webcam Support" msgstr "바코드 웹캠 지원" -#: common/setting/system.py:382 +#: common/setting/system.py:389 msgid "Allow barcode scanning via webcam in browser" msgstr "브라우저에서 웹캠을 통한 바코드 스캔을 허용합니다" -#: common/setting/system.py:387 +#: common/setting/system.py:394 msgid "Barcode Show Data" msgstr "바코드 데이터 표시" -#: common/setting/system.py:388 +#: common/setting/system.py:395 msgid "Display barcode data in browser as text" msgstr "브라우저에 바코드 데이터를 텍스트로 표시합니다" -#: common/setting/system.py:393 +#: common/setting/system.py:400 msgid "Barcode Generation Plugin" msgstr "바코드 생성 플러그인" -#: common/setting/system.py:394 +#: common/setting/system.py:401 msgid "Plugin to use for internal barcode data generation" msgstr "내부 바코드 데이터 생성에 사용할 플러그인" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "부품 잠금" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "수정 방지를 위한 부품 잠금 활성화" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "부품 리비전" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "부품에 리비전 필드를 활성화합니다" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "조립품 리비전만" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "조립 부품에만 리비전을 허용합니다" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "조립품에서 삭제 허용" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "조립품에 사용되는 부품의 삭제를 허용합니다" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN 정규식" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "부품 IPN과 일치시키기 위한 정규식 패턴" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "IPN 중복 허용" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "여러 부품이 동일한 IPN을 공유하도록 허용합니다" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "IPN 편집 허용" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "부품 편집 중 IPN 값 변경을 허용합니다" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "부품 BOM 데이터 복사" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "부품을 복제할 때 기본으로 BOM 데이터를 복사합니다" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "부품 매개변수 데이터 복사" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "부품을 복제할 때 기본으로 매개변수 데이터를 복사합니다" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "부품 테스트 데이터 복사" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "부품을 복제할 때 기본으로 테스트 데이터를 복사합니다" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "카테고리 매개변수 템플릿 복사" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "부품을 생성할 때 카테고리 매개변수 템플릿을 복사합니다" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "부품은 기본적으로 템플릿입니다" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "부품은 기본적으로 다른 구성요소로 조립할 수 있습니다" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "구성요소" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "부품은 기본적으로 하위 구성요소로 사용할 수 있습니다" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "구매 가능" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "부품은 기본적으로 구매 가능합니다" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "판매 가능" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "부품은 기본적으로 판매 가능합니다" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "부품은 기본적으로 추적 가능합니다" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "가상" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "부품은 기본적으로 가상입니다" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "관련 부품 표시" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "부품에 대한 관련 부품을 표시합니다" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "초기 재고 데이터" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "새 부품 추가 시 초기 재고 생성을 허용합니다" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "초기 공급업체 데이터" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "새 부품 추가 시 초기 공급업체 데이터 생성을 허용합니다" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "부품명 표시 형식" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "부품명을 표시하는 형식" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "부품 카테고리 기본 아이콘" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "부품 카테고리 기본 아이콘(비워두면 아이콘 없음)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "가격 최소 소수 자릿수" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "가격 데이터를 표시할 때 최소 소수 자릿수" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "가격 최대 소수 자릿수" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "가격 데이터를 표시할 때 최대 소수 자릿수" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "공급업체 가격 사용" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "전체 가격 계산에 공급업체 수량별 가격을 포함합니다" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "구매 이력 우선" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "과거 구매 주문 가격이 공급업체 수량별 가격보다 우선합니다" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "재고 항목 가격 사용" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "가격 계산에 수동으로 입력한 재고 데이터의 가격을 사용합니다" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "재고 항목 가격 유효 기간" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "가격 계산에서 지정한 일 수보다 오래된 재고 항목을 제외합니다" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "변형(Variant) 가격 사용" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "전체 가격 계산에 변형(Variant) 가격을 포함합니다" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "활성 변형만" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "변형(Variant) 가격 계산에 활성 변형 부품만 사용합니다" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "가격 자동 업데이트" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "내부 데이터가 변경되면 부품 가격을 자동으로 업데이트" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "가격 재구성 간격" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "부품 가격이 자동으로 업데이트되기까지의 일 수" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "내부 가격" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "부품에 대해 내부 가격 사용" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "내부 가격 우선 적용" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "가능한 경우 내부 가격이 가격 범위 계산보다 우선합니다" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "BOM 수량 0 허용" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "부품의 BOM 항목에 수량 0을 허용합니다. 설정 수량을 사용해 빌드 수량과 무관하게 빌드당 필요한 수량을 정의할 수 있습니다" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "라벨 인쇄 사용" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "웹 인터페이스에서 라벨 인쇄를 사용합니다" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "라벨 이미지 DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "라벨 인쇄 플러그인에 제공할 이미지 파일 생성 시 DPI 해상도" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "보고서 사용" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "보고서 생성을 사용합니다" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "디버그 모드" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "디버그 모드에서 보고서 생성(HTML 출력)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "보고서 URL 가져오기" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "보고서 생성 시 원격 URL 가져오기 허용" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "보고서 오류 로그" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "보고서 생성 중 발생하는 오류를 기록합니다" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "페이지 크기" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "PDF 보고서의 기본 페이지 크기" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "매개변수 단위 강제" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "단위가 제공된 경우, 매개변수 값은 지정된 단위와 일치해야 합니다" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "전역 고유 시리얼" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "재고 항목의 시리얼 번호는 전역적으로 고유해야 합니다" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "소진된 재고 삭제" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "재고 항목이 소진되었을 때의 기본 동작을 결정합니다" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" -msgstr "" +msgstr "일련번호 편집 허용" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" -msgstr "" +msgstr "재고 항목의 일련번호 편집 허용" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" -msgstr "" +msgstr "일련번호 재고 삭제" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" -msgstr "" +msgstr "일련번호가 있는 재고 항목의 삭제 허용" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "배치 코드 템플릿" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "재고 항목의 기본 배치 코드를 생성하기 위한 템플릿" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "재고 만료" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "재고 만료 기능 사용" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "만료 재고 판매" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "만료된 재고의 판매를 허용합니다" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "재고 경과 시간" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "만료 전 재고 항목을 오래된 것으로 간주하는 일 수" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "만료 재고로 빌드" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "만료된 재고로 빌드하는 것을 허용합니다" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "재고 소유권 제어" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "재고 위치 및 항목에 대한 소유권 제어를 사용합니다" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "재고 위치 기본 아이콘" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "재고 위치 기본 아이콘(비어 있으면 아이콘 없음)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "설치된 재고 항목 표시" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "재고 표에서 설치된 재고 항목을 표시합니다" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "항목 설치 시 BOM 확인" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "설치된 재고 항목은 상위 부품의 BOM에 존재해야 합니다" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "재고 없음 상태 이동 허용" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "재고가 없는 재고 항목을 재고 위치 간에 이동할 수 있도록 허용합니다" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "반출 시 기본적으로 기존 재고와 병합" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "반출 시 재고 병합 동작의 기본 상태입니다. (필요 시 반출별로 변경 가능)" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "작업 지시서 참조번호 패턴" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "작업 지시서 참조번호 필드를 생성하기 위한 필수 패턴" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "책임자 필수" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "각 주문에는 책임자가 지정되어야 합니다" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "활성 부품 필수" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "비활성 부품에 대해 작업 지시서 생성을 방지합니다" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "잠긴 부품 필수" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "잠기지 않은 부품에 대해 작업 지시서 생성을 방지합니다" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "유효한 BOM 필수" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "BOM이 검증되지 않으면 작업 지시서 생성을 방지합니다" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "하위 주문 종료 필수" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "모든 하위 주문이 종료될 때까지 작업 지시서 완료를 방지합니다" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "외주 생산 작업 지시서" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "외주 생산 작업 지시서 기능 사용" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" -msgstr "" +msgstr "외부 제작 주문 필요" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" -msgstr "" +msgstr "외부 공급업체에서 조립 부품을 주문할 때 외부 제작 주문 필요" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "테스트 통과 전까지 차단" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "필수 테스트가 모두 통과될 때까지 생산 완제품 완료를 방지합니다" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "반품 주문 사용" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "사용자 인터페이스에서 반품 주문 기능을 사용합니다" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "반품 주문 참조 패턴" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "반품 주문 참조 필드를 생성하기 위한 필수 패턴" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "완료된 반품 주문 편집" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "반품 주문이 완료된 후에도 편집을 허용합니다" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "판매 주문 참조 패턴" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "판매 주문 참조 필드를 생성하기 위한 필수 패턴" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "판매 주문 기본 배송" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "판매 주문과 함께 기본 배송 생성 사용" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "완료된 판매 주문 편집" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "판매 주문이 배송되었거나 완료된 후에도 편집을 허용합니다" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "배송 확인 필요" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "항목이 확인될 때까지 배송 완료를 방지합니다" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "배송된 주문을 완료로 표시" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "\"배송됨\" 상태를 건너뛰고, 배송된 것으로 표시된 판매 주문을 자동으로 완료 처리합니다" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "전송 주문 활성화" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "사용자 인터페이스에서 전송 주문 기능 활성화" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "전송 주문 참조 패턴" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "전송 주문 참조 필드 생성에 필요한 패턴" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" -msgstr "" +msgstr "미완료 항목 테스트 차단" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" -msgstr "" +msgstr "필요한 항목 테스트가 완료되지 않은 경우 재고 항목을 판매 주문에 할당하지 않음" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "구매 주문 참조 패턴" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "구매 주문 참조 필드를 생성하기 위한 필수 패턴" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "완료된 구매 주문 편집" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "구매 주문이 배송되었거나 완료된 후에도 편집을 허용합니다" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "통화 변환" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "재고 수령 시 항목 값을 기준 통화로 변환합니다" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "구매 주문 자동 완료" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "모든 라인 항목을 수령하면 구매 주문을 자동으로 완료로 표시합니다" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "비밀번호 찾기 사용" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "로그인 페이지에서 비밀번호 찾기 기능을 사용합니다" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "회원가입 사용" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "로그인 페이지에서 사용자 자기 등록(회원가입)을 사용합니다" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "SSO 사용" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "로그인 페이지에서 SSO를 사용합니다" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "SSO 등록 사용" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "로그인 페이지에서 SSO를 통한 자기 등록(회원가입)을 사용합니다" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "SSO 그룹 동기화 사용" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "IdP에서 제공하는 그룹과 InvenTree 그룹의 동기화를 사용합니다" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSO 그룹 키" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "IdP에서 제공하는 groups 클레임 속성의 이름" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "SSO 그룹 매핑" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "SSO 그룹을 로컬 InvenTree 그룹으로 매핑합니다. 로컬 그룹이 없으면 생성됩니다." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "SSO 외부 그룹 제거" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "IdP에서 제공되지 않는 그룹이 사용자에게 할당되어 있으면 제거할지 여부입니다. 이 설정을 비활성화하면 보안 문제가 발생할 수 있습니다" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "이메일 필수" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "회원가입 시 이메일 입력을 요구합니다" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "SSO 사용자 자동 입력" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "SSO 계정 데이터에서 사용자 상세 정보를 자동으로 채웁니다" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "이메일 2회 입력" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "회원가입 시 이메일을 두 번 입력하도록 요청합니다" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "비밀번호 2회 입력" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "회원가입 시 비밀번호를 두 번 입력하도록 요청합니다" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "허용된 도메인" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "특정 도메인으로 회원가입을 제한합니다(쉼표로 구분, @로 시작)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "회원가입 시 그룹" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "등록 시 새 사용자가 할당될 그룹입니다. SSO 그룹 동기화가 활성화된 경우, IdP에서 그룹을 할당할 수 없을 때만 이 그룹이 설정됩니다." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "MFA 강제" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "사용자는 다중 요소 보안을 사용해야 합니다." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "이 설정을 활성화하면 모든 사용자가 다중 요소 인증을 설정해야 합니다. 모든 세션이 즉시 연결 해제됩니다." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "시작 시 플러그인 확인" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "시작 시 모든 플러그인이 설치되어 있는지 확인합니다(컨테이너 환경에서 사용)" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "플러그인 업데이트 확인" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "설치된 플러그인의 업데이트를 주기적으로 확인합니다" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "URL 통합 사용" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "플러그인이 URL 라우트를 추가할 수 있도록 허용합니다" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "내비게이션 통합 사용" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "플러그인이 내비게이션에 통합될 수 있도록 허용합니다" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "앱 통합 사용" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "플러그인이 앱을 추가할 수 있도록 허용합니다" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "스케줄 통합 사용" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "플러그인이 예약 작업을 실행할 수 있도록 허용합니다" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "이벤트 통합 사용" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "플러그인이 내부 이벤트에 응답할 수 있도록 허용합니다" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "인터페이스 통합 사용" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "플러그인이 사용자 인터페이스에 통합될 수 있도록 허용합니다" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "메일 통합 사용" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "플러그인이 발신/수신 메일을 처리할 수 있도록 허용합니다" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "프로젝트 코드 사용" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "프로젝트를 추적하기 위한 프로젝트 코드를 사용합니다" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "재고 실사 사용" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "과거 재고 수준과 가치를 기록하는 기능을 사용합니다" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "외부 위치 제외" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "외부 위치의 재고 품목을 재고 실사 계산에서 제외합니다" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "자동 재고 실사 주기" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "자동 재고 실사 기록 간격(일)" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "오래된 재고 실사 항목 삭제" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "지정된 일수보다 오래된 재고 실사 항목을 삭제합니다" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "재고 실사 삭제 간격" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "재고 실사 항목은 지정된 일수 후 삭제됩니다" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "오래된 재고 추적 항목 삭제" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "지정된 일수보다 오래된 재고 추적 항목을 삭제합니다" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "재고 추적 삭제 간격" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "재고 추적 항목은 지정된 일수 후 삭제됩니다" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "사용자 전체 이름 표시" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "사용자 이름 대신 사용자 전체 이름을 표시합니다" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "사용자 프로필 표시" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "프로필 페이지에 사용자 프로필을 표시합니다" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" -msgstr "" +msgstr "주 시작 요일" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "달력 보기에 표시할 한 주의 시작 요일" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "일요일" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "월요일" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "화요일" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "수요일" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "목요일" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "금요일" + +#: common/setting/system.py:1273 +msgid "Saturday" +msgstr "토요일" + +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "달력 표시 기간" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "달력 보기에 표시할 향후 개월 수" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "개월" + +#: common/setting/system.py:1286 +msgid "Enable Test Station Data" +msgstr "테스트 스테이션 데이터 사용" + +#: common/setting/system.py:1287 +msgid "Enable test station data collection for test results" +msgstr "테스트 결과를 위한 테스트 스테이션 데이터 수집을 사용합니다" + +#: common/setting/system.py:1292 +msgid "Enable Machine Ping" +msgstr "장비 핑 사용" + +#: common/setting/system.py:1294 +msgid "Enable periodic ping task of registered machines to check their status" +msgstr "등록된 장비의 상태를 확인하기 위해 주기적으로 핑 작업을 수행합니다" #: common/setting/system.py:1201 msgid "Starting day of the week, for display in calendar views" @@ -3881,213 +4160,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "검색 미리보기 창의 각 섹션에 표시할 결과 수" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "정규식 검색" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "검색 쿼리에서 정규식을 사용할 수 있도록 합니다" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "단어 단위 검색" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "검색 쿼리가 단어 전체가 일치하는 결과만 반환합니다" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "노트 검색" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "검색 쿼리가 항목의 노트에서 일치하는 결과를 반환합니다" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Esc 키로 폼 닫기" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Esc 키를 사용해 모달 폼을 닫습니다" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "내비게이션 바 고정" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "내비게이션 바를 화면 상단에 고정합니다" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "테이블 헤더 고정" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "테이블 헤더를 테이블 상단에 고정합니다" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "스포트라이트 표시" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "스포트라이트 내비게이션 기능을 사용합니다" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "내비게이션 아이콘" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "내비게이션 바에 아이콘을 표시합니다" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "날짜 형식" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "날짜 표시 기본 형식" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "재고 기록 표시" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "부품 상세 페이지에 재고 기록 정보를 표시합니다" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "마지막 탐색 경로 표시" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "탐색 경로(브레드크럼)에서 현재 페이지를 표시" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "추가 모델 정보 표시" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "모델 선택 드롭다운에 추가 정보 표시" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "테이블에서 전체 재고 위치 표시" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "비활성화: 전체 위치 경로를 마우스오버 툴팁으로 표시합니다. 활성화: 전체 위치 경로를 일반 텍스트로 표시합니다." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "테이블에서 전체 부품 카테고리 표시" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "비활성화: 전체 카테고리 경로를 마우스오버 툴팁으로 표시합니다. 활성화: 전체 카테고리 경로를 일반 텍스트로 표시합니다." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" -msgstr "" +msgstr "BOM 테이블에 하위 조립품 표시" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" -msgstr "" +msgstr "BOM 테이블에서 하위 조립품 표시 사용" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "오류 보고서 수신" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "시스템 오류에 대한 알림을 수신" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "마지막으로 사용한 인쇄 장비" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "사용자의 마지막 사용 인쇄 장비를 저장" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" -msgstr "" +msgstr "최종 단계에서 항목 표시" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" -msgstr "" +msgstr "하위 항목이 없는 위치 또는 카테고리에서 하위 레벨 대신 항목/부품을 기본으로 표시" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "모든 모델" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "첨부 모델 유형이 제공되지 않았습니다" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "잘못된 첨부 모델 유형입니다" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "파일 크기가 최대 업로드 제한({max_size}MB)을 초과함" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "잘못된 파일 이름" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "최소 자리수는 최대 자리수보다 클 수 없습니다" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "최대 자리수는 최소 자리수보다 작을 수 없습니다" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "빈 도메인은 허용되지 않습니다." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "잘못된 도메인 이름: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "값은 대문자여야 합니다" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "값은 유효한 변수 식별자여야 합니다" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "부품이 활성화됨" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "제조사가 활성화됨" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "공급업체 부품이 활성화됨" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "기본 공급업체 부품" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "내부 부품이 활성화됨" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "공급업체가 활성화됨" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "제조사" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "회사" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "재고 있음" @@ -4123,8 +4435,8 @@ msgstr "연락처 전화번호" msgid "Contact email address" msgstr "연락처 이메일 주소" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "담당자" @@ -4176,283 +4488,283 @@ msgstr "세금 ID" msgid "Company Tax ID" msgstr "회사 세금 ID" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "주소" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "주소" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "회사 선택" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "주소 제목" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "주소 항목을 설명하는 제목" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "기본 주소" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "기본 주소로 설정" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "주소 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "주소 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "주소 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "주소 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "우편번호" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "도시/지역" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "우편번호 도시/지역" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "주/도" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "주 또는 도" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "국가" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "주소 국가" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "택배 배송 메모" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "택배 배송을 위한 메모" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "내부 배송 메모" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "내부용 배송 메모" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "주소 정보 링크(외부)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "제조사 부품" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "기본 부품" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "부품 선택" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "제조사 선택" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "제조사 부품 번호" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "외부 제조사 부품 링크 URL" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "제조사 부품 설명" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "포장 단위는 기본 부품 단위와 호환되어야 합니다" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "포장 단위는 0보다 커야 합니다" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "연결된 제조사 부품은 동일한 기본 부품을 참조해야 합니다" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "공급업체" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "공급업체 선택" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "공급업체 SKU" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "이 공급업체 부품이 활성 상태인가요?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "기본" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "연결된 부품의 기본 공급업체 부품인가요?" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "제조사 부품 선택" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "외부 공급업체 부품 링크 URL" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "공급업체 부품 설명" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "기본 비용" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "최소 요금(예: 보관 수수료)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "포장" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "부품 포장" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "포장 수량" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "한 포장에 공급되는 총 수량입니다. 단품인 경우 비워 두세요." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "배수" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "주문 배수" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "공급업체에서 제공 가능한 수량" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "가용성 업데이트됨" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "가용성 데이터의 마지막 업데이트 날짜" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "공급업체 가격 구간" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "이 공급업체에서 사용하는 기본 통화" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "회사명" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "재고 있음" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "가격 구간" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "표시 이름" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "데이터 내보내기 중 오류가 발생했습니다" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "데이터 내보내기 플러그인이 잘못된 데이터 형식을 반환했습니다" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "내보내기 형식" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "내보내기 파일 형식을 선택하세요" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "내보내기 플러그인" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "내보내기 플러그인을 선택하세요" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "이 항목에 대한 추가 상태 정보" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "사용자 정의 상태 키" @@ -4476,123 +4788,152 @@ msgstr "접수됨" msgid "Invalid status code" msgstr "잘못된 상태 코드" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "데이터 파일" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "가져올 데이터 파일" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "열" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "이 가져오기 세션의 대상 모델 유형" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "가져오기 상태" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "필드 기본값" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "필드 재정의" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "필드 필터" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "기존 레코드 업데이트" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "활성화하면 기존 레코드가 새 데이터로 업데이트됩니다" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "일부 필수 필드가 매핑되지 않았습니다" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "완료된 행 수 기록" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "행 수 기록" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "레코드의 기존 데이터베이스 식별자" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "열이 이미 데이터베이스 필드에 매핑되어 있습니다" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "필드가 이미 데이터 열에 매핑되어 있습니다" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "열 매핑은 유효한 가져오기 세션에 연결되어야 합니다" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "데이터 파일에 해당 열이 없습니다" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "대상 모델에 해당 필드가 없습니다" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "선택한 필드는 읽기 전용입니다" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "조회 필드는 관련(외래 키) 필드에만 설정할 수 있음" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "잘못된 조회 필드입니다. 사용 가능한 옵션: {options}" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "가져오기 세션" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "필드" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "열" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "조회 필드" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "외래 키 조회에 사용할 데이터베이스 필드. 자동 조회를 사용하려면 비워두세요." + +#: importer/models.py:674 msgid "Row Index" msgstr "행 인덱스" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "원본 행 데이터" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "오류" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "유효" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "기존 레코드를 업데이트하려면 ID가 필요합니다." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "값에 대해 여러 항목이 일치합니다. 값이 고유한지 확인하거나 특정 조회 필드를 선택하세요" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "제공된 ID로 레코드를 찾을 수 없습니다" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "잘못된 ID 형식이 제공되었습니다" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "기존 레코드를 업데이트하려면 ID가 필요합니다." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "지원되지 않는 데이터 파일 형식" @@ -4600,43 +4941,47 @@ msgstr "지원되지 않는 데이터 파일 형식" msgid "Failed to open data file" msgstr "데이터 파일을 열지 못했습니다" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "잘못된 데이터 파일 크기입니다" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "잘못된 필드 기본값" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "잘못된 필드 재정의" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "잘못된 필드 필터" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "행" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "승인할 행 ID 목록" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "제공된 행이 없습니다" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "행이 이 세션에 속하지 않습니다" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "행에 잘못된 데이터가 포함되어 있습니다" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "행이 이미 완료되었습니다" @@ -4672,115 +5017,115 @@ msgstr "데이터 파일에 열이 너무 많습니다" msgid "Data file contains too many rows" msgstr "데이터 파일에 행이 너무 많습니다" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "값은 유효한 사전(dictionary) 객체여야 합니다" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "복사본" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "각 라벨에 대해 인쇄할 복사본 수" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "연결됨" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "알 수 없음" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "인쇄 중" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "경고" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "미디어 없음" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "용지 걸림" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "연결 끊김" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "오류" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "라벨 프린터" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "다양한 항목의 라벨을 직접 인쇄합니다." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "프린터 위치" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "프린터 범위를 특정 위치로 제한합니다" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "장비 이름" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "장비 유형" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "장비의 유형" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "드라이버" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "장비에 사용되는 드라이버" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "장비를 비활성화할 수 있습니다" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "사용 가능한 드라이버" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "오류 없음" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "초기화됨" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "장비 상태" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "장비" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "장비 구성" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "구성 유형" @@ -4792,7 +5137,7 @@ msgstr "속성 키" msgid "Value of the property" msgstr "속성 값" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "그룹" @@ -4816,117 +5161,118 @@ msgstr "최대 진행도" msgid "Maximum value for progress type, required if type=progress" msgstr "진행도 유형의 최대값( type=progress 인 경우 필수)" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "주문 참조" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "미결" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "프로젝트 코드 있음" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "생성자" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "이전 생성" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "이후 생성" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "시작일 있음" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "시작일 이전" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "시작일 이후" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "목표일 있음" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "목표일 이전" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "목표일 이후" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "이전 업데이트" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "이후 업데이트" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "가격 정보 있음" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "완료일 이전" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "완료일 이후" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "외주 생산 작업 지시서" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "주문" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "주문 완료" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "내부 부품" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "주문 대기" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "완료됨" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "배송 있음" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "배송을 찾을 수 없습니다" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "구매 주문" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5280,891 @@ msgstr "구매 주문" msgid "Sales Order" msgstr "판매 주문" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "반품 주문" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "전송 주문" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "총액" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "이 주문의 총액" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "주문 통화" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "이 주문의 통화(비워 두면 회사 기본값 사용)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "이 주문은 잠겨 있어 수정할 수 없습니다" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "담당자가 선택한 회사와 일치하지 않습니다" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "시작일은 목표일보다 이전이어야 합니다" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "주소가 선택한 회사와 일치하지 않습니다" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "주문 설명(선택 사항)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "이 주문의 프로젝트 코드를 선택하세요" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "외부 페이지 링크" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "시작일" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "이 주문의 예정 시작일" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "목표일" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "주문 배송 예상일입니다. 이 날짜 이후에는 주문이 기한 초과로 표시됩니다." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "발행일" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "주문이 발행된 날짜" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "업데이트 일시" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "이 주문을 담당하는 사용자 또는 그룹" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "이 주문의 연락 담당자" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "이 주문의 회사 주소" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "주문 참조" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "상태" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "구매 주문 상태" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "품목을 주문하는 공급업체" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "공급업체 참조" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "공급업체 주문 참조 코드" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "수령자" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "주문이 완료된 날짜" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "목적지" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "수령된 품목의 목적지" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "부품 공급업체는 구매 주문 공급업체와 일치해야 합니다" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "라인 항목이 구매 주문과 일치하지 않습니다" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "라인 항목에 연결된 부품이 없습니다" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "수량은 양수여야 합니다" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "가상 부품에는 일련번호를 할당할 수 없습니다" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "모든 재고 허용(일련번호 유무 무관)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "일련번호가 있는 재고만" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "일련번호가 없는 재고만" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "고객" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "품목을 판매하는 대상 회사" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "판매 주문 상태" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "고객 참조" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "고객 주문 참조 코드" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "발송일" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "발송자" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "라인 항목이 이 주문과 연결되어 있지 않습니다" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "다음 일련번호에 대한 일치 항목을 찾을 수 없습니다" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "다음 일련번호는 사용할 수 없습니다" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "주문이 이미 완료되었습니다" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "주문이 이미 취소되었습니다" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "열린 주문만 완료로 표시할 수 있습니다" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "미완료 발송이 있어 주문을 완료할 수 없습니다" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "미완료 할당이 있어 주문을 완료할 수 없습니다" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "미완료 라인 항목이 있어 주문을 완료할 수 없습니다" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "이 주문은 잠겨 있어 수정할 수 없습니다" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "품목 수량" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "라인 번호" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "이 항목의 라인 번호(선택)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "라인 항목 참조" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "라인 항목 메모" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "이 라인 항목의 목표일(비워 두면 주문의 목표일을 사용)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "라인 항목 설명(선택)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "이 라인의 추가 정보" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "단가" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "구매 주문 라인 항목" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "공급업체 부품은 공급업체와 일치해야 합니다" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "빌드 주문은 외부로 표시되어야 합니다" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "빌드 주문은 조립 부품에만 연결할 수 있습니다" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "빌드 주문 부품은 라인 항목 부품과 일치해야 합니다" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" -msgstr "" +msgstr "조립 부품에는 외부 제작 주문이 필요함" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "공급업체 부품" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "수령됨" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "수령된 품목 수" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "구매 가격" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "단위 구매 가격" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "이 라인 항목으로 이행할 외주 생산 작업 지시서" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "구매 주문 추가 라인" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "판매 주문 라인 항목" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "판매 가능한 부품만 판매 주문에 할당할 수 있습니다" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "판매 가격" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "단위 판매 가격" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "발송됨" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "발송 수량" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "판매 주문 발송" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "발송 주소는 고객과 일치해야 합니다" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "이 발송의 배송지 주소" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "발송 날짜" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "배송일" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "발송물 배송 날짜" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "확인자" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "이 발송을 확인한 사용자" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "발송" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "발송 번호" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "운송장 번호" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "발송 추적 정보" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "송장 번호" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "연결된 송장의 참조 번호" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "발송이 이미 전송되었습니다" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "발송에 할당된 재고 품목이 없습니다" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "발송은 완료하기 전에 확인되어야 합니다" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "판매 주문 추가 라인" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "판매 주문 할당" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "재고 품목이 할당되지 않았습니다" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "부품이 다른 라인에 재고 품목을 할당할 수 없습니다" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "부품이 없는 라인에는 재고를 할당할 수 없습니다" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "할당 수량은 재고 수량을 초과할 수 없습니다" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "할당 수량은 0보다 커야 합니다" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "일련번호가 있는 재고 품목의 수량은 1이어야 합니다" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "판매 주문이 발송과 일치하지 않습니다" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "발송이 판매 주문과 일치하지 않습니다" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "라인" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "판매 주문 발송 참조" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "품목" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "할당할 재고 품목을 선택하세요" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "재고 할당 수량을 입력하세요" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "반품 주문 참조" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "품목이 반품되는 회사" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "반품 주문 상태" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "반품 주문 라인 항목" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "재고 품목을 지정해야 합니다" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "반품 수량이 재고 수량을 초과합니다" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "반품 수량은 0보다 커야 합니다" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "일련번호가 있는 재고 품목에 대한 수량이 올바르지 않습니다" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "고객에게서 반품받을 품목을 선택하세요" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "수령일" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "이 반품 품목을 수령한 날짜" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "결과" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "이 라인 항목의 결과" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "이 라인 항목의 반품 또는 수리에 관련된 비용" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "반품 주문 추가 라인" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "주문 ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "전송 주문 참조" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "복제할 주문의 ID" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "전송 주문 상태" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "라인 복사" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "전송된 항목의 출발지" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "원본 주문에서 라인 항목을 복사" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "전송된 항목의 목적지" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "추가 라인 복사" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "재고 소비" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "원본 주문에서 추가 라인 항목을 복사" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "목적지로 재고를 전송하는 대신, 할당된 재고 항목에서 전송 수량을 제거하여 \"소비\" 처리" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "매개변수 복사" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "대상 위치를 설정해야 주문을 완료할 수 있습니다" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" -msgstr "원본 주문에서 주문 매개변수를 복사" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "완전히 할당되어야 주문을 완료할 수 있습니다" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "이동 주문 항목" + +#: order/models.py:4027 +msgid "transferred" +msgstr "이동됨" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "이동된 수량" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "이동 주문 할당" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "라인 항목" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "완료된 라인" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "주문 복제" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "사용자 정의 상태 키" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "이 주문을 복제하기 위한 옵션을 지정하세요" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "이 논리값에 대한 주문 상태를 사용자 정의 값으로 업데이트" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "유효하지 않은 주문 ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "사용자 정의 상태 키는 정수여야 함" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "잘못된 사용자 정의 상태 키" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "이 주문 상태에 대한 사용자 정의 상태 키가 잘못됨" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "공급업체 이름" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "주문을 취소할 수 없습니다" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "미완료 라인 항목이 있어도 주문을 종료할 수 있도록 허용" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "주문에 미완료 라인 항목이 있습니다" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "주문이 열려 있지 않습니다" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "자동 가격 책정" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "공급업체 부품 데이터를 기반으로 구매 가격을 자동으로 계산" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "구매 가격 통화" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "항목 병합" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "부품, 목적지, 목표일이 같은 항목을 하나의 라인 항목으로 병합" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "내부 부품 번호" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "내부 부품 이름" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "공급업체 부품을 지정해야 합니다" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "구매 주문을 지정해야 합니다" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "공급업체는 구매 주문과 일치해야 합니다" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "구매 주문은 공급업체와 일치해야 합니다" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "라인 항목" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "수령 품목의 목적지 위치를 선택하세요" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "입고 재고 품목의 배치 코드를 입력하세요" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "만료일" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "입고 재고 품목의 만료일을 입력하세요" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "입고 재고 품목의 일련번호를 입력하세요" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "입고 재고 품목의 포장 정보를 재정의" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "입고 재고 품목에 대한 추가 메모" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "바코드" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "스캔된 바코드" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "바코드가 이미 사용 중입니다" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "라인 항목을 제공해야 합니다" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "목적지 위치를 지정해야 합니다" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "제공된 바코드 값은 고유해야 합니다" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "발송" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "완료된 발송" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "할당된 라인" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "판매 가격 통화" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "할당된 품목" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "발송 세부 정보가 제공되지 않았습니다" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "라인 항목이 이 주문과 연결되어 있지 않습니다" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "수량은 양수여야 합니다" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" -msgstr "" +msgstr "재고 항목이 필요한 모든 테스트를 통과하지 못함" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "할당할 일련번호를 입력하세요" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "발송이 이미 발송되었습니다" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "발송이 이 주문과 연결되어 있지 않습니다" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "다음 일련번호에 대한 일치 항목을 찾을 수 없습니다" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "항목이 소싱되는 재고 위치(모든 위치를 사용하려면 비워둠)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "다음 일련번호는 사용할 수 없습니다" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "이 위치에서 재고 항목 제외" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "이 배송에 할당량 지정" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "단일 라인 항목을 충족하기 위해 여러 위치에서 재고를 가져올 수 있도록 허용" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "일련번호 지정 재고" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "일련번호가 지정된 재고 항목이 자동 할당에 포함되는지 여부 제어" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "이 라인 항목으로 할당 제한(모든 라인에 할당하려면 비워둠)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "라인 항목이 이 주문에 속하지 않음" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "반품 주문 라인 항목" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "라인 항목이 반품 주문과 일치하지 않습니다" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "라인 항목이 이미 수령되었습니다" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "진행 중인 주문에 대해서만 품목을 수령할 수 있습니다" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "반품 수량" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "라인 가격 통화" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "할당이 불완전해도 주문 완료 허용" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "주문에 불완전한 할당이 있습니다" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "분실" @@ -5718,1279 +6173,1312 @@ msgstr "분실" msgid "Returned" msgstr "반품됨" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "진행 중" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "반품" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "수리" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "교체" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "환불" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "거부" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "지급됨" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "기한 초과 구매 주문" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "구매 주문 {po}가 이제 기한을 초과했습니다" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "기한 초과 판매 주문" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "판매 주문 {so}가 이제 기한을 초과했습니다" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "기한 초과 반품 주문" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "반품 주문 {ro}가 이제 기한을 초과했습니다" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "즐겨찾기" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "즐겨찾기 카테고리로 필터" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "깊이" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "카테고리 깊이로 필터" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "최상위" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "최상위 카테고리로 필터" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "계층 포함" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "필터 결과에 하위 카테고리를 포함" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "상위" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "상위 카테고리로 필터" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "지정된 카테고리 아래의 하위 카테고리를 제외" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "최대 레벨" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "카테고리 트리의 깊이 제한" + +#: part/api.py:442 msgid "Has Results" msgstr "결과 있음" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "변형 여부" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "리비전 여부" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "리비전 있음" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "BOM 유효" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "카테고리 계층 포함" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "참이면 지정된 카테고리의 하위 카테고리에 있는 항목을 포함합니다" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "숫자 카테고리 ID 또는 'null' 값으로 필터" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "조립 부품이 활성 상태" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "조립 부품을 추적할 수 있음" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "조립 부품을 테스트할 수 있음" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" -msgstr "" +msgstr "조립품이 잠겨 있음" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "구성 부품이 활성 상태" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "구성 부품을 추적할 수 있음" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "구성 부품을 테스트할 수 있음" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "구성 부품이 조립품임" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "구성 부품이 가상 부품임" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "사용 가능한 재고 있음" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "사용" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "부품 카테고리" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "부품 카테고리" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "기본 위치" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "이 카테고리의 부품 기본 위치" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "구조적" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "부품은 구조 카테고리에 직접 할당할 수 없지만, 하위 카테고리에 할당할 수 있습니다." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "기본 키워드" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "이 카테고리의 부품 기본 키워드" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "아이콘" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "아이콘(선택)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "일부 부품이 이미 이 카테고리에 할당되어 있어 이 부품 카테고리를 구조적으로 만들 수 없습니다!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "부품 카테고리 매개변수 템플릿" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "기본값" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "기본 매개변수 값" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "부품" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "잠긴 부품의 매개변수는 삭제할 수 없습니다" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "잠긴 부품의 매개변수는 수정할 수 없습니다" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "잠겨 있어 이 부품을 삭제할 수 없습니다" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "여전히 활성 상태라 이 부품을 삭제할 수 없습니다" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "조립품에 사용 중이라 이 부품을 삭제할 수 없습니다" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "부품 '{self}'은(는) '{parent}'의 BOM에 사용할 수 없습니다(순환 참조)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "부품 '{parent}'이(가) '{self}'의 BOM에 사용되고 있습니다(순환 참조)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN은 정규식 패턴 {pattern}과 일치해야 합니다" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "부품은 자기 자신의 개정이 될 수 없습니다" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "개정으로 표시된 부품에는 개정 코드가 지정되어야 합니다" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "개정은 조립 부품에만 허용됩니다" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "템플릿 부품의 개정을 만들 수 없습니다" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "상위 부품은 동일한 템플릿을 가리켜야 합니다" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "이 일련번호의 재고 항목이 이미 존재합니다" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "부품 설정에서 중복 IPN은 허용되지 않습니다" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "중복된 부품 개정이 이미 존재합니다." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "이 이름, IPN 및 개정의 부품이 이미 존재합니다." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "부품은 구조 부품 카테고리에 할당할 수 없습니다!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "부품 이름" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "템플릿 여부" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "이 부품은 템플릿 부품인가요?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "이 부품은 다른 부품의 변형(Variant)인가요?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "변형 대상" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "부품 설명(선택)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "키워드" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "검색 결과에서 가시성을 높이기 위한 부품 키워드" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "부품 카테고리" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "부품 개정 또는 버전 번호" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "개정" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "이 부품은 다른 부품의 개정인가요?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "개정 대상" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "이 항목은 보통 어디에 보관되나요?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "기본 만료" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "이 부품의 재고 항목 만료 기간(일)" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "최소 재고" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "허용되는 최소 재고 수준" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" -msgstr "" +msgstr "최대 재고" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" -msgstr "" +msgstr "허용되는 최대 재고 수준" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "이 부품의 측정 단위" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "이 부품을 다른 부품으로 조립/제작할 수 있나요?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "이 부품을 사용해 다른 부품을 제작할 수 있나요?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "이 부품에 고유 항목 추적 기능이 있나요?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "이 부품에 대한 테스트 결과를 기록할 수 있나요?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "이 부품을 외부 공급업체에서 구매할 수 있나요?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "이 부품을 고객에게 판매할 수 있나요?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "이 부품이 활성 상태인가요?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "잠긴 부품은 편집할 수 없습니다" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "소프트웨어 제품이나 라이선스 같은 가상 부품인가요?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "이 부품이 접착제나 고정구 같은 소모품입니까?" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "BOM 검증됨" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "이 부품의 BOM이 유효한가요?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "BOM 체크섬" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "저장된 BOM 체크섬" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOM 검증자" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "BOM 검증 날짜" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "생성 사용자" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "이 부품의 책임 소유자" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "판매 배수" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "가격 계산 캐시에 사용되는 통화" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "최소 BOM 비용" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "구성 부품의 최소 비용" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "최대 BOM 비용" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "구성 부품의 최대 비용" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "최소 구매 비용" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "과거 구매 비용의 최소값" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "최대 구매 비용" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "과거 구매 비용의 최대값" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "최소 내부 가격" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "내부 가격 구간에 기반한 최소 비용" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "최대 내부 가격" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "내부 가격 구간에 기반한 최대 비용" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "최소 공급업체 가격" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "외부 공급업체로부터의 최소 가격" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "최대 공급업체 가격" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "외부 공급업체로부터의 최대 가격" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "최소 변형 비용" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "변형 부품의 계산된 최소 비용" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "최대 변형 비용" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "변형 부품의 계산된 최대 비용" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "최소 비용" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "최소 비용 재정의" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "최대 비용" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "최대 비용 재정의" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "계산된 전체 최소 비용" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "계산된 전체 최대 비용" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "최소 판매 가격" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "가격 구간에 기반한 최소 판매 가격" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "최대 판매 가격" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "가격 구간에 기반한 최대 판매 가격" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "최소 판매 비용" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "과거 판매 가격의 최소값" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "최대 판매 비용" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "과거 판매 가격의 최대값" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "재고 조사 대상 부품" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "항목 수" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "재고 조사 시점의 개별 재고 항목 수" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "재고 조사 시점의 사용 가능한 총 재고" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "날짜" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "재고 조사가 수행된 날짜" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "최소 재고 비용" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "보유 재고의 추정 최소 비용" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "최대 재고 비용" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "보유 재고의 추정 최대 비용" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "부품 판매 가격 구간" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "부품 내부 가격 구간" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "부품 테스트 템플릿" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "템플릿 이름이 올바르지 않습니다 - 영숫자 문자를 최소 1개 포함해야 합니다" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "테스트 템플릿은 테스트 가능한 부품에만 만들 수 있습니다" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "같은 키의 테스트 템플릿이 이 부품에 이미 존재합니다" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "테스트 이름" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "테스트 이름을 입력하세요" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "테스트 키" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "테스트를 위한 단순화된 키" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "테스트 설명" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "이 테스트에 대한 설명을 입력하세요" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "이 테스트가 활성화되어 있나요?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "필수" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "이 테스트는 통과가 필수인가요?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "값 필요" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "테스트 결과를 추가할 때 값이 필요한가요?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "첨부 필요" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "테스트 결과를 추가할 때 파일 첨부가 필요한가요?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "이 테스트의 유효한 선택지(쉼표로 구분)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" -msgstr "" +msgstr "잘못된 수량 - 부품에 지정된 단위 없음" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "수량은 0 이상이어야 합니다" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "조립품이 잠겨 있어 BOM 항목을 수정할 수 없습니다" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "변형 조립품이 잠겨 있어 BOM 항목을 수정할 수 없습니다" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "상위 부품을 선택하세요" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "하위 부품" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "BOM에 사용할 부품을 선택하세요" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" -msgstr "" +msgstr "수량" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" -msgstr "" +msgstr "부품 하나를 생산하는 데 소비되는 하위 부품의 양" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "이 BOM 항목의 BOM 수량" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "이 BOM 항목은 선택 사항입니다" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "이 BOM 항목은 소모품입니다(제작 주문에서 추적되지 않음)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "설정 수량" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "설정 손실을 고려해 제작에 추가로 필요한 수량" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "손실률" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "제작 손실률 추정치(백분율, 0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "반올림 배수" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "필요 생산 수량을 이 값의 가장 가까운 배수로 올림합니다" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "BOM 항목 참조" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "BOM 항목 메모" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "체크섬" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "BOM 라인 체크섬" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "검증됨" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "이 BOM 항목이 검증되었습니다" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "상속됨" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "이 BOM 항목은 변형 부품의 BOM에 상속됩니다" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "변형 부품의 재고 항목을 이 BOM 항목에 사용할 수 있습니다" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "추적 가능한 부품의 수량은 정수여야 합니다" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "하위 부품을 지정해야 합니다" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "BOM 항목 대체품" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "대체 부품은 기준 부품과 같을 수 없습니다" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "상위 BOM 항목" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "대체 부품" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "부품 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "부품 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "관련 부품 선택" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "이 관계에 대한 메모" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "부품과 자기 자신 사이에는 부품 관계를 만들 수 없습니다" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "중복된 관계가 이미 존재합니다" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "하위 카테고리 삭제" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "이 카테고리에 포함된 모든 하위 카테고리 삭제" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "부품 삭제" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "이 카테고리에 포함된 모든 부품 삭제" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "상위 카테고리" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "상위 부품 카테고리" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "하위 카테고리" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "결과" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "이 템플릿에 대해 기록된 결과 수" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "이 재고 항목의 구매 통화" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "파일이 이미지가 아닙니다" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "원본 부품" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "복제할 원본 부품을 선택하세요" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "이미지 복사" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "원본 부품의 이미지를 복사합니다" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "BOM 복사" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "원본 부품의 자재 명세서(BOM)를 복사합니다" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "원본 부품의 매개변수 데이터를 복사합니다" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "메모 복사" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "원본 부품의 메모를 복사합니다" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "테스트 복사" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "원본 부품의 테스트 템플릿을 복사합니다" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "초기 재고 수량" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "이 부품의 초기 재고 수량을 지정하세요. 수량이 0이면 재고가 추가되지 않습니다." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "초기 재고 위치" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "이 부품의 초기 재고 위치를 지정하세요" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "공급업체를 선택하세요(또는 비워 두고 건너뛰기)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "제조사를 선택하세요(또는 비워 두고 건너뛰기)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "제조사 부품 번호" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "선택한 회사는 유효한 공급업체가 아닙니다" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "선택한 회사는 유효한 제조사가 아닙니다" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "이 MPN과 일치하는 제조사 부품이 이미 존재합니다" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "이 SKU와 일치하는 공급업체 부품이 이미 존재합니다" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "카테고리 이름" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "제작 중" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "현재 생산 중인 이 부품의 수량" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "제작 예정인 이 부품의 미완료 수량" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "재고 항목" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "개정" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "총 재고" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "미할당 재고" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "변형 재고" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "부품 복제" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "다른 부품에서 초기 데이터를 복사합니다" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "이미지 복사" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "원본 부품의 이미지를 복사합니다" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "BOM 복사" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "원본 부품의 자재 명세서(BOM)를 복사합니다" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "메모 복사" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "원본 부품의 메모를 복사합니다" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "테스트 복사" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "원본 부품의 테스트 템플릿을 복사합니다" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "초기 재고" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "초기 재고 수량과 함께 부품을 생성합니다" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "공급업체 정보" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "이 부품에 대한 초기 공급업체 정보를 추가합니다" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "카테고리 매개변수 복사" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "선택한 부품 카테고리의 매개변수 템플릿을 복사합니다" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "기존 이미지" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "기존 부품 이미지의 파일명" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "이미지 파일이 존재하지 않습니다" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "전체 자재 명세서(BOM) 검증" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "제작 가능" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "제작 주문에 필요" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "제작 주문에 할당됨" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "판매 주문에 필요" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "판매 주문에 할당됨" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "부품 IPN" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "부품 설명" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "재고 조사 정보를 생성할 부품을 선택하세요(및 모든 변형 부품)." -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "해당 카테고리(및 하위 카테고리)의 모든 부품을 포함할 카테고리를 선택하세요" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "해당 위치(하위 위치 포함)에 재고가 있는 모든 부품을 포함할 위치를 선택하세요" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "재고 조사 항목 생성" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "선택한 부품에 대한 재고 조사 항목을 저장합니다" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "보고서 생성" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "선택한 부품에 대한 재고 조사 보고서를 생성합니다" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "최소 가격" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "계산된 최소 가격 값을 재정의합니다" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "최소 가격 통화" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "최대 가격" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "계산된 최대 가격 값을 재정의합니다" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "최대 가격 통화" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "업데이트" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "이 부품의 가격 정보를 업데이트합니다" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "제공된 통화를 {default_currency}(으)로 변환할 수 없습니다" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "최소 가격은 최대 가격보다 클 수 없습니다" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "최대 가격은 최소 가격보다 작을 수 없습니다" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" -msgstr "" +msgstr "이 항목에 필요한 양(단위 포함 가능)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "상위 조립품을 선택하세요" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "구성 부품을 선택하세요" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" -msgstr "" +msgstr "잘못된 수량 형식" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "BOM을 복사할 부품을 선택하세요" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "기존 데이터 제거" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "복사하기 전에 기존 BOM 항목을 제거합니다" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "상속 항목 포함" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "템플릿 부품에서 상속된 BOM 항목 포함" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "잘못된 행 건너뛰기" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "이 옵션을 사용하면 잘못된 행을 건너뜁니다" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "대체 부품 복사" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "BOM 항목을 복제할 때 대체 부품도 복사" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "재고 부족 알림" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "{part.name}의 사용 가능한 재고가 설정된 최소 수준 아래로 떨어졌습니다" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "유통기한 임박 재고 알림" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "유통기한이 임박한 재고 항목이 1개 있습니다" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "유통기한이 임박한 재고 항목이 {item_count}개 있습니다" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "유통기한 없음" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "{abs(days_diff)}일 전에 만료됨" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "오늘 만료됨" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry}일" @@ -7011,7 +7499,7 @@ msgstr "샘플" msgid "Installed" msgstr "설치됨" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "플러그인이 현재 활성 상태이므로 삭제할 수 없습니다" @@ -7023,23 +7511,23 @@ msgstr "작업이 지정되지 않았습니다" msgid "No matching action found" msgstr "일치하는 작업을 찾을 수 없습니다" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "바코드 데이터와 일치하는 항목을 찾을 수 없습니다" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "바코드 데이터와 일치하는 항목을 찾았습니다" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "지원되지 않는 모델입니다" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "모델 인스턴스를 찾을 수 없습니다" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "바코드가 기존 항목과 일치합니다" @@ -7055,51 +7543,67 @@ msgstr "일치하는 공급업체 부품을 찾을 수 없습니다" msgid "Multiple matching supplier parts found" msgstr "일치하는 공급업체 부품이 여러 개 있습니다" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "바코드 데이터에 일치하는 플러그인을 찾을 수 없습니다" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "공급업체 부품과 일치함" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "항목이 이미 입고되었습니다" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "구매 주문 발견\\r일치하는 공급업체 부품 없음" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "공급업체 부품 발견\\r일치하는 구매 주문 없음" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "공급업체 바코드에 일치하는 플러그인이 없습니다" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "일치하는 라인 항목이 여러 개 있습니다" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "일치하는 라인 항목을 찾을 수 없습니다" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "판매 주문이 제공되지 않았습니다" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "바코드가 기존 재고 항목과 일치하지 않습니다" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "재고 항목이 라인 항목과 일치하지 않습니다" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "사용 가능한 재고가 부족합니다" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "재고 항목이 판매 주문에 할당되었습니다" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "정보가 충분하지 않습니다" @@ -7108,23 +7612,23 @@ msgstr "정보가 충분하지 않습니다" msgid "Found matching item" msgstr "일치하는 항목을 찾았습니다" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "공급업체 부품이 라인 항목과 일치하지 않습니다" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "라인 항목이 이미 완료되었습니다" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "라인 항목을 입고하려면 추가 정보가 필요합니다" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "구매 주문 라인 항목을 입고했습니다" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "라인 항목 입고에 실패했습니다" @@ -7261,21 +7765,21 @@ msgid "Provides native support for barcodes" msgstr "바코드에 대한 기본 지원을 제공합니다" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7809,11 @@ msgstr "짧은 바코드 접두사" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "짧은 바코드에 사용할 접두사를 사용자 지정합니다. 여러 InvenTree 인스턴스가 있는 환경에서 유용할 수 있습니다" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "빌드 자동 생성" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "조립품에 대한 빌드 주문을 자동으로 생성합니다" @@ -7507,74 +8011,82 @@ msgid "Include Variant Items" msgstr "변형 항목 포함" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "가격 계산에 부품 변형 재고를 포함합니다" +msgid "Include part variant stock in stocktake data" +msgstr "재고 조사 데이터에 부품 변형 재고 포함" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "재고 수량 0인 항목 제외" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "내보낸 데이터셋에서 재고 수량이 0인 부품 제외" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "부품 재고 조사 내보내기" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "부품 재고 조사 데이터 내보내기 도구" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "최소 단가" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "최대 단가" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "최소 총 비용" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "최대 총 비용" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "InvenTree UI 알림" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "통합 UI 알림 방법" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree 이메일 알림" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "통합 이메일 알림 방법" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "이메일 알림 허용" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "이 사용자에게 이메일 알림을 보낼 수 있도록 허용합니다" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree Slack 알림" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "통합 Slack 알림 방법" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "Slack 수신 웹훅 URL" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "Slack 채널로 메시지를 보내는 데 사용되는 URL" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "링크 열기" @@ -7634,6 +8146,11 @@ msgstr "디버그 모드" #: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 +msgid "Debug mode" +msgstr "디버그 모드" + +#: plugin/builtin/labels/inventree_label.py:34 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "디버그 모드를 활성화하면 PDF 대신 원본 HTML을 반환합니다" @@ -7653,55 +8170,55 @@ msgstr "마지막 사용" msgid "Options" msgstr "옵션" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "라벨 시트의 페이지 크기" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "라벨 건너뛰기" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "라벨 시트를 인쇄할 때 이 개수만큼의 라벨을 건너뜁니다" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "테두리" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "각 라벨 주위에 테두리를 인쇄합니다" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "가로" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "라벨 시트를 가로 모드로 인쇄합니다" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "페이지 여백" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "페이지 가장자리 여백(mm)" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree 라벨 시트 프린터" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "여러 라벨을 한 장의 시트에 배열합니다" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "라벨이 페이지 크기에 비해 너무 큽니다" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "생성된 라벨이 없습니다" @@ -7753,77 +8270,85 @@ msgstr "TME 바코드 스캔을 지원합니다" msgid "The Supplier which acts as 'TME'" msgstr "'TME' 역할을 하는 공급업체" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "슈퍼유저 계정만 플러그인을 관리할 수 있습니다" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "플러그인 설치가 비활성화되어 있습니다" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "설치할 패키지 이름 또는 URL이 제공되지 않았습니다" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "패키지 이름 또는 URL에 잘못된 문자가 있습니다" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "플러그인을 성공적으로 설치했습니다" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "플러그인을 {path}에 설치했습니다" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "레지스트리에서 플러그인을 찾을 수 없습니다" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "플러그인이 패키지 플러그인이 아닙니다" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "플러그인 패키지 이름을 찾을 수 없습니다" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "스태프 사용자만 플러그인을 관리할 수 있습니다" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "플러그인 제거가 비활성화되어 있습니다" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "플러그인이 현재 활성 상태이므로 제거할 수 없습니다" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "플러그인이 필수이므로 제거할 수 없습니다" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "플러그인이 샘플 플러그인이므로 제거할 수 없습니다" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "플러그인이 내장 플러그인이므로 제거할 수 없습니다" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "플러그인이 설치되어 있지 않습니다" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "플러그인 설치 정보를 찾을 수 없습니다" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "플러그인을 성공적으로 제거했습니다" @@ -7871,15 +8396,25 @@ msgstr "필수 플러그인" msgid "Package Plugin" msgstr "패키지 플러그인" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "플러그인" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "작성자를 찾을 수 없습니다" -#: plugin/registry.py:786 +#: plugin/registry.py:825 +#, python-brace-format +msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" +msgstr "플러그인 '{p}'은(는) 현재 InvenTree 버전 {v}와 호환되지 않습니다" + +#: plugin/registry.py:828 +#, python-brace-format +msgid "Plugin requires at least version {v}" +msgstr "플러그인은 최소 버전 {v}가 필요합니다" + +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "플러그인 '{p}'은(는) 현재 InvenTree 버전 {v}와 호환되지 않습니다" @@ -8114,176 +8649,184 @@ msgstr "구성 삭제" msgid "Delete the plugin configuration from the database" msgstr "데이터베이스에서 플러그인 구성을 삭제합니다" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "설정이 구성으로 재정의되었는지 여부" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "이 설정이 적용될 사용자" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "항목" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "플러그인을 찾을 수 없습니다" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "플러그인이 라벨 인쇄를 지원하지 않습니다" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "이 모델 유형을 볼 권한이 없습니다" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "잘못된 라벨 크기입니다" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "템플릿에 유효한 항목이 제공되지 않았습니다" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Letter" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "이 이름의 템플릿 파일이 이미 존재합니다" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "템플릿 이름" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "템플릿 설명" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "리비전 번호(자동 증가)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "인쇄 시 모델에 첨부" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "인쇄 시 보고서 출력물을 연결된 모델 인스턴스에 첨부파일로 저장합니다" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "파일명 패턴" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "파일명을 생성하기 위한 패턴" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "템플릿이 활성화됨" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "템플릿 대상 모델 유형" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "필터" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "템플릿 쿼리 필터(쉼표로 구분된 key=value 쌍 목록)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "템플릿 파일" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "PDF 보고서 페이지 크기" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "보고서를 가로 방향으로 렌더링" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "병합" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "선택한 항목에 대해 단일 보고서를 렌더링합니다" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "템플릿 {self.name}에서 생성된 보고서" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "템플릿 구문 오류" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "보고서 렌더링 오류" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "보고서 생성 오류" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "보고서 출력 병합 오류" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "너비 [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "라벨 너비(mm)" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "높이 [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "라벨 높이(mm)" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "라벨 인쇄 오류" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "스니펫" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "보고서 스니펫 파일" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "스니펫 파일 설명" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "자산" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "보고서 자산 파일" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "자산 파일 설명" @@ -8291,23 +8834,23 @@ msgstr "자산 파일 설명" msgid "User must be authenticated to save report templates" msgstr "보고서 템플릿을 저장하려면 사용자 인증이 필요합니다" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "보고서 템플릿 선택" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "보고서에 포함할 항목의 기본 키 목록" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "라벨 템플릿 선택" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "인쇄 플러그인" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "라벨 인쇄에 사용할 플러그인을 선택하세요" @@ -8338,13 +8881,10 @@ msgstr "필요한 자재" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "부품 이미지" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "지급됨" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "필요 대상" @@ -8380,8 +8920,8 @@ msgstr "합계" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "시리얼 번호" @@ -8405,7 +8945,7 @@ msgstr "재고 품목 테스트 보고서" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "설치된 항목" @@ -8438,810 +8978,922 @@ msgstr "결과 없음(필수)" msgid "No result" msgstr "결과 없음" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "이동됨" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "잘못된 미디어 파일 경로" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "잘못된 정적 파일 경로" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "자산 파일을 찾을 수 없습니다" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "이미지 파일을 찾을 수 없습니다" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "이미지 파일이 지정되지 않았습니다" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image 태그에는 Part 인스턴스가 필요합니다" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image 태그에는 Company 인스턴스가 필요합니다" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "위치 깊이로 필터" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "최상위 위치로 필터" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "필터 결과에 하위 위치를 포함합니다" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "상위 위치" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "상위 위치로 필터" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "부품명(대소문자 구분 없음)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "부품명 포함(대소문자 구분 없음)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "부품명(정규식)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "부품 IPN(대소문자 구분 없음)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "부품 IPN 포함(대소문자 구분 없음)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "부품 IPN(정규식)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "최소 재고" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "최대 재고" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "상태 코드" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "외부 위치" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "작업 지시서에서 소비됨" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "다른 재고 품목에 설치됨" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "부품 트리" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "업데이트 날짜 이전" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "업데이트 날짜 이후" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "재고조사 날짜 이전" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "재고조사 날짜 이후" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "재고 실사일 있음" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "유효기간 날짜 이전" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "유효기간 날짜 이후" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "장기 재고" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "제외할 재고 품목 PK를 제공하면 해당 품목과 모든 하위 항목을 제외합니다" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "위치 계단식 적용" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "true이면 지정한 위치의 하위 위치에 있는 항목을 포함합니다" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "숫자 Location ID 또는 'null' 리터럴로 필터" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "수량이 필요합니다" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "유효한 부품을 제공해야 합니다" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "지정한 공급업체 부품이 존재하지 않습니다" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "공급업체 부품에 포장 단위가 정의되어 있지만 use_pack_size 플래그가 설정되지 않았습니다" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "추적 불가능한 부품에는 시리얼 번호를 제공할 수 없습니다" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "설치된 항목 포함" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "true이면 지정한 재고 품목 아래에 설치된 항목의 테스트 결과를 포함합니다" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "숫자 재고 품목 ID로 필터" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "ID가 {id}인 재고 품목이 존재하지 않습니다" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "부품 변형 포함" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "날짜 이후" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "날짜 이전" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "재고 위치 유형" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "재고 위치 유형" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "아이콘이 설정되지 않은 모든 위치에 대한 기본 아이콘(선택)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "재고 위치" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "재고 위치" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "소유자" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "소유자 선택" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "재고 품목은 구조적 재고 위치에 직접 배치할 수 없으며, 하위 위치에 배치할 수 있습니다." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "외부" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "외부 재고 위치입니다" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "위치 유형" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "이 위치의 재고 위치 유형" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "일부 재고 품목이 이미 이 위치에 있으므로 이 재고 위치를 구조적 위치로 만들 수 없습니다!" -#: stock/models.py:537 -msgid "Serialized stock items cannot be deleted" -msgstr "" +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "오래된 재고 우선(FIFO)" -#: stock/models.py:674 +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "최신 재고 우선(LIFO)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "적은 수량 우선" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "많은 수량 우선" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "만료일 임박 우선" + +#: stock/models.py:582 +msgid "Serialized stock items cannot be deleted" +msgstr "일련번호가 있는 재고 항목은 삭제할 수 없음" + +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field}이(가) 존재하지 않습니다" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "부품을 지정해야 합니다" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "재고 품목은 구조적 재고 위치에 배치할 수 없습니다!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "일련번호 편집이 허용되지 않음 - 이 항목에는 이미 일련번호가 할당되어 있습니다" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "가상 부품에 대해 재고 품목을 생성할 수 없습니다" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "부품 유형('{self.supplier_part.part}')은(는) {self.part}여야 합니다" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "시리얼 번호가 있는 품목의 수량은 1이어야 합니다" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "수량이 1보다 크면 시리얼 번호를 설정할 수 없습니다" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "항목은 자기 자신에 속할 수 없습니다" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "is_building=True인 경우 항목에는 제조 참조가 있어야 합니다" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "제조 참조가 동일한 부품 객체를 가리키지 않습니다" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "상위 재고 품목" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "기본 부품" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "이 재고 품목에 맞는 공급업체 부품을 선택하세요" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "이 재고 품목은 어디에 있습니까?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "이 재고 품목이 보관된 포장재" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "설치 위치" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "이 항목이 다른 항목에 설치되어 있습니까?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "이 항목의 시리얼 번호" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "이 재고 품목의 배치 코드" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "재고 수량" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "원본 제조" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "이 재고 품목의 제조" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "소비한 대상" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "이 재고 품목을 소비한 제조 주문" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "원본 구매 주문" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "이 재고 품목의 구매 주문" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "대상 판매 주문" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "재고 품목의 유효기간입니다. 이 날짜 이후 재고는 만료로 간주됩니다" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "이 재고 항목이 생성된 날짜" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "소진 시 삭제" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "재고가 소진되면 이 재고 품목을 삭제합니다" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "구매 시점의 단위 구매 가격" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "부품으로 변환됨" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "수량이 사용 가능한 재고를 초과합니다" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "구조적 위치에 재고를 할당할 수 없습니다" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "부품이 추적으로 설정되어 있지 않습니다" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "수량은 정수여야 합니다" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "수량은 사용 가능한 재고 수량({self.quantity})을 초과할 수 없습니다" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "시리얼 번호는 목록으로 제공되어야 합니다" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "수량이 시리얼 번호와 일치하지 않습니다" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "구조적 위치에 재고를 할당할 수 없습니다" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "테스트 템플릿이 존재하지 않습니다" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "재고 품목이 판매 주문에 할당되었습니다" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "재고 품목이 다른 품목에 설치되어 있습니다" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "재고 품목에 다른 품목이 포함되어 있습니다" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "재고 품목이 고객에게 할당되었습니다" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "재고 품목이 현재 생산 중입니다" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "시리얼 추적 재고는 병합할 수 없습니다" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "중복 재고 품목" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "재고 품목은 동일한 부품을 참조해야 합니다" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "재고 항목은 동일한 공급업체 부품을 참조해야 합니다" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "재고 상태 코드는 일치해야 합니다" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "재고에 없으므로 재고 항목을 이동할 수 없습니다" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "재고 항목 추적" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "항목 메모" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "재고 항목 테스트 결과" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "이 테스트에는 값을 제공해야 합니다" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "이 테스트에는 첨부 파일을 업로드해야 합니다" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "이 테스트의 값이 올바르지 않습니다" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "테스트 결과" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "테스트 출력 값" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "테스트 결과 첨부 파일" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "테스트 메모" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "테스트 스테이션" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "테스트가 수행된 테스트 스테이션의 식별자" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "시작됨" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "테스트 시작 시각" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "완료됨" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "테스트 종료 시각" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "생성된 배치 코드" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "제조 주문 선택" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "배치 코드를 생성할 재고 항목을 선택하세요" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "배치 코드를 생성할 위치를 선택하세요" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "배치 코드를 생성할 부품을 선택하세요" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "구매 주문 선택" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "배치 코드 수량을 입력하세요" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "생성된 일련 번호" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "일련 번호를 생성할 부품을 선택하세요" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "생성할 일련 번호 수량" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "이 결과의 테스트 템플릿" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "이 부품에 일치하는 테스트를 찾을 수 없습니다" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "템플릿 ID 또는 테스트 이름을 제공해야 합니다" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "테스트 종료 시각은 테스트 시작 시각보다 빠를 수 없습니다" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "상위 항목" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "상위 재고 항목" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "추가 시 포장 단위 사용: 입력한 수량은 포장 개수입니다" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "포장 단위 사용" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "새 항목의 일련 번호를 입력하세요" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "공급업체 부품 번호" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "만료됨" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "하위 항목" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "추적 항목" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "이 재고 항목의 구매 가격(단위 또는 포장 기준)" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "일련 번호를 부여할 재고 항목 수를 입력하세요" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "재고 항목이 제공되지 않았습니다" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "수량은 사용 가능한 재고 수량({q})을(를) 초과할 수 없습니다" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "대상 재고 위치" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "이 부품에는 일련 번호를 할당할 수 없습니다" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "일련 번호가 이미 존재합니다" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "설치할 재고 항목을 선택하세요" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "설치 수량" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "설치할 항목 수량을 입력하세요" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "거래 메모 추가(선택 사항)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "설치 수량은 최소 1이어야 합니다" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "재고 항목을 사용할 수 없습니다" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "선택한 부품이 BOM(자재 명세서)에 없습니다" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "설치 수량은 사용 가능한 수량을 초과할 수 없습니다" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "미설치 항목의 대상 위치" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "재고 항목을 변환할 부품을 선택하세요" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "선택한 부품은 변환에 사용할 수 없는 옵션입니다" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "공급업체 부품이 할당된 재고 항목은 변환할 수 없습니다" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "재고 항목 상태 코드" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "재고 항목을 변환할 부품을 선택하세요" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "선택한 부품은 변환에 사용할 수 없는 옵션입니다" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "공급업체 부품이 할당된 재고 항목은 변환할 수 없습니다" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "상태를 변경할 재고 항목을 선택하세요" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "선택된 재고 항목이 없습니다" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "하위 위치" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "재고 항목 삭제" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "이 위치에 포함된 모든 재고 항목 삭제" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "하위 위치 삭제" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "이 위치에 포함된 모든 하위 위치 삭제" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "상위 재고 위치" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "부품은 판매 가능해야 합니다" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "항목이 판매 주문에 할당되어 있습니다" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "항목이 이동 주문에 할당됨" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "항목이 제조 주문에 할당되어 있습니다" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "재고 항목을 할당할 고객" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "선택한 회사는 고객이 아닙니다" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "재고 할당 메모" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "재고 항목 목록을 제공해야 합니다" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "재고 병합 메모" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "공급업체 불일치 허용" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "공급업체 부품이 다른 재고 항목의 병합을 허용합니다" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "상태 불일치 허용" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "상태 코드가 다른 재고 항목의 병합을 허용합니다" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "최소 두 개의 재고 항목을 제공해야 합니다" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "변경 없음" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "재고 항목 기본 키 값" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "재고 항목이 재고에 없습니다" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "재고 항목이 이미 재고에 있습니다" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "수량은 음수일 수 없습니다" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "재고 거래 메모" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "기존 재고로 병합" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "가능한 경우 이 항목을 대상 위치의 기존 재고에 병합" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "재고 거래 메모" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "카운트된 항목의 재고 위치 설정(선택 사항)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "가능하면 반품된 항목을 기존 재고 항목에 병합합니다" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "다음 일련 번호" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "이전 일련 번호" @@ -9342,42 +9994,50 @@ msgid "Merged stock items" msgstr "재고 항목 병합됨" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "변형(Variant)으로 변환됨" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "제조 주문 출력 생성됨" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "제조 주문 출력 완료됨" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "제조 주문 출력 거부됨" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "제조 주문에서 소모됨" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "판매 주문으로 출하됨" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "구매 주문으로 입고됨" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "반품 주문으로 반품됨" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "고객에게 발송됨" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "고객으로부터 반품됨" @@ -9527,19 +10187,19 @@ msgstr "사용자" msgid "Select which users are assigned to this group" msgstr "이 그룹에 할당할 사용자를 선택하세요" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "개인 정보" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "권한" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "중요 날짜" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "토큰이 취소되었습니다" @@ -9547,279 +10207,283 @@ msgstr "토큰이 취소되었습니다" msgid "Token has expired" msgstr "토큰이 만료되었습니다" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API 토큰" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API 토큰" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "토큰 이름" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "사용자 지정 토큰 이름" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "토큰 만료일" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "마지막 사용" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "토큰이 마지막으로 사용된 시간" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "취소됨" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "권한 세트" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "보기" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "항목을 볼 권한" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "추가" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "항목을 추가할 권한" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "변경" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "항목을 수정할 권한" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "삭제" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "항목을 삭제할 권한" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "봇" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "내부" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "게스트" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "언어" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "사용자의 선호 언어" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "테마" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "웹 UI 설정(JSON) - 수동으로 편집하지 마세요!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "위젯" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "대시보드 위젯 설정(JSON) - 수동으로 편집하지 마세요!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "표시 이름" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "사용자가 선택한 표시 이름" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "직책" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "주요 직함 또는 직책" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "사용자 상태 메시지" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "사용자 위치 정보" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "사용자가 시스템을 사용 중입니다" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "사용자가 선호하는 연락처 정보" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "사용자 유형" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "어떤 유형의 사용자입니까?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "조직" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "사용자의 기본 조직/소속" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "기본 그룹" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "사용자의 기본 그룹" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "관리자" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" -msgstr "" +msgstr "자재 명세서" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "구매 주문" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "판매 주문" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "반품 주문" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "이동 주문" + +#: users/serializers.py:196 msgid "Username" msgstr "사용자 이름" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "이름" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "사용자의 이름" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "성" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "사용자의 성" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "사용자의 이메일 주소" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "사용자가 인증되어야 합니다" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "슈퍼유저만 다른 사용자의 토큰을 만들 수 있습니다" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "관리자" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "이 사용자에게 관리자 권한이 있습니까" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "슈퍼유저" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "이 사용자는 슈퍼유저입니까" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "이 사용자 계정이 활성 상태입니까" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "슈퍼유저만 이 필드를 조정할 수 있습니다" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "비밀번호" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "사용자의 비밀번호" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "경고 무시" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "비밀번호 규칙에 대한 경고를 무시합니다" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "스태프" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "이 사용자에게 스태프 권한이 있습니까" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "사용자를 생성할 권한이 없습니다" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "계정이 생성되었습니다." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "로그인하려면 비밀번호 재설정 기능을 사용하세요" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "InvenTree에 오신 것을 환영합니다" diff --git a/src/backend/InvenTree/locale/lt/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/lt/LC_MESSAGES/django.po index fac3f7a446..c569f94344 100644 --- a/src/backend/InvenTree/locale/lt/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/lt/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Lithuanian\n" "Language: lt_LT\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API galinis taškas nerastas" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Elementai turi būti pateikti kaip sąrašas" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Pateiktas neteisingas elementų sąrašas" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Filtras „all“ gali būti naudojamas tik su reikšme „true“" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Nė vienas elementas neatitinka pateiktų kriterijų" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Vartotojas neturi teisių peržiūrėti šio modelio" @@ -65,150 +69,155 @@ msgstr "El. pašto adreso patvirtinimas" msgid "You must type the same email each time." msgstr "Kiekvieną kartą turite įvesti tą patį el. pašto adresą." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Pateiktas pagrindinis el. pašto adresas neteisingas." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Pateiktas el. pašto domenas nepatvirtintas." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Neteisingai nurodytas vienetas ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nepateikta reikšmė" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Nepavyko konvertuoti {original} į {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Pateiktas neteisingas kiekis" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Išsami klaidos informacija pateikta administravimo skydelyje" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Įveskite datą" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Neteisinga dešimtainė reikšmė" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Pastabos" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Reikšmė „{name}“ neatitinka šablono formato" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Pateikta reikšmė neatitinka reikalaujamo šablono: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Negalima iš karto susieti daugiau nei 1000 elementų" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Nepateiktas serijos numeris" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Pasikartojantis serijinis numeris" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Neteisinga grupė: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Grupės {group} kiekis viršija leistiną kiekį ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Serijos numerių nerasta" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Pašalinkite HTML žymes iš šios reikšmės" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Duomenyse yra draudžiamo „markdown“ turinio" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Ryšio klaida" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Serveris grąžino netinkamą būsenos kodą" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Įvyko išimtis" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Serveris grąžino neteisingą „Content-Length“ reikšmę" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Paveikslėlio dydis per didelis" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Paveikslėlio atsisiuntimas viršijo maksimalų leistiną dydį" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Nutolęs serveris grąžino tuščią atsakymą" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Nurodytas URL nėra tinkamas paveikslėlio failas" @@ -216,159 +225,203 @@ msgstr "Nurodytas URL nėra tinkamas paveikslėlio failas" msgid "Log in to the app" msgstr "Prisijungti prie programos" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "El. paštas" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Prieš atliekant bet kokius veiksmus, privalote įjungti dviejų veiksnių autentifikavimą." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Klaida vykdant įskiepio patvirtinimą" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metaduomenys turi būti „Python“ žodyno tipo objektas" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Įskiepio metaduomenys" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON metaduomenų laukas, skirtas naudoti išoriniams įskiepiams" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Netinkamai suformuotas šablonas" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Nurodytas nežinomas formato raktas" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Trūksta būtino formato rakto" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "\"Nuorodos laukas negali būti tuščias" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Nuoroda turi atitikti reikalaujamą šabloną" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Nuorodos numeris per didelis" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Neteisingas pasirinkimas" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Pavadinimas" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Aprašymas" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Aprašymas (neprivalomas)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Kelias" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Po tuo pačiu pirminiu elementu negali būti pasikartojančių pavadinimų" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Pastabos su „Markdown“ (neprivalomas)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Brūkšninio kodo duomenys" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Trečiosios šalies brūkšninio kodo duomenys" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Brūkšninio kodo maiša" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Unikali brūkšninio kodo duomenų maiša\"" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Rastas esamas brūkšninis kodas" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Serverio klaida" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Serveris užfiksavo klaidą." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Paveikslėlis" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Turi būti teisingas skaičius" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valiuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Pasirinkite valiutą iš galimų variantų" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Neteisinga reikšmė" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Kopijuoti parametrus" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Kopijuoti eilutes" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Kopijuoti eilutės įrašus iš pradinio užsakymo" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Kopijuoti papildomas eilutes" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Kopijuoti papildomas eilutes iš pradinio užsakymo" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabų" @@ -521,46 +574,48 @@ msgstr "Kinų (supaprastinta)" msgid "Chinese (Traditional)" msgstr "Kinų (tradicinė)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Neteisingas fizinis vienetas" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Netinkamas valiutos kodas" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Užsakymo būsena" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Pirminė gamyba" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Įtraukti variantus" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Įtraukti variantus" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Įtraukti variantus" msgid "Part" msgstr "Detalė" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategorija" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Ankstesnė gamyba" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Priskirta man" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Priskirta" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Sukurta prieš" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Sukurta po" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Turi pradžios datą" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Pradžios data prieš" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Pradžios data po" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Turi tikslinę datą" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Tikslinė data prieš" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Tikslinė data po" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Užbaigta prieš" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Užbaigta po" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Minimali data" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Maksimali data" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Neįtraukti medžio struktūros" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Prieš ištrinant gamybą, ji turi būti atšaukta" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Sunaudojama" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Pasirinktinai" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Surinkimas" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Sekama" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testuojama" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Liko neįvykdytų užsakymų" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Priskirta" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Prieinama" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Užsakyta" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Gamybos užsakymas" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Vieta" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Gamybos užsakymai" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Surinkimo BOM nėra patvirtintas" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Negalima sukurti gamybos užsakymo neaktyviai detalei" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Negalima sukurti gamybos užsakymo atrakintai detalei" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Turi būti nurodytas atsakingas vartotojas arba grupė" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Gamybos užsakymo detalės keisti negalima" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Tikslinė data turi būti po pradžios datos" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Gamybos užsakymo nuoroda" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Nuoroda" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Trumpas gamybos aprašymas (neprivalomas)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Pasirinkite detalę gamybai" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Pardavimo užsakymo nuoroda" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Šaltinio vieta" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Pasirinkite vietą atsargoms paimti šiai gamybai (palikite tuščią, jei tinka bet kuri vieta)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Paskirties vieta" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Pasirinkite vietą, kur bus laikomos užbaigtos prekės" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Gamybos kiekis" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Atsargų kiekis, kurias reikia pagaminti" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Užbaigtos prekės" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Užbaigtų atsargų elementų skaičius" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Gamybos būsena" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Gamybos būsenos kodas" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Partijos kodas" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Šios gamybos partijos kodas" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Sukūrimo data" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Gamybos pradžios data" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Planuojama šio gamybos užsakymo pradžios data" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Tikslinė užbaigimo data" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Planuojama gamybos pabaigos data. Po šios datos gamyba bus pavėluota." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Užbaigimo data" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "Užbaigė" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Išdavė" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Vartotojas, kuris išdavė šį gamybos užsakymą" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Atsakingas" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Vartotojas ar grupė, atsakinga už šį gamybos užsakymą" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Išorinė nuoroda" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Nuoroda į išorinį URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Gamybos prioritetas" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Šio gamybos užsakymo prioritetas" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Projekto kodas" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Šio gamybos užsakymo projekto kodas" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Nepavyko perduoti užduoties, kad būtų atlikti gamybos paskirstymai" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Gamybos užsakymas {build} užbaigtas" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Gamybos užsakymas užbaigtas" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Sekamoms detalėms būtina nurodyti serijos numerius" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nepateiktas gamybos rezultatas" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Gamybos rezultatas jau užbaigtas" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Gamybos rezultatas neatitinka gamybos užsakymo" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Kiekis turi būti didesnis nei nulis" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Kiekis negali viršyti rezultato kiekio" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Gamybos rezultatas {serial} nepraėjo visų privalomų testų" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Viršytas prieinamas kiekis ({q})" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Gamybos užsakymo eilutės įrašas" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Gamybos objektas" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Gamybos objektas" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Kiekis" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Reikalingas kiekis gamybos užsakymui" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Gamybos elementas turi nurodyti rezultatą, nes pagrindinė detalė pažymėta kaip sekama" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Pasirinktas atsargų elementas neatitinka BOM eilutės" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Atsargoms su serijos numeriais kiekis turi būti 1" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Priskirtas kiekis ({q}) negali viršyti galimo atsargų kiekio ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Atsargų elementas per daug paskirstytas" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Atsargų elementas" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Šaltinio atsargų elementas" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Atsargų kiekis, skirtas paskirstyti į gamybą" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Įdiegti į" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Paskirties atsargų elementas" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Gamybos lygis" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Detalės pavadinimas" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Gamybos rezultatas" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Gamybos rezultatas neatitinka pirminės gamybos" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Rezultato detalė neatitinka gamybos užsakymo detalės" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Šis gamybos rezultatas jau užbaigtas" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Šis gamybos rezultatas nėra visiškai paskirstytas" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Įveskite kiekį gamybos rezultatui" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Sekamoms detalėms reikalingas sveikasis kiekis" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Reikalingas sveikasis kiekis, nes komplektavimo žiniaraštyje yra sekamų detalių" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Serijos numeriai" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Įveskite serijos numerius gamybos rezultatams" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Atsargų vieta gamybos rezultatams" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Automatiškai priskirti serijos numerius" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatiškai priskirti reikalingas prekes su atitinkančiais serijos numeriais" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Šie serijos numeriai jau egzistuoja arba yra neteisingi" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Turi būti pateiktas gamybos rezultatų sąrašas" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Atsargų vieta brokuotiems rezultatams" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Atmesti priskyrimus" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Atmesti visus atsargų priskyrimus brokuotiems rezultatams" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Priežastis, dėl kurios gamybos rezultatas(-ai) buvo nurašytas(-i)" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Vieta, kur laikomi užbaigti gamybos rezultatai" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Priimti nepilną priskyrimą" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Užbaigti rezultatus, net jei atsargos dar nėra pilnai priskirtos" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Sunaudoti priskirtas atsargas" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Sunaudoti bet kokias šiai gamybai jau priskirtas atsargas" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Pašalinti nebaigtus rezultatus" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Ištrinti visus nebaigtus gamybos rezultatus" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Neleidžiama" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Priimti kaip sunaudotą šio gamybos užsakymo metu" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Panaikinkite priskyrimus prieš užbaigiant šį gamybos užsakymą" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Per daug paskirstytos atsargos" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Kaip norite elgtis su papildomai šiam gamybos užsakymui priskirtomis atsargomis" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Kai kurios atsargos paskirstytos per daug" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Priimti nepriskirtą" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Priimti, kad atsargos nebuvo visiškai priskirtos šiam gamybos užsakymui" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Reikalingos atsargos nėra visiškai priskirtos" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Priimti nepilną" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Priimti, kad ne visi reikalingi gamybos rezultatai buvo užbaigti" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Reikalingas gamybos kiekis nebuvo užbaigtas" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Gamybos užsakymas turi nebaigtų antrinių gamybų" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Gamybos užsakymas turi būti gamybos būsenoje" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Gamybos užsakymas turi nebaigtų rezultatų" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Gamybos eilutė" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Gamybos rezultatas" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Gamybos rezultatas turi būti susietas su ta pačia gamyba" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Gamybos eilutės įrašas" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part turi būti ta pati detalė kaip ir gamybos užsakyme" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Prekė turi būti atsargose" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Viršytas prieinamas kiekis ({q})" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Sekamų detalių priskyrymui turi būti nurodytas gamybos rezultatas" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Negalima nurodyti gamybos rezultato nesekamoms detalėms" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Turi būti pateikti paskirstymo elementai" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Atsargų vieta, iš kurios bus imamos detalės (palikite tuščią, jei tinka bet kuri vieta)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Neįtraukti vietos" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Neįtraukti atsargų iš šios pasirinktos vietos" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Keičiamos atsargos" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Atsargos iš skirtingų vietų gali būti naudojamos pakaitomis" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Pakaitinės atsargos" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Leisti priskirti pakaitines detales" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Pasirenkami elementai" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Priskirti papildomus BOM elementus gamybos užsakymui" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "BOM nuoroda" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "BOM detalės ID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "BOM detalės pavadinimas" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Gamyba" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Tiekėjo detalė" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Priskirtas kiekis" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Gamybos nuoroda" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Detalės kategorijos pavadinimas" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Sekama" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Paveldėta" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Leisti variantus" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "BOM elementas" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "Gamyboje" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Išorinės atsargos" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Prieinamos atsargos" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Prieinamos pakaitinės atsargos" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Prieinamos variantų atsargos" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Laukiama" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Gamyba" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Sulaikyta" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Atšaukta" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Užbaigta" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Gamybos užsakymas {build} užbaigtas" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Gamybos užsakymas užbaigtas" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Atsargos, reikalingos gamybos užsakymui" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Vėluojantis gamybos užsakymas" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Gamybos užsakymas {bo} dabar vėluoja" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "Yra nuoroda" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Yra failas" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Vartotojas neturi teisės ištrinti šių priedų" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Vartotojas neturi teisės ištrinti šio priedo" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Pasirinkimų sąrašas yra užrakintas" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Netinkamas valiutos kodas" @@ -1539,15 +1641,20 @@ msgstr "Nepateikta jokių galiojančių valiutos kodų" msgid "No plugin" msgstr "Nėra papildinio" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Projekto kodo etiketė" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Atnaujinta" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Paskutinio atnaujinimo laiko žymė" @@ -1567,794 +1674,844 @@ msgstr "Unikalus projekto kodas" msgid "Project description" msgstr "Projekto aprašymas" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Vartotojas arba grupė, atsakinga už šį projektą" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Nustatymo raktas" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Nustatymo reikšmė" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Pasirinkta reikšmė yra netinkama" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Reikšmė turi būti loginė (taip/ne)" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Reikšmė turi būti sveikasis skaičius" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Reikšmė turi būti tinkamas skaičius" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Reikšmė neatitinka patikros taisyklių" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Raktas turi būti unikalus" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Vartotojas" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Kiekio ribinis taškas kainai" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Kaina" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Vieneto kaina nurodytam kiekiui" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Galutinis taškas" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Galutinis taškas, kuriuo priimamas šis webhook'as" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Šio webhook'o pavadinimas" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktyvus" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Vartotojas arba grupė, atsakinga už šį projektą" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Nustatymo raktas" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Nustatymo reikšmė" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Pasirinkta reikšmė yra netinkama" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Reikšmė turi būti loginė (taip/ne)" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Reikšmė turi būti sveikasis skaičius" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Reikšmė turi būti tinkamas skaičius" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Reikšmė neatitinka patikros taisyklių" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Raktas turi būti unikalus" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Vartotojas" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Kiekio ribinis taškas kainai" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Kaina" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Vieneto kaina nurodytam kiekiui" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Galutinis taškas" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Galutinis taškas, kuriuo priimamas šis webhook'as" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Šio webhook'o pavadinimas" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Ar šis webhook'as aktyvus" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Raktas" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Prieigos raktas" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Slaptas raktas" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Bendras slaptas HMAC raktas" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Pranešimo ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Unikalus pranešimo identifikatorius" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Pagrindinis serveris" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Serveris, iš kurio gautas pranešimas" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Antraštė" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Šio pranešimo antraštė" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Turinys" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Šio pranešimo turinys" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Galutinis taškas, kuriame gautas pranešimas" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Apdorota" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Ar darbas su šiuo pranešimu baigtas?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "ID" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Pavadinimas" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Nuoroda" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Paskelbta" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autorius" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Santrauka" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Perskaityta" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Ar ši naujiena buvo perskaityta?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Paveikslėlio failas" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Modelio tipas, kuriam priskiriamas šis paveikslėlis" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "Modelio ID, kuriam priskiriamas šis paveikslėlis" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Pasirinktinis vienetas" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Vieneto simbolis turi būti unikalus" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Vieneto pavadinimas turi būti tinkamas identifikatorius" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Vieneto pavadinimas" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Simbolis" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Nebūtinas vieneto simbolis" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Apibrėžimas" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Vieneto apibrėžimas" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Priedas" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Trūksta failo" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Trūksta išorinės nuorodos" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Modelio tipas" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Modelio tipas, kuriam skirtas paveikslėlis" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Pasirinkite failą priedui" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Komentaras" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Komentaras prie priedo" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Įkėlimo data" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Failo įkėlimo data" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Failo dydis" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Failo dydis baitais" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Netinkamas modelio tipas priedui" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Pasirinktinė būsena" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Pasirinktinės būsenos" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Nuorodos būsenų rinkinys" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Būsenų rinkinys, papildomas šia pasirinktine būsena" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Loginis raktas" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Loginis būsenos raktas, atitinkantis šią pasirinkitinę būseną" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Reikšmė" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Skaitinė reikšmė, saugoma modelio duomenų bazėje" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Būsenos pavadinimas" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etiketė" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Etiketė, rodoma vartotojo sąsajoje" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Spalva" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Spalva, rodoma vartotojo sąsajoje" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Modelis" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Modelis, su kuriuo susieta būsena" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Turi būti pasirinktas modelis" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Turi būti pasirinktas raktas" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Turi būti pasirinktas loginis raktas" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "Raktas turi skirtis nuo loginio rakto" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Turi būti pateikta tinkama nuorodos būsenos klasė" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "Raktas turi skirtis nuo nuorodos būsenų loginių raktų" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "Loginis raktas turi būti tarp nuorodos būsenų loginių raktų" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Pavadinimas turi skirtis nuo nuorodos būsenų pavadinimų" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Pasirinkimų sąrašas" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Pasirinkimų sąrašai" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Pasirinkimų sąrašo pavadinimas" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Pasirinkimų sąrašo aprašymas" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Užrakinta" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Ar šis sąrašas užrakintas?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Ar šį pasirinkimų sąrašą galima naudoti?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Šaltinio papildinys" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Papildinys, pateikiantis šį pasirinkimų sąrašą" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Šaltinio eilutė" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Neprivaloma eilutė, identifikuojanti šaltinį, naudotą šiam sąrašui" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Numatytasis įrašas" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Numatytasis šio pasirinkimų sąrašo įrašas" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Sukurta" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Data ir laikas, kada buvo sukurtas pasirinkimų sąrašas" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Paskutinį kartą atnaujinta" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Data ir laikas, kada paskutinį kartą buvo atnaujintas sąrašas" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Pasirinkimų sąrašo įrašas" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Pasirinkimų sąrašo įrašai" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Pasirinkimų sąrašas, kuriam priklauso šis įrašas" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Pasirinkimų sąrašo įrašo reikšmė" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Pasirinkimų įrašo etiketė" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Pasirinkimų įrašo aprašymas" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Ar šis sąrašo įrašas aktyvus?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Parametro šablonas" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Žymimojo laukelio parametrai negali turėti matavimo vienetų" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Žymimojo laukelio parametrai negali turėti pasirinkimų" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Pasirinkimai turi būti unikalūs" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Parametro šablono pavadinimas turi būti unikalus" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Parametro pavadinimas" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Vienetai" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Fiziniai šio parametro vienetai" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Parametro aprašymas" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Žymimasis laukelis" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Ar šis parametras yra žymimasis laukelis?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Pasirinkimai" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Galimi pasirinkimai šiam parametrui (atskirti kableliais)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Pasirinkimų sąrašas šiam parametrui" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Įjungta" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Neteisingas pasirinkimas parametro reikšmei" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Šablonas" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Data" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Parametro reikšmė" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Pastaba" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Neprivalomas pastabų laukas" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Brūkšninio kodo nuskaitymas" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Brūkšninio kodo duomenys" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Vartotojas, nuskaitęs brūkšninį kodą" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Laiko žymė" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Brūkšninio kodo nuskaitymo data ir laikas" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "URL galutinis taškas, kuris apdorojo brūkšninį kodą" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Kontekstas" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Konteksto duomenys brūkšninio kodo nuskaitymui" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Atsakas" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Atsako duomenys iš brūkšninio kodo nuskaitymo" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Rezultatas" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Ar brūkšninio kodo nuskaitymas buvo sėkmingas?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Raktas" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} atšaukta" msgid "A order that is assigned to you was canceled" msgstr "Užsakymas, kuris buvo jums priskirtas, buvo atšauktas" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Gautos prekės" @@ -2388,104 +2545,100 @@ msgstr "Prekės buvo gautos pagal pirkimo užsakymą" msgid "Items have been received against a return order" msgstr "Prekės buvo gautos pagal grąžinimo užsakymą" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Nurodo, ar nustatymą pakeičia aplinkos kintamasis" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Nepaisyti" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Vykdoma" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Laukiančios užduotys" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Suplanuotos užduotys" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Nepavykusios užduotys" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Užduoties ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Unikalus užduoties ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Užraktas" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Užrakto laikas" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Užduoties pavadinimas" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funkcija" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Funkcijos pavadinimas" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumentai" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Užduoties argumentai" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Rakto argumentai" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Užduoties rakto argumentai" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Failo pavadinimas" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Modelio tipas" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Vartotojas neturi leidimo kurti ar redaguoti šio modelio priedų" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Pasirinkimų sąrašas yra užrakintas" - #: common/setting/system.py:97 msgid "No group" msgstr "Nėra grupės" @@ -2614,13 +2767,13 @@ msgstr "Valiutų atnaujinimo intervalas" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Kaip dažnai atnaujinti valiutų kursus (nulis – išjungti)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dienos" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Naudotinas valiutų atnaujinimo papildinys" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Griežtas URL tikrinimas" @@ -2760,947 +2921,1017 @@ msgstr "Brūkšninio kodo generavimo papildinys" msgid "Plugin to use for internal barcode data generation" msgstr "Papildinys vidiniam brūkšninių kodų generavimui" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Detalių versijos" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Įjungti versijos lauką detalėms" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Tik surinkimo versijoms" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Leisti versijas tik surenkamoms detalėms" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Leisti pašalinti iš surinkimo" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Leisti ištrinti detales, kurios yra naudojamos surinkimuose" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN reguliarioji išraiška" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Reguliariosios išraiškos šablonas detalių IPN tikrinimui" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Leisti pasikartojančius IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Leisti kelioms detalėms turėti tą patį IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Leisti redaguoti IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Leisti keisti IPN reikšmę redaguojant detalę" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Kopijuoti detalės BOM duomenis" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Kopijuoti BOM duomenis pagal nutylėjimą dubliuojant detalę" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Kopijuoti detalės parametrus" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Kopijuoti parametrų duomenis pagal nutylėjimą dubliuojant detalę" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Kopijuoti detalės testavimo duomenis" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Kopijuoti testavimo duomenis pagal nutylėjimą dubliuojant detalę" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kopijuoti kategorijų parametrų šablonus" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Kopijuoti kategorijų parametrų šablonus kuriant detalę" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Detalės pagal nutylėjimą yra šablonai" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Detalės pagal nutylėjimą gali būti surenkamos iš kitų komponentų" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponentas" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Detalės pagal nutylėjimą gali būti naudojamos kaip sub-komponentai" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Galima įsigyti" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Detalės pagal nutylėjimą gali būti įsigyjamos" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Parduodama" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Detalės pagal nutylėjimą gali būti parduodamos" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Detalės pagal nutylėjimą gali būti sekamos" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuali" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Detalės pagal nutylėjimą yra virtualios" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Rodyti susijusias detales" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Rodyti susijusias detales pasirinktai detalei" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Pradiniai atsargų duomenys" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Leisti sukurti pradinę atsargą pridedant naują detalę" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Pradiniai tiekėjo duomenys" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Leisti sukurti pradinius tiekėjo duomenis pridedant naują detalę" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Detalės pavadinimo rodymo formatas" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Detalės pavadinimo rodymo formatas" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Detalės kategorijos numatytoji piktograma" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Detalės kategorijos numatytoji piktograma (tuščia reiškia, kad nenaudojama)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Mažiausias kainos dešimtainių skaičių kiekis" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Minimalus dešimtainių skaitmenų skaičius rodomas kainodaros duomenyse" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Didžiausias kainos dešimtainių skaičių kiekis" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Didžiausias dešimtainių skaitmenų skaičius rodomas kainodaros duomenyse" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Naudoti tiekėjo kainas" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Įtraukti tiekėjų kainų lygius į bendrą kainodaros skaičiavimą" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Pirkimų istorija keičia kainas" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Istorinės pirkimo kainos pakeičia tiekėjo kainų lygius" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Naudoti atsargų kainas" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Naudoti kainas iš rankiniu būdu įvestų atsargų duomenų kainodaros skaičiavimui" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Atsargų kainų galiojimo trukmė" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Pašalinti senesnes nei nurodytas dienų skaičius atsargas iš kainodaros skaičiavimų" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Naudoti variantų kainas" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Įtraukti variantų kainas į bendrą kainodaros skaičiavimą" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Tik aktyvūs variantai" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Naudoti tik aktyvius detalių variantus kainodarai" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Kainodaros atnaujinimo intervalas" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Dienų skaičius iki automatinio detalių kainų atnaujinimo" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Vidinės kainos" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Įjungti vidines kainas detalėms" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Vidinės kainos viršenybė" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Jei yra, vidinės kainos pakeičia bendrus kainodaros skaičiavimus" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Įjungti etikečių spausdinimą" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Įjungti etikečių spausdinimą iš žiniatinklio sąsajos" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Etiketės vaizdo DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "DPI raiška generuojant vaizdus etikečių spausdinimo papildiniams" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Įjungti ataskaitas" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Įjungti ataskaitų generavimą" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Derinimo režimas" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Generuoti ataskaitas derinimo režimu (HTML išvestis)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Registruoti ataskaitų klaidas" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Registruoti klaidas, įvykusias generuojant ataskaitas" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Puslapio dydis" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Numatytasis PDF ataskaitų puslapio dydis" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Reikalauti parametrų vienetų" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Jei nurodyti vienetai, parametro reikšmės turi atitikti nurodytus vienetus" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Globaliai unikalūs serijiniai numeriai" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Atsargų serijos numeriai turi būti globaliai unikalūs" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Ištrinti išnaudotas atsargas" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Nustato numatytą elgseną, kai atsargos yra išnaudotos" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Partijos kodo šablonas" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Šablonas numatytiesiems atsargų partijos kodams generuoti" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Atsargų galiojimas" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Įjungti atsargų galiojimo funkcionalumą" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Parduoti pasibaigusias galioti atsargas" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Leisti parduoti pasibaigusias galioti atsargas" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Atsargų senėjimo laikas" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Dienų skaičius, po kurio atsargos laikomos pasenusiomis iki jų galiojimo pabaigos" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Naudoti pasibaigusias galioti atsargas gamyboje" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Leisti naudoti pasibaigusias galioti atsargas gamyboje" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Atsargų nuosavybės kontrolė" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Įjungti atsargų vietų ir vienetų nuosavybės kontrolę" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Atsargų vietos numatytoji piktograma" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Atsargų vietos numatytoji piktograma (tuščia reiškia nenaudojama)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Rodyti sumontuotas atsargas" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Rodyti sumontuotas atsargas atsargų lentelėse" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Tikrinti BOM montuojant atsargas" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Sumontuotos atsargos turi būti pirminio gaminio BOM" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Leisti perkelti neturimas atsargas" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Leisti perkelti atsargas tarp vietų net jei jų nėra atsargose" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Gamybos užsakymo nuorodos šablonas" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Privalomas šablonas gamybos užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Reikalauti atsakingo savininko" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Kiekvienam užsakymui turi būti priskirtas atsakingas savininkas" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Reikalauti aktyvios detalės" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Neleidžia kurti gamybos užsakymų neaktyvioms detalėms" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Reikalauti užrakintos detalės" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Neleidžia kurti gamybos užsakymų neužrakintoms detalėms" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Reikalauti galiojančio komplektavimo sąrašo (BOM)" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Neleidžia kurti gamybos užsakymų, kol BOM nėra patvirtintas" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Reikalauti uždarytų antrinių užsakymų" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Neleidžia užbaigti gamybos užsakymo, kol visi antriniai užsakymai neuždaryti" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blokuoti, kol testai bus išlaikyti" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Neleidžia užbaigti gaminių, kol visi privalomi testai nėra išlaikyti" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Įjungti grąžinimo užsakymus" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Įjungia grąžinimo užsakymų funkciją vartotojo sąsajoje" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Grąžinimo užsakymo nuorodos šablonas" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Būtinas šablonas grąžinimo užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Redaguoti užbaigtus grąžinimo užsakymus" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Leisti redaguoti grąžinimo užsakymus po jų užbaigimo" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Pardavimo užsakymo nuorodos šablonas" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Būtinas šablonas pardavimo užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Numatytasis siuntinys pardavimo užsakymui" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Leisti automatiškai sukurti siuntinį kartu su pardavimo užsakymu" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Redaguoti užbaigtus pardavimo užsakymus" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Leisti redaguoti pardavimo užsakymus po jų išsiuntimo arba užbaigimo" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Pažymėti išsiųstus užsakymus kaip užbaigtus" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Pardavimo užsakymai, pažymėti kaip išsiųsti, bus automatiškai užbaigti, praleidžiant būseną „išsiųsta“" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Pirkimo užsakymo nuorodos šablonas" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Būtinas šablonas pirkimo užsakymo nuorodos laukui generuoti" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Redaguoti užbaigtus pirkimo užsakymus" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Leisti redaguoti pirkimo užsakymus po jų išsiuntimo arba užbaigimo" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Konvertuoti valiutą" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Konvertuoti prekių vertę į pagrindinę valiutą priimant prekes" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Automatiškai užbaigti pirkimo užsakymus" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Automatiškai pažymėti pirkimo užsakymus kaip užbaigtus, kai visos eilutės yra gautos" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Įjungti pamiršto slaptažodžio funkciją" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Leisti naudoti pamiršto slaptažodžio funkciją prisijungimo puslapyje" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Įjungti registraciją" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Leisti vartotojams savarankiškai registruotis prisijungimo puslapyje" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "Įjungti vieningą prisijungimą (SSO)" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Įjungti vieningą prisijungimą (SSO) prisijungimo puslapyje" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Įjungti registraciją per SSO" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Leisti vartotojams registruotis per SSO prisijungimo puslapyje" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Įjungti SSO grupių sinchronizavimą" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Įjungti InvenTree grupių sinchronizavimą su tapatybės tiekėjo (IdP) grupėmis" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSO grupės raktas" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Grupių atributo pavadinimas, kurį pateikia tapatybės tiekėjas (IdP)" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "SSO grupių susiejimas" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "SSO grupių susiejimas su vietinėmis InvenTree grupėmis. Jei vietinė grupė neegzistuoja, ji bus sukurta." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Pašalinti grupes, nepriklausančias SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Ar pašalinti vartotojui priskirtas grupes, jei jos nėra pateikiamos per IdP. Išjungus gali kilti saugumo problemų" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "El. paštas privalomas" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Reikalauti vartotojo el. pašto registracijos metu" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Automatiškai užpildyti SSO naudotojų duomenis" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Automatiškai užpildyti vartotojo informaciją pagal SSO paskyros duomenis" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Įvesti el. paštą du kartus" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Registracijos metu prašyti vartotojų du kartus įvesti el. paštą" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Įvesti slaptažodį du kartus" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Registracijos metu prašyti vartotojų du kartus įvesti slaptažodį" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Leidžiami domenai" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Riboti registraciją tik tam tikriems domenams (atskiriama kableliais, prasideda @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grupė registruojantis" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Grupė, į kurią priskiriami nauji vartotojai registracijos metu. Jei įjungta SSO grupių sinchronizacija, ši grupė nustatoma tik tuo atveju, jei grupė negaunama iš IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Reikalauti kelių veiksnių autentifikacijos (MFA)" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Vartotojai privalo naudoti kelių veiksnių apsaugą." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Tikrinti įskiepius paleidimo metu" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Tikrina, ar visi įskiepiai įdiegti paleidžiant – naudoti konteinerių aplinkose" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Tikrinti įskiepių atnaujinimus" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Įjungti periodinius įdiegtų įskiepių atnaujinimų tikrinimus" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Įjungti URL integravimą" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Leisti įskiepiams pridėti URL maršrutus" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Įjungti navigacijos integraciją" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Leisti įskiepiams integruotis į navigaciją" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Įjungti programų integraciją" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Leisti įskiepiams pridėti programas" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Įjungti planavimo integraciją" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Leisti įskiepiams vykdyti suplanuotas užduotis" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Įjungti įvykių integraciją" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Leisti įskiepiams reaguoti į vidinius įvykius" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Įjungti sąsajos integraciją" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Leisti įskiepiams integruotis į vartotojo sąsają" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Įjungti projektų kodus" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Įjungti projektų kodų naudojimą projektų sekimui" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Neįtraukti išorinių vietų" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Automatinės inventorizacijos periodas" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Rodyti pilnus vartotojų vardus" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Rodyti pilnus vardus vietoj vartotojo vardų" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Rodyti vartotojų profilius" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Rodyti vartotojų profilius jų paskyros puslapyje" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Įjungti bandymų stoties duomenis" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Įjungti bandymų stoties duomenų rinkimą testų rezultatams" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Rezultatų skaičius, rodomas kiekviename paieškos peržiūros lango skyriuje" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Reguliariųjų išraiškų paieška" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Įjungti reguliariųjų išraiškų palaikymą paieškoje" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Ieškoti viso žodžio atitikmenų" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Paieškos užklausos grąžins tik tikslius viso žodžio atitikmenis" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Ieškoti pastabose" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Paieškos rezultatai apima atitikmenis iš įrašo pastabų" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Escape klavišas uždaro formas" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Naudoti Escape klavišą modalinių formų uždarymui" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Fiksuotas naršymo meniu" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Naršymo meniu pozicija fiksuota ekrano viršuje" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Naršymo piktogramos" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Rodyti piktogramas naršymo juostoje" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Datos formatas" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Pageidaujamas datos rodymo formatas" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "Rodyti paskutinę naršymo grandį" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "Rodyti aktyvų puslapį naršymo grandinėje" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" +msgstr "Rodyti paskutinę naršymo grandį" + +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" +msgstr "Rodyti aktyvų puslapį naršymo grandinėje" + +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" -msgstr "" - -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Gauti klaidų ataskaitas" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Gauti pranešimus apie sistemos klaidas" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Paskutiniai naudoti spausdintuvai" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Išsaugoti paskutinius naudotojo naudotus spausdintuvus" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Nepateiktas priedų modelio tipas" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Neteisingas priedų modelio tipas" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Mažiausias vietų skaičius negali būti didesnis nei didžiausias" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Didžiausias vietų skaičius negali būti mažesnis nei mažiausias" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Tuščias domenas neleidžiamas." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Neteisingas domeno pavadinimas: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Reikšmė turi būti didžiosiomis raidėmis" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Reikšmė turi būti galiojantis kintamojo identifikatorius" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Detalė yra aktyvi" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Gamintojas yra aktyvus" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Tiekėjo detalė yra aktyvi" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Vidinė detalė yra aktyvi" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Tiekėjas yra aktyvus" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Gamintojas" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Įmonė" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Turi atsargų" @@ -4123,8 +4387,8 @@ msgstr "Kontaininis telefono numeris" msgid "Contact email address" msgstr "Kontaktinis el. pašto adresas" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontaktinis asmuo" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adresas" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adresai" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Pasirinkite įmonę" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Adreso pavadinimas" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Pavadinimas, apibūdinantis adreso įrašą" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Pagrindinis adresas" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Nustatyti kaip pagrindinį adresą" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "1-a eilutė" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Adreso 1-a eilutė" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "2-a eilutė" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Adreso 2-a eilutė" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Pašto kodas" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Miestas / regionas" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Pašto kodas, miestas / regionas" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Valstija / provincija" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Valstija arba provincija" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Šalis" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Adreso šalis" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Kurjerio siuntos pastabos" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Pastabos siuntų kurjeriui" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Vidinės siuntos pastabos" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Siuntimo pastabos vidiniam naudojimui" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Nuoroda į adreso informaciją (išorinė)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Gamintojo detalė" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Pagrindinė detalė" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Pasirinkite detalę" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Pasirinkite gamintoją" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Gamintojo detalės numeris (MPN)" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "Išorinės nuorodos į gamintojo detalės URL" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Gamintojo detalės aprašymas" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Pakuotės vienetai turi atitikti pagrindinės detalės vienetus" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Pakuotės vienetų kiekis turi būti didesnis už nulį" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Susieta gamintojo detalė turi nurodyti tą pačią pagrindinę detalę" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Tiekėjas" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Pasirinkite tiekėją" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Tiekėjo sandėlio numeris (SKU)" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Ar ši tiekėjo detalė aktyvi?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Pasirinkite gamintojo detalę" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "Išorinės nuorodos į tiekėjo detalės URL" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Tiekėjo detalės aprašymas" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "bazinė kaina" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimalus mokestis (pvz., sandėliavimo mokestis)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Pakuotė" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Detalės pakuotė" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Pakuotės kiekis" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Bendras kiekis vienoje pakuotėje. Palikite tuščią, jei prekė tiekiama po vieną." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "daugiklis" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Užsakymo daugiklis" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Tiekėjo turimas kiekis" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Prieinamumas atnaujintas" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Paskutinio prieinamumo duomenų atnaujinimo data" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Tiekėjo kainos ribos" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Numatytoji valiuta, naudojama šiam tiekėjui" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Įmonės pavadinimas" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Sandėlyje" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Įvyko klaida eksportuojant duomenis" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Duomenų eksporto įskiepis grąžino neteisingą duomenų formatą" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Eksporto formatas" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Pasirinkite eksporto failo formatą" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Eksporto įskiepis" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Pasirinkite eksporto įskiepį" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Papildoma būsena šiam elementui" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Pasirinktinės būsenos raktas" @@ -4476,123 +4740,152 @@ msgstr "Pateiktas" msgid "Invalid status code" msgstr "Neteisingas būsenos kodas" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Duomenų failas" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Duomenų failas, kurį reikia importuoti" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Stulpeliai" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Importavimo sesijos tikslinio modelio tipas" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Importavimo būsena" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Laukų numatytosios reikšmės" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Laukų perrašymai" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Laukų filtrai" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Kai kurie privalomi laukai nėra susieti" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "Šis stulpelis jau yra susietas su duomenų bazės lauku" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Šis laukas jau yra susietas su duomenų stulpeliu" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Stulpelių susiejimas turi būti susietas su galiojančia importavimo sesija" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Stulpelis neegzistuoja duomenų faile" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Laukas neegzistuoja tiksliniame modelyje" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Pasirinktas laukas yra tik skaitomas" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Importavimo sesija" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Laukas" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Stulpelis" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Eilutės indeksas" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Pradiniai eilutės duomenys" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Klaidos" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Galiojantis" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Nepalaikomas duomenų failo formatas" @@ -4600,43 +4893,47 @@ msgstr "Nepalaikomas duomenų failo formatas" msgid "Failed to open data file" msgstr "Nepavyko atidaryti duomenų failo" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Neteisingi duomenų failo matmenys" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Neteisingos laukų numatytosios reikšmės" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Neteisingi laukų perrašymai" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Neteisingi laukų filtrai" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Eilutės" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Eilučių ID sąrašas, kurias priimti" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Nepateikta jokių eilučių" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "Eilutė nepriklauso šiai sesijai" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "Eilutėje yra neteisingų duomenų" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "Eilutė jau buvo užbaigta" @@ -4672,115 +4969,115 @@ msgstr "Duomenų faile per daug stulpelių" msgid "Data file contains too many rows" msgstr "Duomenų faile per daug eilučių" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Reikšmė turi būti teisingas žodyno objektas" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopijos" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Etiketės spausdinamų kopijų skaičius" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Prijungta" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Nežinoma" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Spausdinama" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Nėra laikmenos" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Popieriaus užstrigimas" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Atjungta" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Etikečių spausdintuvas" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Tiesiogiai spausdinti etiketes įvairiems elementams." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Spausdintuvo vieta" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Apriboti spausdintuvo veikimą konkrečia vieta" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Įrenginio pavadinimas" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Įrenginio tipas" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Įrenginio rūšis" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Tvarkyklė" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Įrenginiui naudojama tvarkyklė" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Įrenginiai gali būti išjungti" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Tvarkyklė prieinama" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Klaidų nėra" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Inicializuota" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Įrenginio būsena" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Įrenginys" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Įrenginio konfigūracija" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Konfigūracijos tipas" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupė" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Užsakymo nuoroda" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Neįvykdyta" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Turi projekto kodą" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Sukūrė" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Sukurta prieš" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Sukurta po" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Turi pradžios datą" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Pradžios data prieš" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Pradžios data po" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Turi tikslinę datą" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Tikslinė data prieš" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Tikslinė data po" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Turi kainodarą" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Užbaigta prieš" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Užbaigta po" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Užsakymas" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Užsakymas įvykdytas" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Vidinė detalė" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Užsakymas laukia vykdymo" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Užbaigta" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Turi siuntą" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Pirkimo užsakymas" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Pirkimo užsakymas" msgid "Sales Order" msgstr "Pardavimo užsakymas" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Grąžinimo užsakymas" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Bendra kaina" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Bendra kaina už šį užsakymą" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Užsakymo valiuta" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Užsakymo valiuta (palikite tuščią, jei norite naudoti įmonės numatytąją valiutą)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Šis užsakymas užrakintas ir negali būti keičiamas" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Kontaktas nesutampa su pasirinkta įmone" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "Pradžios data turi būti prieš tikslinę datą" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Užsakymo aprašymas (neprivalomas)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Pasirinkite projekto kodą šiam užsakymui" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Nuoroda į išorinį puslapį" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Pradžios data" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Numatyta pradžios data šiam užsakymui" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Tikslinė data" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Tikėtina užsakymo pristatymo data. Užsakymas bus vėluojantis po šios datos." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Išdavimo data" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Data, kada užsakymas buvo išduotas" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Vartotojas arba grupė, atsakinga už šį užsakymą" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Kontaktinis asmuo šiam užsakymui" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Įmonės adresas šiam užsakymui" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Užsakymo nuoroda" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Būsena" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Pirkimo užsakymo būsena" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Įmonė, iš kurios užsakomos prekės" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Tiekėjo nuoroda" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Tiekėjo užsakymo nuorodos kodas" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "gavo" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Data, kada užsakymas buvo užbaigtas" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Paskirties vieta" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Paskirties vieta gautoms prekėms" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Detalių tiekėjas turi atitikti pirkimo užsakymo tiekėją" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Eilutės įrašas neatitinka pirkimo užsakymo" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Kiekis turi būti teigiamas skaičius" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Klientas" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Įmonė, kuriai prekės parduodamos" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Pardavimo užsakymo būsena" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Kliento nuoroda" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Kliento užsakymo nuorodos kodas" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Siuntos data" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "išsiuntė" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Eilutės įrašas nėra susijęs su šiuo užsakymu" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Nerasta atitikmenų šiems serijos numeriams" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Šie serijos numeriai nepasiekiami" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Užsakymas jau baigtas" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Užsakymas jau atšauktas" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Tik atviras užsakymas gali būti pažymėtas kaip užbaigtas" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Užsakymas negali būti užbaigtas, nes yra neišsiųstų siuntų" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Užsakymas negali būti užbaigtas, nes yra nepriskirtų prekių" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Užsakymas negali būti užbaigtas, nes yra neužbaigtų eilučių" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "Užsakymas užrakintas ir negali būti keičiamas" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Prekės kiekis" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Eilutės įrašo nuoroda" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Eilutės įrašo pastabos" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Tikslinė šio eilutės įrašo data (palikite tuščią, jei norite naudoti užsakymo tikslinę datą)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Eilutės įrašo aprašymas (neprivalomas)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Papildomas kontekstas šiai eilutei" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Vieneto kaina" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Pirkimo užsakymo eilutės įrašas" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Tiekėjo detalė turi atitikti tiekėją" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Tiekėjo detalė" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Gauta" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Gautų prekių kiekis" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Pirkimo kaina" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Vieneto pirkimo kaina" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Pirkimo užsakymo papildoma eilutė" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Pardavimo užsakymo eilutės įrašas" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Tik parduodamos detalės gali būti priskirtos pardavimo užsakymui" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Pardavimo kaina" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Vieneto pardavimo kaina" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Išsiųsta" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Išsiųstas kiekis" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Pardavimo užsakymo siunta" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Siuntos data" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Pristatymo data" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Siuntos pristatymo data" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Patikrino" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Vartotojas, patikrinęs šią siuntą" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Siunta" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Siuntos numeris" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Sekimo numeris" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Siuntos sekimo informacija" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Sąskaitos faktūros numeris" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Nuorodos numeris susijusiai sąskaitai faktūrai" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Siunta jau buvo išsiųsta" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Siunta neturi priskirtų prekių" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Pardavimo užsakymo papildoma eilutė" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Pardavimo užsakymo paskirstymas" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Prekė nėra priskirta" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Negalima priskirti prekių eilutei su skirtinga detale" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Negalima priskirti prekių eilutei, jei joje nėra detalės" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Priskiriamas kiekis negali viršyti atsargų kiekio" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Priskirtas kiekis turi būti didesnis nei nulis" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Kiekis turi būti 1, jei prekė turi serijos numerį" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Pardavimo užsakymas nesutampa su siunta" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Siunta nesutampa su pardavimo užsakymu" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Eilutė" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Pardavimo užsakymo siuntos nuoroda" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Prekė" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Pasirinkite atsargų elementą priskyrimui" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Įveskite prekių priskyrimo kiekį" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Grąžinimo užsakymo nuoroda" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Įmonė, iš kurios grąžinamos prekės" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Grąžinimo užsakymo būsena" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Grąžinimo užsakymo eilutės įrašas" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Turi būti nurodytas atsargų elementas" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Grąžinamo kiekis viršija prekių kiekį" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "Grąžinamo kiekis turi būti daugiau nei nulis" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Neteisingas kiekis serijinio numerio prekei" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Pasirinkite prekę grąžinimui iš kliento" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Gavimo data" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Rezultatas" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Rezultatas šiam eilutės įrašui" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Išlaidos, susijusios su šio eilutės įrašo grąžinimu ar remontu" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Grąžinimo užsakymo papildoma eilutė" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "Užsakymo ID" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "Užsakymo, kurį reikia dubliuoti, ID" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Kopijuoti eilutes" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Kopijuoti eilutės įrašus iš pradinio užsakymo" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Kopijuoti papildomas eilutes" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Kopijuoti papildomas eilutes iš pradinio užsakymo" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Kopijuoti parametrus" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Eilutės įrašai" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Užbaigtos eilutės" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Dubliuoti užsakymą" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Nurodykite užsakymo dubliavimo parinktis" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Neteisingas užsakymo ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Tiekėjo pavadinimas" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Užsakymo atšaukti negalima" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Leisti užbaigti užsakymą su neužbaigtais eilutės įrašais" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Užsakyme yra neužbaigtų eilutės įrašų" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Užsakymas nėra atidarytas" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Automatinis kainų nustatymas" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Automatiškai apskaičiuoti pirkimo kainą pagal tiekėjo detalės duomenis" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Pirkimo kainos valiuta" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Sujungti elementus" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Sujungti elementus su ta pačia detale, paskirtimi ir tiksline data į vieną eilutės įrašą" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Vidinis detalės numeris" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Vidinis detalės pavadinimas" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Turi būti nurodyta tiekėjo detalė" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Turi būti nurodytas pirkimo užsakymas" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Tiekėjas turi atitikti pirkimo užsakymą" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Pirkimo užsakymas turi atitikti tiekėją" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Eilutės įrašas" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Pasirinkite paskirties vietą gautiems elementams" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Įveskite partijos kodą gaunamoms atsargoms" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Galiojimo data" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Įveskite galiojimo datą gaunamoms atsargoms" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Įveskite gaunamų atsargų serijos numerius" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Pakeisti gaunamų atsargų pakavimo informaciją" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Papildoma pastaba gaunamoms atsargoms" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Brūkšninis kodas" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Nuskaitytas brūkšninis kodas" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Brūkšninis kodas jau naudojamas" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Turi būti pateikti eilutės įrašai" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Turi būti nurodyta paskirties vieta" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Pateiktos brūkšninių kodų reikšmės turi būti unikalios" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Siuntos" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Užbaigtos siuntos" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Pardavimo kainos valiuta" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Paskirstyti elementai" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Nepateikta siuntos informacija" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Eilutės įrašas nėra susijęs su šiuo užsakymu" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Kiekis turi būti teigiamas" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Įveskite priskiriamus serijos numerius" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Siunta jau išsiųsta" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Siunta nėra susieta su šiuo užsakymu" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Nerasta atitikmenų šiems serijos numeriams" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Šie serijos numeriai nepasiekiami" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Grąžinimo užsakymo eilutės įrašas" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Eilutės įrašas neatitinka grąžinimo užsakymo" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Eilutės įrašas jau gautas" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Elementai gali būti priimami tik pagal vykdomus užsakymus" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Grąžinamas kiekis" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Eilutės kainos valiuta" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Prarasta" @@ -5718,1279 +6125,1312 @@ msgstr "Prarasta" msgid "Returned" msgstr "Grąžinta" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Vykdoma" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Grąžinimas" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Remontas" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Keitimas" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Pinigų grąžinimas" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Atmesti" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Išduota" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Vėluojantis pirkimo užsakymas" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Pirkimo užsakymas {po} dabar vėluoja" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Vėluojantis pardavimo užsakymas" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Pardavimo užsakymas {so} dabar vėluoja" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Vėluojantis grąžinimo užsakymas" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Grąžinimo užsakymas {ro} dabar vėluoja" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Pažymėta žvaigždute" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Filtruoti pagal pažymėtas kategorijas" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Gylis" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filtruoti pagal kategorijos gylį" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Aukščiausio lygio" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filtruoti pagal aukščiausio lygio kategorijas" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Kaskada" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Įtraukti sub-kategorijas į filtravimo rezultatus" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Pirminė kategorija" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Filtruoti pagal pirminę kategoriją" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Neįtraukti sub-kategorijų po nurodyta kategorija" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Turi rezultatų" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Yra variantas" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Yra versija" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Turi versijų" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "BOM galiojantis" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Surinkimo detalė gali būti testuojama" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Komponento detalė gali būti testuojama" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Naudoja" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Detalių kategorija" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Detalių kategorijos" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Numatytoji vieta" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Numatytoji vieta detalėms šioje kategorijoje" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Struktūrinė" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Detalės negali būti priskirtos struktūrinei kategorijai tiesiogiai, bet gali būti priskirtos jos subkategorijoms." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Numatytieji raktažodžiai" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Numatytieji raktažodžiai detalėms šioje kategorijoje" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Piktograma" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Piktograma (neprivaloma)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Negalite paversti šios detalių kategorijos struktūrine, nes kai kurios detalės jau jai priskirtos!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Detalių kategorijos parametro šablonas" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Numatytoji reikšmė" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Numatytoji parametro reikšmė" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Detalės" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Negalima ištrinti šios detalės, nes ji užrakinta" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Negalima ištrinti šios detalės, nes ji vis dar aktyvi" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Negalima ištrinti šios detalės, nes ji naudojama sirinkime" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Detalė „{self}“ negali būti naudojama detalių sąraše „{parent}“ (rekursyviai)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Detalė „{parent}“ naudojama detalių sąraše „{self}“ (rekursyviai)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN turi atitikti regex šabloną {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Detalė negali būti savo pačios versija" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Versijos leidžiamos tik surinkimo detalėms" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Negalima sukurti šabloninės detalės versijos" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "Pagrindinė detalė turi būti susieta su tuo pačiu šablonu" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Atsargų elementas su šiuo serijos numeriu jau egzistuoja" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN dublikatų detalių nustatymuose naudoti negalima" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Tokia detalės versija jau egzistuoja." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Detalė su tokiu pavadinimu, IPN ir versija jau egzistuoja." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Detalės negali būti priskirtos struktūrinėms detalių kategorijoms!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Detalės pavadinimas" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Yra šablonas" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Ar ši detalė yra šabloninė detalė?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Ar ši detalė yra kitos detalės variantas?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variantas iš" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Detalės aprašymas (neprivalomas)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Raktažodžiai" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Detalės raktažodžiai, skirti pagerinti matomumą paieškos rezultatuose" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Detalės kategorija" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Detalės versija arba numeris" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Versija" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Ar ši detalė yra kitos detalės versija?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Versija iš" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Kur ši detalė paprastai laikoma?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Numatytasis galiojimo laikas" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Šios detalės atsargų galiojimo laikas (dienomis)" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimalus atsargų kiekis" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Mažiausias leidžiamas atsargų kiekis" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Šios detalės matavimo vienetai" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Ar ši detalė gali būti pagaminta iš kitų detalių?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Ar ši detalė gali būti naudojama kitoms detalėms gaminti?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Ar ši detalė turi unikalių vienetų sekimą?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Ar šiai detalei gali būti priskirti bandymų rezultatai?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Ar ši detalė gali būti perkama iš išorinių tiekėjų?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Ar ši detalė gali būti parduodama klientams?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Ar ši detalė yra aktyvi?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Užrakintos detalės negali būti redaguojamos" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Ar tai virtuali detalė, pavyzdžiui, programinė įranga ar licencija?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "BOM kontrolinė suma" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Išsaugota BOM kontrolinė suma" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Detalių sąrašą patikrino" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Detalių sąrašo patikrinimo data" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Sukūręs vartotojas" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Atsakingas vartotojas už šią detalę" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Parduodamas kiekis" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Valiuta, naudojama kainų skaičiavimams kaupti" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimali BOM kaina" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Minimali komponentų detalių kaina" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maksimali BOM kaina" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Maksimali komponentų detalių kaina" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimali pirkimo kaina" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Mažiausia istorinė pirkimo kaina" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maksimali pirkimo kaina" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Didžiausia istorinė pirkimo kaina" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimali vidinė kaina" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Mažiausia kaina pagal vidinius kainų intervalus" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maksimali vidinė kaina" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Didžiausia kaina pagal vidinius kainų intervalus" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Mažiausia tiekėjo kaina" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Mažiausia detalės kaina iš išorinių tiekėjų" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Didžiausia tiekėjo kaina" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Didžiausia detalės kaina iš išorinių tiekėjų" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Mažiausia varianto kaina" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Apskaičiuota minimali variantų detalių kaina" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Didžiausia varianto kaina" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Apskaičiuota didžiausia variantų detalių kaina" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimali kaina" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Nepaisyti minimalios kainos" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maksimali kaina" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Nepaisyti maksimalios kainos" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Apskaičiuota bendra minimali kaina" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Apskaičiuota bendra maksimali kaina" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Minimali pardavimo kaina" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Mažiausia pardavimo kaina pagal kainų intervalus" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Didžiausia pardavimo kaina" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Didžiausia pardavimo kaina pagal kainų intervalus" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Mažiausia pardavimo kaina" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Mažiausia istorinė pardavimo kaina" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Didžiausia pardavimo kaina" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Didžiausia istorinė pardavimo kaina" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Detalė inventorizacijai" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Vienetų skaičius" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Atsargų įrašų skaičius inventorizacijos metu" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Bendras prieinamas atsargų kiekis inventorizacijos metu" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Data" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Inventorizacijos atlikimo data" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Minimali atsargų kaina" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Apytikslė minimali turimų atsargų kaina" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maksimali atsargų kaina" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Apytikslė maksimali turimų atsargų kaina" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Detalės kainų intervalai pardavimui" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Detalės bandymų šablonas" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Netinkamas šablono pavadinimas - turi būti bent vienas raidinis ar skaitinis simbolis" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Bandymų šablonus galima kurti tik testuojamoms detalėms" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Detalė jau turi bandymų šabloną su tokiu pačiu raktu" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Bandymo pavadinimas" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Įveskite bandymo pavadinimą" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Bandymo raktas" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Supaprastintas bandymo raktas" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Bandymo aprašymas" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Įveskite šio bandymo aprašymą" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Ar šis bandymas įjungtas?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Privalomas" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Ar šį bandymą būtina išlaikyti?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Reikalauja reikšmės" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Ar šiam bandymui reikia įvesti reikšmę pridedant rezultatą?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Reikalauja priedo" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Ar šiam bandymui reikia pridėti failą su rezultatu?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Galimi pasirinkimai šiam bandymui (atskirti kableliais)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOM elemento keisti negalima - surinkimas užrakintas" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM elemento keisti negalima - varianto surinkimas užrakintas" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Pasirinkite pirminę detalę" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Pavaldi detalė" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Pasirinkite detalę, naudojamą BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "BOM reikalingas šios detalės kiekis" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Šis BOM elementas yra pasirenkamas" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Šis BOM elementas yra sunaudojamas (nesekamas gamybos užsakymuose)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "BOM nuoroda" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "BOM pastabos" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Kontrolinė suma" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "BOM eilutės kontrolinė suma" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Patvirtinta" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Šis BOM elementas patvirtintas" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Paveldima" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Šį BOM elementą paveldi variantų sąrašai" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Šiam BOM elementui galima naudoti variantinių detalių atsargas" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Sekamoms detalėms kiekis turi būti sveikasis skaičius" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Turi būti nurodyta pavaldi detalė" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "BOM elemento pakaitalas" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Pakaitinė detalė negali būti tokia pati kaip pagrindinė detalė" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Pagrindinis BOM elementas" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Pakaitinė detalė" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Detalė 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Detalė 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Pasirinkite susijusią detalę" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Pastaba šiam ryšiui" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Detalių ryšio negalima sukurti tarp detalės ir jos pačios" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Toks ryšys jau egzistuoja" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Pagrindinė kategorija" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Pagrindinė detalių kategorija" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Subkategorijos" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Rezultatai" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Rezultatų skaičius, susietas su šiuo šablonu" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Šio atsargų elemento pirkimo valiuta" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Failas nėra paveikslėlis" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Pradinė detalė" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Pasirinkite pradinę detalę kopijavimui" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kopijuoti paveikslėlį" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Kopijuoti paveikslėlį iš pradinės detalės" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Kopijuoti BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Kopijuoti komplektavimo žiniaraštį iš pradinės detalės" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Kopijuoti parametrų duomenis iš pradinės detalės" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Kopijuoti pastabas" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Kopijuoti pastabas iš pradinės detalės" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Pradinis atsargų kiekis" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Nurodykite pradinį atsargų kiekį šiai detalei. Jei kiekis nulis - atsargos nebus pridėtos." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Pradinė atsargų vieta" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Nurodykite pradinę atsargų vietą šiai detalei" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Pasirinkite tiekėją (arba palikite tuščią, jei nenorite nurodyti)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Pasirinkite gamintoją (arba palikite tuščią, jei nenorite nurodyti)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Gamintojo detalės numeris" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Pasirinkta įmonė nėra galiojantis tiekėjas" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Pasirinkta įmonė nėra galiojantis gamintojas" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Detalė su šiuo gamintojo numeriu (MPN) jau egzistuoja" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Tiekėjo detalė su šiuo SKU jau egzistuoja" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Kategorijos pavadinimas" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Surinkimas" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Atsargos" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Versijos" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Bendros atsargos" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Nepriskirtos atsargos" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Variantų atsargos" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Kopijuoti detalę" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Kopijuoti pradinius duomenis iš kitos detalės" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kopijuoti paveikslėlį" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Kopijuoti paveikslėlį iš pradinės detalės" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Kopijuoti BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Kopijuoti komplektavimo žiniaraštį iš pradinės detalės" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Kopijuoti pastabas" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Kopijuoti pastabas iš pradinės detalės" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Pradinės atsargos" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Sukurti detalę su pradiniu atsargų kiekiu" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Tiekėjo informacija" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Pridėti pradinę tiekėjo informaciją šiai detalei" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Kopijuoti kategorijos parametrus" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Kopijuoti parametrų šablonus iš pasirinktos detalių kategorijos" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Esamas paveikslėlis" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Esamos detalės paveikslėlio failo pavadinimas" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Paveikslėlio failas neegzistuoja" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Patvirtinti visą komplektavimo žiniaraštį" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Galima surinkti" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Mažiausia kaina" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Pakeisti apskaičiuotą mažiausią kainą" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Mažiausios kainos valiuta" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Didžiausia kaina" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Pakeisti apskaičiuotą didžiausią kainą" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Didžiausios kainos valiuta" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Atnaujinti" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Atnaujinti šios detalės kainodarą" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Nepavyko konvertuoti iš nurodytų valiutų į {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Mažiausia kaina negali būti didesnė už didžiausią kainą" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Didžiausia kaina negali būti mažesnė už mažiausią kainą" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Pasirinkite pirminį surinkimą" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Pasirinkite komponentinę detalę" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Pasirinkite detalę, iš kurios kopijuoti BOM" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Pašalinti esamus duomenis" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Pašalinti esamus BOM elementus prieš kopijuojant" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Įtraukti paveldėtus" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Įtraukti BOM elementus, paveldėtus iš šabloninių detalių" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Praleisti netinkamas eilutes" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Įjunkite šią parinktį, jei norite praleisti netinkamas eilutes" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Kopijuoti pakaitines detales" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopijuoti pakaitines detales, kai kopijuojami BOM elementai" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Perspėjimas apie mažas atsargas" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Galimas atsargų kiekis detalei {part.name} nukrito žemiau nustatyto minimalaus lygio" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "Pavyzdys" msgid "Installed" msgstr "Įdiegtas" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Įskiepis negali būti ištrintas, nes šiuo metu yra aktyvus" @@ -7023,23 +7463,23 @@ msgstr "Nenurodytas joks veiksmas" msgid "No matching action found" msgstr "Atitinkantis veiksmas nerastas" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Brūkšninio kodo duomenims atitikmens nerasta" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Rastas atitikmuo brūkšninio kodo duomenims" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Modelis nepalaikomas" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Modelio egzempliorius nerastas" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Brūkšninis kodas atitinka esamą elementą" @@ -7055,51 +7495,67 @@ msgstr "Tiekėjo detalių atitikmenų nerasta" msgid "Multiple matching supplier parts found" msgstr "Rastos kelios atitinkančios tiekėjo detalės" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Brūkšninio kodo duomenims atitinkančio įskiepio nerasta" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Atitinkanti tiekėjo detalė" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Prekė jau buvo priimta" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Tiekėjo brūkšniniam kodui įskiepis nerastas" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Rasti keli atitinkantys eilutės įrašai" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Atitinkančios eilutės įrašo nerasta" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Nepateiktas pardavimo užsakymas" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Brūkšninis kodas neatitinka jokio esamo atsargų elemento" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Atsargų elementas neatitinka eilutės įrašo" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Nepakanka atsargų" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Atsargų elementas priskirtas pardavimo užsakymui" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Nepakanka informacijos" @@ -7108,23 +7564,23 @@ msgstr "Nepakanka informacijos" msgid "Found matching item" msgstr "Rastas atitinkantis elementas" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Tiekėjo detalė neatitinka eilutės įrašo" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Eilutės įrašas jau užbaigtas" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Norint priimti eilutės įrašą, reikia daugiau informacijos" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Gauta pirkimo užsakymo eilutė" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Nepavyko priimti eilutės įrašo" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Suteikia vietinį brūkšninių kodų palaikymą" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Trumpo brūkšninio kodo priešdėlis" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Pritaikykite trumpųjų brūkšninių kodų priešdėlį - naudinga, kai naudojami keli InvenTree egzemplioriai" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL, naudojamas pranešimams siųsti į Slack kanalą" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Atidaryti nuorodą" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Suteikia vidinį palaikymą PDF etikečių spausdinimui" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Derinimo režimas" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Įjungti derinimo režimą - grąžina neapdorotą HTML vietoje PDF" @@ -7653,55 +8117,55 @@ msgstr "paskutinį kartą naudota" msgid "Options" msgstr "Parinktys" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Etikečių lapo puslapio dydis" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Praleisti etiketes" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Spausdinant etikečių lapą, praleisti nurodytą etikečių skaičių" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Rėmelis" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Spausdinti rėmelį aplink kiekvieną etiketę" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Gulsčias" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Spausdinti etikečių lapą gulsčiu režimu" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Puslapio paraštė" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Paraštė aplink puslapį (mm)" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree etikečių lapo spausdintuvas" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Išdėsto kelias etiketes viename lape" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Etiketė per didelė šiam puslapio dydžiui" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Etikečių nesugeneruota" @@ -7753,77 +8217,85 @@ msgstr "Suteikia palaikymą TME brūkšninių kodų nuskaitymui" msgid "The Supplier which acts as 'TME'" msgstr "Tiekėjas, veikiantis kaip 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Įskiepių diegimas išjungtas" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Įskiepis sėkmingai įdiegtas" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Įskiepis įdiegtas į {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Įskiepis neaptiktas registre" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Įskiepis nėra supakuotas įskiepis" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Įskiepio paketo pavadinimas nerastas" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Tik personalo vartotojai gali tvarkyti įskiepius" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Įskiepių šalinimas išjungtas" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Įskiepis negali būti pašalintas, nes šiuo metu yra aktyvus" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Įskiepis neįdiegtas" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Įskiepio diegimas nerastas" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Įskiepis sėkmingai pašalintas" @@ -7871,25 +8343,25 @@ msgstr "Privalomas įskiepis" msgid "Package Plugin" msgstr "Pakuotės įskiepis" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Įskiepis" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Autorius nerastas" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Įskiepis '{p}' nesuderinamas su dabartine InvenTree versija {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Įskiepiui reikalinga bent versija {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Įskiepiui reikalinga ne aukštesnė nei versija {v}" @@ -8114,176 +8586,184 @@ msgstr "Ištrinti konfigūraciją" msgid "Delete the plugin configuration from the database" msgstr "Ištrinti įskiepio konfigūraciją iš duomenų bazės" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Elementai" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Įskiepis nerastas" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Įskiepis nepalaiko etikečių spausdinimo" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Neleistini etiketės matmenys" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Šablonui nepateikti galimi elementai" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Letter" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Šablono failas tokiu pavadinimu jau egzistuoja" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Šablono pavadinimas" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Šablono aprašymas" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Versijos numeris (didinamas automatiškai)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Pridėti prie modelio spausdinant" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Išsaugoti ataskaitą kaip priedą susietam modelio egzemplioriui spausdinimo metu" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Failo vardo šablonas" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Šablonas failų vardų generavimui" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Šablonas įjungtas" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Šablonui skirtas modelio tipas" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtrai" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Šablono užklausos filtrai (kableliais atskirtas key=value porų sąrašas)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Šablono failas" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Puslapio dydis PDF ataskaitoms" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Rodyti ataskaitą gulsčiai" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Ataskaita sugeneruota iš šablono {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Klaida generuojant ataskaitą" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Plotis [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Etiketės plotis, nurodytas milimetrais" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Aukštis [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Etiketės aukštis, nurodytas milimetrais" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Klaida spausdinant etiketes" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Fragmentas" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Ataskaitos fragmento failas" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Fragmento failo aprašymas" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Išteklius" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Ataskaitos ištekliaus failas" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Ištekliaus failo aprašymas" @@ -8291,23 +8771,23 @@ msgstr "Ištekliaus failo aprašymas" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Pasirinkite ataskaitos šabloną" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Elementų pirminių raktų sąrašas, įtrauktinas į ataskaitą" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Pasirinkite etiketės šabloną" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Spausdinimo įskiepis" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Pasirinkite įskiepį etikečių spausdinimui" @@ -8338,13 +8818,10 @@ msgstr "Reikalingos medžiagos" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Detalės vaizdas" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Išduota" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Reikalinga objektui" @@ -8380,8 +8857,8 @@ msgstr "Iš viso" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serijos numeris" @@ -8405,7 +8882,7 @@ msgstr "Atsargų elemento bandymo ataskaita" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Sumontuoti elementai" @@ -8438,810 +8915,922 @@ msgstr "Nėra rezultato (privaloma)" msgid "No result" msgstr "Nėra rezultato" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Paveikslėlio failas nerastas" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "Žyma part_image reikalauja detalės (Part) egzemplioriaus" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "Žyma company_image reikalauja įmonės (Company) egzemplioriaus" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Filtruoti pagal vietos gylį" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Filtruoti pagal aukščiausio lygio vietas" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Įtraukti sub-vietas į filtravimo rezultatus" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Pirminė vieta" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filtruoti pagal pirminę vietą" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Detalės pavadinimas (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Detalės pavadinimas turi (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Detalės pavadinimas (reguliarioji išraiška)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "Detalės IPN (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "Detalės IPN turi (neskiria didžiųjų ir mažųjų raidžių)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "Detalės IPN (reguliarioji išraiška)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Mažiausias kiekis" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Didžiausias kiekis" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Būsenos kodas" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Išorinė vieta" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Sunaudota gamybos užsakyme" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Sumontuota kitame atsargų elemente" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Detalių medis" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Atnaujinta iki" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Atnaujinta po" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Inventorizacija iki" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Inventorizacija po" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Galiojimo data iki" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Galiojimo data po" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Pasenusi" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Reikalingas kiekis" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Turi būti pateikta galiojanti detalė" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Nurodyta tiekėjo detalė neegzistuoja" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Tiekėjo detalė turi nustatytą pakuotės dydį, bet nepažymėtas požymis use_pack_size" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Serijos numeriai negali būti pateikti detalei, kurios negalima sekti" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Atsargų vietos tipas" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Atsargų vietos tipai" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Numatytoji piktograma visoms vietoms, kurioms nepaskirta piktograma (neprivaloma)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Atsargų vieta" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Atsargų vietos" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Savininkas" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Pasirinkite savininką" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Atsargos negali būti tiesiogiai patalpintos į struktūrines atsargų vietas, bet gali būti patalpinti į jų sub-vietas." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Išorinė" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Tai yra išorinė atsargų vieta" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Vietos tipas" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Šios vietos atsargų vietos tipas" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Negalite padaryti šios atsargų vietos struktūrine, nes joje jau yra atsargų!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Turi būti nurodyta detalė" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Atsargos negali būti patalpintos į struktūrines atsargų vietas!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Atsargų elementas negali būti sukurtas virtualioms detalėms" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Detalės tipas ('{self.supplier_part.part}') turi būti {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Elemento, turinčio serijos numerį, kiekis turi būti 1" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Serijos numeris negali būti nustatytas, jei kiekis didesnis nei 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Elementas negali priklausyti pats sau" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Elementas turi turėti surinkimo nuorodą, jei is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Surinkimo nuoroda nenurodo į tą pačią detalę" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Pirminis atsargų elementas" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Pagrindinė detalė" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Pasirinkite atitinkančią tiekėjo detalę šiam atsargų elementui" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Kur yra šis atsargų elementas?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Pakuotė, kurioje laikomas šis atsargų elementas" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Sumontuotas į" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Ar šis elementas yra sumontuotas kitame elemente?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Šio elemento serijos numeris" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Šio atsargų elemento partijos kodas" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Atsargų kiekis" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Surinkimo šaltinis" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Surinkimas šiam atsargų elementui" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Sunaudojo" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Gamybos užsakymas, kuris sunaudojo šį atsargų elementą" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Pirkimo užsakymo šaltinis" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Pirkimo užsakymas šiam atsargų elementui" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Pardavimo užsakymo paskirtis" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Atsargų elemento galiojimo data. Po šios datos atsargos bus laikomos pasibaigusiomis" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Ištrinti išnaudojus" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Ištrinti šį atsargų elementą, kai atsargos bus išnaudotos" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Vieneto pirkimo kaina pirkimo metu" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Konvertuota į detalę" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Detalė nenustatyta kaip sekama" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Kiekis turi būti sveikasis skaičius" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Kiekis negali viršyti galimų atsargų kiekio ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Serijos numeriai turi būti pateikti sąraše" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Kiekis nesutampa su serijos numeriais" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Bandomasis šablonas neegzistuoja" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Atsargų elementas buvo priskirtas pardavimo užsakymui" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Atsargų elementas sumontuotas kitame elemente" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Atsargų elementas turi kitų elementų" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Atsargų elementas buvo priskirtas klientui" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Atsargų elementas šiuo metu gaminamas" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Su serijos numeriais pažymėtų atsargų sujungti negalima" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Pasikartojantys atsargų elementai" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Atsargų elementai turi būti susiję su ta pačia detale" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Atsargų elementai turi būti susiję su ta pačia tiekėjo detale" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Atsargų būsenos kodai turi sutapti" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Atsargų elemento negalima perkelti, nes jo nėra sandėlyje" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Atsargų elemento sekimas" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Įrašo pastabos" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Atsargų elemento bandymo rezultatas" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Šiam bandymui turi būti pateikta reikšmė" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Šiam bandymui turi būti įkeltas priedas" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "Netinkama reikšmė šiam bandymui" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Bandymo rezultatas" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Bandymo išvesties reikšmė" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Bandymo rezultato priedas" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Bandymo pastabos" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Bandymų stotis" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "Bandymų stoties identifikatorius, kurioje atliktas bandymas" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Pradėta" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Bandymo pradžios laiko žyma" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Pabaigta" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Bandymo pabaigos laiko žyma" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Sugeneruotas partijos kodas" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Pasirinkite gamybos užsakymą" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Pasirinkite atsargų elementą partijos kodui sugeneruoti" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Pasirinkite vietą partijos kodui sugeneruoti" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Pasirinkite detalę partijos kodui sugeneruoti" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Pasirinkite pirkimo užsakymą" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Įveskite kiekį partijos kodui" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Sugeneruotas serijos numeris" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Pasirinkite detalę serijos numeriui sugeneruoti" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Kiekis serijos numerių, kuriuos reikia sugeneruoti" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Bandymo šablonas šiam rezultatui" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "Turi būti pateiktas šablono ID arba bandymo pavadinimas" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "Bandymo pabaigos laikas negali būti ankstesnis nei pradžios laikas" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Pirminis elementas" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Pirminis atsargų elementas" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Naudoti pakuotės dydį pridedant: nurodytas kiekis yra pakuočių skaičius" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Įveskite serijos numerius naujiems elementams" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Tiekėjo detalės numeris" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Nebegaliojantis" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Antriniai elementai" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Sekami elementai" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Šio atsargų elemento pirkimo kaina, vienetui arba pakuotei" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Įveskite atsargų elementų, kuriuos reikia serializuoti, skaičių" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Kiekis negali viršyti galimų atsargų kiekio ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Paskirties atsargų vieta" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Šiai detalei negali būti priskirti serijos numeriai" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Serijos numeriai jau egzistuoja" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Pasirinkite atsargų elementą montavimui" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Montuojamas kiekis" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Įveskite montuojamų elementų kiekį" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Pridėkite operacijos pastabą (neprivaloma)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Montuojamas kiekis turi būti bent 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Atsargų elementas nepasiekiamas" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Pasirinktos detalės nėra komplektavimo žiniaraštyje" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Montuojamas kiekis negali viršyti turimo kiekio" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Paskirties vieta išmontuotam elementui" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Pasirinkite detalę, į kurią konvertuoti atsargų elementą" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Pasirinkta detalė netinkama konvertavimui" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Negalima konvertuoti atsargų elemento, kuriam priskirta tiekėjo detalė" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Atsargų elemento būsenos kodas" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Pasirinkite detalę, į kurią konvertuoti atsargų elementą" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Pasirinkta detalė netinkama konvertavimui" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Negalima konvertuoti atsargų elemento, kuriam priskirta tiekėjo detalė" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Pasirinkite atsargų elementus būsenai pakeisti" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Nepasirinkti jokie atsargų elementai" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Sub-vietos" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Pirminė atsargų vieta" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Detalė turi būti parduodama" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Elementas priskirtas pardavimo užsakymui" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Elementas priskirtas gamybos užsakymui" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Klientas, kuriam priskiriami atsargų elementai" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Pasirinkta įmonė nėra klientas" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Atsargų priskyrimo pastabos" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Turi būti pateiktas atsargų elementų sąrašas" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Atsargų sujungimo pastabos" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Leisti skirtingus tiekėjus" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Leisti sujungti atsargų elementus su skirtingomis tiekėjų detalėmis" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Leisti skirtingas būsenas" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Leisti sujungti atsargų elementus su skirtingais būsenos kodais" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Turi būti pateikti bent du atsargų elementai" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Be pakeitimų" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Atsargų elemento pirminio rakto reikšmė" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Atsargų elemento nėra sandėlyje" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Atsargų operacijos pastabos" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Atsargų operacijos pastabos" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Kitas serijos numeris" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Ankstesnis serijos numeris" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Sujungti atsargų elementai" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Konvertuota į variantą" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Sukurtas gamybos užsakymo rezultatas" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Gamybos užsakymo rezultatas užbaigtas" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Gamybos užsakymo rezultatas atmestas" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Sunaudota gamybos užsakyme" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Išsiųsta pagal pardavimo užsakymą" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Gauta pagal pirkimo užsakymą" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Grąžinta pagal grąžinimo užsakymą" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Išsiųsta klientui" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Grąžinta iš kliento" @@ -9527,19 +10124,19 @@ msgstr "Vartotojai" msgid "Select which users are assigned to this group" msgstr "Pasirinkite, kurie vartotojai priskirti šiai grupei" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Asmeninė informacija" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Leidimai" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Svarbios datos" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Raktas buvo atšauktas" @@ -9547,279 +10144,283 @@ msgstr "Raktas buvo atšauktas" msgid "Token has expired" msgstr "Raktas nebegalioja" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API prieigos raktas" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API prieigos raktai" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Rakto pavadinimas" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Pasirinktas rakto pavadinimas" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Rakto galiojimo data" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Paskutinį kartą naudotas" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Paskutinis rakto naudojimo laikas" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Atšauktas" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Leidimų rinkinys" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Peržiūra" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Leidimas peržiūrėti objektus" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Pridėti" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Leidimas pridėti objektus" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Keisti" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Leidimas redaguoti objektus" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Ištrinti" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Leidimas ištrinti objektus" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Botas" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Vidinis" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Svečias" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Kalba" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Pageidaujama vartotojo kalba" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Tema" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Žiniatinklio sąsajos nustatymai (JSON formatu) - neredaguoti rankiniu būdu!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Valdikliai" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Prietaisų skydelio valdiklių nustatymai (JSON formatu) - neredaguoti rankiniu būdu!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Rodomas vardas" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Pasirinktas vartotojo rodomas vardas" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Pareigos" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Pagrindinės pareigos arba darbo pavadinimas" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Vartotojo būsenos žinutė" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Vartotojo buvimo vietos informacija" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "Vartotojas aktyviai naudoja sistemą" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Pageidaujama vartotojo kontaktinė informacija" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Vartotojo tipas" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "Kokio tipo tai vartotojas?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organizacija" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Pagrindinė vartotojo organizacija / priklausomybė" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Pagrindinė grupė" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Pagrindinė vartotojo grupė" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Administratorius" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Pirkimo užsakymai" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Pardavimo užsakymai" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Grąžinimo užsakymai" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Vartotojo vardas" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Vardas" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Vartotojo vardas" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Pavardė" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Vartotojo pavardė" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Vartotojo el. pašto adresas" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Supervartotojas" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Ar šis vartotojas yra supervartotojas" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Ar ši vartotojo paskyra yra aktyvi" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Tik supervartotojas gali keisti šį lauką" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Neturite leidimo kurti vartotojų" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Jūsų paskyra sukurta." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Prisijungimui naudokite slaptažodžio atstatymo funkciją" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Sveiki atvykę į InvenTree" diff --git a/src/backend/InvenTree/locale/lv/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/lv/LC_MESSAGES/django.po index c52edb68aa..848a786bd7 100644 --- a/src/backend/InvenTree/locale/lv/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/lv/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Latvian\n" "Language: lv_LV\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API galapunkts nav atrasts" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Lietotājam nav atļaujas, lai apskatītu šo modeli" @@ -65,150 +69,155 @@ msgstr "E-pasta adreses apstiprinājums" msgid "You must type the same email each time." msgstr "Katru reizi jāievada viena un tā pati e-pasta adrese." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Norādītā primārā e-pasta adrese nav derīga." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Norādītais e-pasta domēns nav apstiprināts." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Norādīta nederīga vienība ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nav norādīta vērtība" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Nevarēja konvertēt {original} par {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Norādītais daudzums nav derīgs" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Ievadiet datumu" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Piezīmes" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Vērtība '{name}' neparādās vajadzīgajā formātā" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Norādītā vērtība neatbilst nepieciešamajam formātam: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Tukša sērijas numura rinda" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Atkārtojas sērijas numurs" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Grupas diapazons {group} pārsniedz pieļaujamo daudzumu ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Netika atrasts neviens sērijas numurs" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Noņemiet HTML tagus no šīs vērtības" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Savienojuma kļūda" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Serveris atbildēja ar nederīgu statusa kodu" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Radās izņēmums" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Serveris atbildēja ar nederīgu Content-Length vērtību" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Attēla izmērs ir pārāk liels" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Attēla lejupielāde pārsniedz maksimālo izmēru" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Attālais serveris atgrieza tukšu atbildi" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Norādītajā URL nav derīgs attēla fails" @@ -216,159 +225,203 @@ msgstr "Norādītajā URL nav derīgs attēla fails" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5718,1279 +6125,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/nl/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/nl/LC_MESSAGES/django.po index d57e77b082..2ec907ae86 100644 --- a/src/backend/InvenTree/locale/nl/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/nl/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API eindpunt niet gevonden" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "Lijst met items of filters moet worden opgegeven voor bulk bewerking" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Items moeten worden opgegeven als een lijst" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Ongeldige items lijst verstrekt" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Alles filteren alleen gebruiken met True" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Geen items die overeenkomen met de opgegeven criteria" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Geen gegevens verstrekt" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Dit veld moet uniek zijn" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Gebruiker heeft geen rechten om dit model te bekijken" @@ -65,150 +69,155 @@ msgstr "E-mailadres bevestiging" msgid "You must type the same email each time." msgstr "Er moet hetzelfde e-mailadres ingevoerd worden." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Het opgegeven primaire e-mailadres is ongeldig." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Het ingevoerde e-maildomein is niet goedgekeurd." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Ongeldige eenheid opgegeven ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Geen waarde opgegeven" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "{original} kon niet worden omgezet naar {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Ongeldige hoeveelheid ingevoerd" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Error details kunnen worden gevonden in het admin scherm" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Voer datum in" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Ongeldige decimale waarde" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Opmerkingen" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Waarde '{name}' verschijnt niet in patroonformaat" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Opgegeven waarde komt niet overeen met vereist patroon: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Kan niet meer dan 1000 items tegelijk serienummers geven." -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Leeg serienummer" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Duplicaat serienummer" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ongeldige groep: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Groepsbereik {group} overschrijdt toegestane hoeveelheid ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Geen serienummers gevonden" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Hoeveelheid van unieke serienummers ({n}) moet overeenkomen met de hoeveelheid ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Verwijder HTML tags van deze waarde" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Gegevens bevatten verboden markdown inhoud" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "Ongeldige URL: geen hostnaam" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "Ongeldige URL: hostnaam kon niet worden opgelost" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "URL-punten naar een privé of gereserveerd IP-adres" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "Te veel doorverwijzingen" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Verbindingsfout" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Server reageerde met ongeldige statuscode" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Uitzondering opgetreden" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Server reageerde met ongeldige Content-Length waarde" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Afbeeldingsformaat is te groot" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Beelddownload overschrijdt de maximale grootte" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Externe server heeft lege reactie teruggegeven" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Opgegeven URL is geen geldig afbeeldingsbestand" @@ -216,159 +225,203 @@ msgstr "Opgegeven URL is geen geldig afbeeldingsbestand" msgid "Log in to the app" msgstr "Log in op de app" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Schakel tweestapsverificatie in voordat je iets anders kunt doen." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Fout bij uitvoeren plug-in validatie" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata moeten een python dict object zijn" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Plug-in metadata" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON metadata veld, voor gebruik door externe plugins" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Onjuist opgemaakt patroon" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Onbekende opmaaksleutel gespecificeerd" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Vereiste opmaaksleutel ontbreekt" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Referentieveld mag niet leeg zijn" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referentie moet overeenkomen met verplicht patroon" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referentienummer is te groot" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Ongeldige keuze" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Naam" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Omschrijving" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Omschrijving (optioneel)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Pad" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Dubbele namen kunnen niet bestaan onder hetzelfde bovenliggende object" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown notitie (optioneel)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Streepjescode gegevens" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Streepjescode van derden" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash van Streepjescode" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Unieke hash van barcode gegevens" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Bestaande barcode gevonden" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Serverfout" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Er is een fout gelogd door de server." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Afbeelding" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Moet een geldig nummer zijn" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Selecteer valuta uit beschikbare opties" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Dit veld mag niet nul zijn." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Ongeldige waarde" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Ongeldig inhoudstype" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Inhoudstype niet gevonden" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "Content type komt niet overeen met de vereiste mixin klasse" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Parameters kopiëren" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Kopieer regels" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Kopieer regelitems uit de oorspronkelijke bestelling" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Extra regels kopiëren" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Extra regelitems van de oorspronkelijke bestelling kopiëren" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabisch" @@ -521,46 +574,48 @@ msgstr "Chinees (vereenvoudigd)" msgid "Chinese (Traditional)" msgstr "Chinees (traditioneel)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Update beschikbaar" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Een update voor Inventree is beschikbaar" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Ongeldige fysieke eenheid" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Geen geldige valutacode" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Status van bestelling" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Bovenliggende Productie" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Inclusief varianten" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Inclusief varianten" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Inclusief varianten" msgid "Part" msgstr "Onderdeel" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Categorie" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Voorouderlijke bouw" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Toegewezen aan mij" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Toegewezen aan" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Gemaakt voor" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Gemaakt na" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Heeft een startdatum" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Vervaldatum voor" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Vervaldatum na" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Heeft doel datum" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Doel datum voor" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Doel datum na" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Voltooid voor" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Voltooid na" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Min. datum" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Max. datum" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Boomstructuur uitsluiten" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Productie moet geannuleerd worden voordat het kan worden verwijderd" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Verbruiksartikelen" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Optioneel" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Samenstelling" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Gevolgd" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testbaar" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Openstaande order" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Toegewezen" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Verbruikt" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Beschikbaar" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "In bestelling" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "Build niet gevonden" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Productieorder" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Locatie" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Uitvoer" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Filter op uitvoer standaard item ID. Gebruik 'null' om niet geïnstalleerde build items te vinden." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Productieorders" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Assemblage stuklijst is niet gevalideerd" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Bouw bestelling kan niet worden aangemaakt voor een inactief onderdeel" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Maken opdracht kan niet worden gemaakt voor een ontgrendeld onderdeel" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Bestellingen bouwen kan alleen extern worden vervuld voor aankochte onderdelen" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Verantwoorde gebruiker of groep moet worden opgegeven" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Bouworder onderdeel kan niet worden gewijzigd" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Doeldatum moet na startdatum zijn" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Productieorderreferentie" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referentie" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Korte beschrijving van de build (optioneel)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Productie-opdracht waar dit product aan is toegewezen" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Selecteer onderdeel om te produceren" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Verkooporder Referentie" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Productieopdracht waar dit productie aan is toegewezen" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Bronlocatie" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Selecteer de locatie waar de voorraad van de productie vandaan moet komen (laat leeg om vanaf elke standaard locatie te nemen)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Externe bouw" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Deze bouw opdracht is extern uitgevoerd" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Bestemmings Locatie" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Selecteer locatie waar de voltooide items zullen worden opgeslagen" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Productiehoeveelheid" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Aantal voorraaditems om te produceren" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Voltooide voorraadartikelen" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Aantal voorraadartikelen die zijn voltooid" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Productiestatus" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Productiestatuscode" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Batchcode" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Batchcode voor deze productieuitvoer" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Aanmaakdatum" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Bouw start datum" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Geplande startdatum voor deze bestelling" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Verwachte opleveringsdatum" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Doeldatum voor productie voltooiing. Productie zal achterstallig zijn na deze datum." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Opleveringsdatum" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "voltooid door" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Uitgegeven door" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Gebruiker die de productieorder heeft gegeven" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Verantwoordelijke" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Gebruiker of groep verantwoordelijk voor deze bouwopdracht" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Externe Link" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link naar externe URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Bouw prioriteit" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Prioriteit van deze bouwopdracht" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Project code" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Project code voor deze build order" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Kan de bouwopdracht niet voltooien zolang onderliggende bouwopdrachten nog openstaan" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Kan de bouwopdracht niet voltooien zolang de output onvolledig is" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Verwijderen van taak om toewijzingen te voltooien mislukt" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Productieorder {build} is voltooid" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Een productieorder is voltooid" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Serienummers moeten worden opgegeven voor traceerbare onderdelen" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Geen productie uitvoer opgegeven" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Productie uitvoer is al voltooid" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Productuitvoer komt niet overeen met de Productieorder" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Hoeveelheid moet groter zijn dan nul" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Hoeveelheid kan niet groter zijn dan aantal" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "Build output heeft niet alle vereiste tests doorstaan" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Build output {serial} heeft niet alle vereiste tests doorstaan" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "Voorraadproducten zijn nog in productie" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Kan een build uitvoer niet gedeeltelijk voltooien met de toegewezen items" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Beschikbare hoeveelheid ({q}) overschreden" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Bouw order regel item" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Bouw object" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Bouw object" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Hoeveelheid" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Vereiste hoeveelheid voor bouwopdracht" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Aantal van verbruikte voorraad" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Productieartikel moet een productieuitvoer specificeren, omdat het hoofdonderdeel gemarkeerd is als traceerbaar" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Geselecteerde voorraadartikelen komen niet overeen met de BOM-regel" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "Toegewezen hoeveelheid moet groter zijn dan nul" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Hoeveelheid moet 1 zijn voor geserialiseerde voorraad" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Toegewezen hoeveelheid ({q}) mag de beschikbare voorraad ({a}) niet overschrijden" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Voorraad item is te veel toegewezen" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Voorraadartikel" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Bron voorraadartikel" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Voorraad hoeveelheid toe te wijzen aan productie" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Installeren in" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Bestemming voorraadartikel" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Bouw level" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Onderdeel naam" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Productieuitvoer" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Productieuitvoer komt niet overeen met de bovenliggende productie" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Uitvoeronderdeel komt niet overeen met productieorderonderdeel" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Deze productieuitvoer is al voltooid" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Deze productieuitvoer is niet volledig toegewezen" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Voer hoeveelheid in voor productie uitvoer" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Hoeveelheid als geheel getal vereist voor traceerbare onderdelen" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Geheel getal vereist omdat de stuklijst traceerbare onderdelen bevat" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Serienummers" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Voer serienummers in voor productieuitvoeren" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Voorraad locatie voor project uitvoer" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Serienummers automatisch toewijzen" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Vereiste artikelen automatisch toewijzen met overeenkomende serienummers" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "De volgende serienummers bestaan al of zijn ongeldig" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Een lijst van productieuitvoeren moet worden verstrekt" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Voorraadlocatie voor geannuleerde outputs" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Toewijzingen weggooien" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Verwijder alle voorraadtoewijzingen voor geannuleerde outputs" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Reden voor annulering van bouworder(s)" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Locatie van voltooide productieuitvoeren" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Incomplete Toewijzing Accepteren" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Voltooi de uitvoer als de voorraad niet volledig is toegewezen" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Toegewezen voorraad gebruiken" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Verbruik elke voorraad die al is toegewezen aan deze build" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Verwijder Incomplete Uitvoeren" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Verwijder alle productieuitvoeren die niet zijn voltooid" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Niet toegestaan" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Accepteer zoals geconsumeerd onder deze bouwopdracht" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "De-alloceren voordat deze bouwopdracht voltooid wordt" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Overgealloceerde voorraad" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Hoe wilt u omgaan met extra voorraaditems toegewezen aan de bouworder" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Sommige voorraadartikelen zijn overalloceerd" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Accepteer Niet-toegewezen" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Accepteer dat voorraadartikelen niet volledig zijn toegewezen aan deze productieorder" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Vereiste voorraad is niet volledig toegewezen" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Accepteer Onvolledig" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Accepteer dat het vereist aantal productieuitvoeren niet is voltooid" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Vereiste productiehoeveelheid is voltooid" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Bouw opdracht heeft open sub bouw orders" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Bouwen moet in de productiestatus staan" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Productieorder heeft onvolledige uitvoeren" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Productielijn" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Productieuitvoer" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Productieuitvoer moet naar dezelfde productie wijzen" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Bouw lijn-item" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part moet naar hetzelfde onderdeel wijzen als de productieorder" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Artikel moet op voorraad zijn" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Beschikbare hoeveelheid ({q}) overschreden" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Productieuitvoer moet worden opgegeven voor de toewijzing van gevolgde onderdelen" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Productieuitvoer kan niet worden gespecificeerd voor de toewijzing van niet gevolgde onderdelen" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Allocaties voor artikelen moeten worden opgegeven" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Voorraadlocatie waar onderdelen afkomstig zijn (laat leeg om van elke locatie te nemen)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Locatie uitsluiten" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Voorraadartikelen van deze geselecteerde locatie uitsluiten" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Uitwisselbare voorraad" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Voorraadartikelen op meerdere locaties kunnen uitwisselbaar worden gebruikt" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Vervangende Voorraad" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Toewijzing van vervangende onderdelen toestaan" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Optionele Items" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Alloceer optionele BOM items om bestelling te bouwen" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "Alle artikelen" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "Niet Gevolgde items" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "Gevolgde Items" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "Item Type" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "Selecteer item type om automatisch toe te wijzen" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "Voorraad prioriteit" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "BOM referentie" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "BOM onderdeel ID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "BOM onderdeel naam" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "Instaleeren Op" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Bouwen" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Leveranciersonderdeel" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Toegewezen hoeveelheid" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Bouw referentie" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Naam categorie onderdeel" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Volgbaar" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Overgenomen" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Varianten toestaan" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Stuklijstartikel" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "In productie" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Gepland om te bouwen" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Externe voorraad" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Beschikbare Voorraad" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Beschikbare vervanging voorraad" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Beschikbare varianten voorraad" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "Verbruikte hoeveelheid overschrijdt toegewezen hoeveelheid" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Optionele notities voor voorraadverbruik" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "Het bouwelement moet verwijzen naar de juiste bouwopdracht" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Dupliceer build item allocatie" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "Build line moet verwijzen naar de juiste bouwopdracht" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Dupliceer build line toewijzing" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Ten minste één item of regel moet worden opgegeven" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Bezig" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Productie" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "In de wacht" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Geannuleerd" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Voltooid" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Productieorder {build} is voltooid" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Een productieorder is voltooid" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Voorraad vereist voor productieorder" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Bouw order {build} vereist extra voorraad" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Achterstallige Productieorder" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Productieorder {bo} is nu achterstallig" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "Heeft Miniatuurafbeelding" + +#: common/api.py:773 msgid "Is Link" msgstr "Is koppeling" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Is een bestand" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Gebruiker heeft geen toestemming om deze bijlagen te verwijderen" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "Gebruiker heeft geen toestemming om deze bijlage te bewerken." -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Gebruiker heeft geen toestemming om deze bijlage te verwijderen." +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Lijst met selecties is vergrendeld" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Ongeldige valuta code" @@ -1539,15 +1641,20 @@ msgstr "Geen geldige valuta codes opgegeven" msgid "No plugin" msgstr "Geen plug-in gevonden" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "Tags" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Projectcode label" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Bijgewerkt" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Tijdstempel van laatste update" @@ -1567,794 +1674,844 @@ msgstr "Unieke projectcode" msgid "Project description" msgstr "Projectbeschrijving" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Gebruiker of groep die verantwoordelijk is voor dit project" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Instellingen" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Instellingswaarde" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Gekozen waarde is geen geldige optie" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Waarde moet een booleaanse waarde zijn" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Waarde moet een geheel getal zijn" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Waarde moet een geldig getal zijn" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Waarde is niet geldig voor validatiecontrole" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Sleutelreeks moet uniek zijn" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Gebruiker" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Prijs pauze hoeveelheid" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Prijs" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Stukprijs op opgegeven hoeveelheid" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Eindpunt" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Eindpunt waarop deze webhook wordt ontvangen" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Naam van deze webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Actief" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Gebruiker of groep die verantwoordelijk is voor dit project" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Instellingen" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Instellingswaarde" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Gekozen waarde is geen geldige optie" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Waarde moet een booleaanse waarde zijn" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Waarde moet een geheel getal zijn" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Waarde moet een geldig getal zijn" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Waarde is niet geldig voor validatiecontrole" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Sleutelreeks moet uniek zijn" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Gebruiker" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Prijs pauze hoeveelheid" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Prijs" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Stukprijs op opgegeven hoeveelheid" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Eindpunt" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Eindpunt waarop deze webhook wordt ontvangen" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Naam van deze webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Is deze webhook actief" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Sleutel" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token voor toegang" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Geheim" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Gedeeld geheim voor HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Bericht ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Unieke identificatie voor dit bericht" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Host" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Host waarvan dit bericht is ontvangen" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Koptekst" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Koptekst van dit bericht" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Berichtinhoud" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Inhoud van dit bericht" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Eindpunt waarop dit bericht is ontvangen" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Aan gewerkt" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Is het werk aan dit bericht voltooid?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Titel" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Koppeling" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Gepubliceerd" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Auteur" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Samenvatting" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Gelezen" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Is dit nieuwsitem gelezen?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Afbeelding" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Doel type voor deze afbeelding" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "Doel modelnummer voor deze afbeelding" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Aangepaste eenheid" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Eenheid symbool moet uniek zijn" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Naam van de unit moet een geldig id zijn" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Naam van eenheid" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbool" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Optionele eenheid symbool" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definitie" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definitie van eenheid" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Bijlage" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Ontbrekend bestand" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Externe link ontbreekt" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Model type" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Doel type voor afbeelding" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Bestand als bijlage selecteren" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "Miniatuur" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Opmerking" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Opmerking van bijlage" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Uploaddatum" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Datum waarop het bestand is geüpload" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "Is een afbeelding" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Bestandsgrootte" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Bestandsgrootte in bytes" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Ongeldig modeltype opgegeven voor bijlage" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Aangepaste staat" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Aangepaste statussen" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Referentie status set" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Status set die met deze aangepaste status wordt uitgebreid" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logische sleutel" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Staat logische sleutel die gelijk is aan deze staat in zakelijke logica" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Waarde" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "De numerieke waarde die wordt opgeslagen in de modellendatabase" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Naam van de toestand" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Label" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Label dat in de frontend getoond wordt" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Kleur" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Kleur die in de frontend getoond wordt" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Model met deze staat is gekoppeld aan" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Het model moet worden gekozen" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Sleutel moet worden geselecteerd" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Logische sleutel moet worden geselecteerd" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "Sleutel moet anders zijn dan logische sleutel" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Geldige referentie status klasse moet worden opgegeven" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "Sleutel moet verschillen van de logische sleutels van de referentie status" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "Logische sleutel moet in de logische sleutels van de referentiestatus staan" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Naam moet anders zijn dan de namen van de referentie status" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Keuzelijst" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Selectielijst" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Naam van de selectielijst" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Beschrijving van de selectielijst" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Vergrendeld" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Is deze selectielijst vergrendeld?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Kan deze selectielijst worden gebruikt?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Bron plug-in" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Plug-in die de selectielijst biedt" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Bron tekenreeks" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Optionele tekenreeks die de bron identificeert die voor deze lijst wordt gebruikt" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Standaard vermelding" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Standaard vermelding voor deze selectielijst" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Gecreëerd" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Datum en tijd waarop de selectielijst is aangemaakt" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Laatst bijgewerkt" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Datum en tijd waarop de selectielijst voor het laatst is bijgewerkt" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Selectielijst item" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Selectielijst item" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Selectielijst waaraan dit item hoort" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Naam van de selectielijst" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Label voor het item in de selectielijst" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Beschrijving van het item in de selectielijst" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Is dit item in deze lijst actief?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Parameter sjabloon" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "Parameter sjablonen" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Checkbox parameters kunnen geen eenheden bevatten" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Checkbox parameters kunnen geen eenheden bevatten" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Keuzes moeten uniek zijn" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "De template van de parameter moet uniek zijn" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "Doelmodeltype voor dit parametersjabloon" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Parameternaam" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Eenheden" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Fysieke eenheden voor deze parameter" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Parameter omschrijving" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Selectievakje" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Is deze parameter een selectievak?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Keuzes" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Geldige keuzes voor deze parameter (komma gescheiden)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Lijst met selecties voor deze parameter" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Ingeschakeld" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "Is dit parametersjabloon ingeschakeld?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "Parameter" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "Parameters" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Ongeldige keuze voor parameter waarde" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "Ongeldig modeltype opgegeven voor parameter" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "Model-ID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "ID van het doelmodel voor deze parameter" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Sjabloon" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "Parameter sjabloon" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Gegevens" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Parameterwaarde" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Opmerking" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Optioneel notities veld" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Barcode Scan" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Barcode gegevens" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Gebruiker die de barcode gescand heeft" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Tijdstempel" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Datum en tijd van de streepjescode scan" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Adres eindpunt dat de streepjescode verwerkt" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Inhoud" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Contextgegevens voor de barcode scan" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Reactie" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Reactiegegevens van de barcode scan" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Resultaat" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Was de barcode succesvol gescand?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Er is een fout opgetreden" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: E-maillog verwijderen wordt beschermd. Zet INVENTREE_PROTECT_EMAIL_LOG naar False om verwijdering toe te staan." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "E-mailbericht" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "E-mail berichten" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Aangekondigd" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Verzonden" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Mislukt" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Geleverd" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Bevestigd" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Inkomend" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Uitgaand" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Geen antwoord" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Track levering" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Track gelezen" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Track Klik" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "Globaal ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Identificatie voor dit bericht (kan worden geleverd door een extern systeem)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "Discussie ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Identificatie voor deze bericht draad (kan worden geleverd door een extern systeem)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Gesprek" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Gekoppeld onderwerp voor dit bericht" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "Prioriteit" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "E-mail gesprekken" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "E-mail gesprekken" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Sleutel" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Unieke sleutel voor deze thread (gebruikt om de conversatie te identificeren)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Unieke identificatie voor dit bericht" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Intern gestart" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Is dit onderwerp intern gestart?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Datum en tijd waarop de conversatie voor het laatst is bijgewerkt" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Datum en tijd waarop de conversatie voor het laatst is bijgewerkt" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} is geannuleerd" msgid "A order that is assigned to you was canceled" msgstr "Een bestelling die aan u is toegewezen is geannuleerd" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Ontvangen items" @@ -2388,104 +2545,100 @@ msgstr "Artikelen zijn ontvangen tegen een inkooporder" msgid "Items have been received against a return order" msgstr "Items zijn ontvangen tegen een retour bestelling" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "Geeft aan of deze instelling bevestiging nodig heeft" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "Deze instelling vereist een bevestiging voordat u verandert. Bevestig alstublieft de wijziging." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Geeft aan of de instelling overschreven wordt door een omgevingsvariabele" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Overschrijven" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Is actief" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Openstaande taken" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Geplande taken" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Mislukte taken" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Taak ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Unieke taak ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Vergrendel" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Tijdstip van vergrendeling" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Naam van de taak" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Functie" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Functie naam" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumenten" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Taak argumenten" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Trefwoord argumenten" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Taak trefwoord argumenten" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Bestandsnaam" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Model type" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Gebruiker heeft geen toestemming om bijlagen voor dit model te maken of te bewerken" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "Gebruiker heeft geen toestemming om parameters voor dit model te maken of te bewerken" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Lijst met selecties is vergrendeld" - #: common/setting/system.py:97 msgid "No group" msgstr "Geen groep" @@ -2614,13 +2767,13 @@ msgstr "Valuta update interval" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Hoe vaak te controleren op updates (nul om uit te schakelen)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dagen" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Munteenheid update plug-in om te gebruiken" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "Maximale upload grote" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Strikte URL validatie" @@ -2760,947 +2921,1017 @@ msgstr "Streepjescode Plug-in" msgid "Plugin to use for internal barcode data generation" msgstr "Plug-in om te gebruiken voor interne barcode data genereren" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Herzieningen onderdeel" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Revisieveld voor onderdeel inschakelen" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Alleen assemblee revisie" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Alleen revisies toestaan voor assemblageonderdelen" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Verwijderen uit Assemblage toestaan" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Verwijderen van onderdelen die in een groep worden gebruikt toestaan" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN Regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Regulier expressiepatroon voor het overeenkomende Onderdeel IPN" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Duplicaat IPN toestaan" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Toestaan dat meerdere onderdelen dezelfde IPN gebruiken" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Bewerken IPN toestaan" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Sta het wijzigen van de IPN toe tijdens het bewerken van een onderdeel" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Kopieer Onderdeel Stuklijstgegevens" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Kopieer standaard stuklijstgegevens bij het dupliceren van een onderdeel" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Kopieer Onderdeel Parametergegevens" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Parametergegevens standaard kopiëren bij het dupliceren van een onderdeel" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Kopieer Onderdeel Testdata" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Testdata standaard kopiëren bij het dupliceren van een onderdeel" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kopiëer Categorieparameter Sjablonen" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Kopieer categorieparameter sjablonen bij het aanmaken van een onderdeel" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Onderdelen zijn standaard sjablonen" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Onderdelen kunnen standaard vanuit andere componenten worden samengesteld" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Onderdeel" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Onderdelen kunnen standaard worden gebruikt als subcomponenten" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Koopbaar" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Onderdelen kunnen standaard gekocht worden" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Verkoopbaar" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Onderdelen kunnen standaard verkocht worden" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Onderdelen kunnen standaard gevolgd worden" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtueel" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Onderdelen zijn standaard virtueel" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Verwante onderdelen tonen" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Verwante onderdelen voor een onderdeel tonen" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Initiële voorraadgegevens" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Aanmaken van eerste voorraad toestaan bij het toevoegen van een nieuw onderdeel" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Initiële leveranciergegevens" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Aanmaken van eerste leveranciersgegevens toestaan bij het toevoegen van een nieuw onderdeel" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Onderdelennaam Weergaveopmaak" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Opmaak om de onderdeelnaam weer te geven" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Standaardicoon voor onderdeel catagorie" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Standaardicoon voor onderdeel catagorie (leeg betekent geen pictogram)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Minimaal aantal prijs decimalen" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Minimaal aantal decimalen om weer te geven bij het weergeven van prijsgegevens" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Maximum prijs decimalen" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Maximum aantal decimalen om weer te geven bij het weergeven van prijsgegevens" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Gebruik leveranciersprijzen" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Prijsvoordelen leveranciers opnemen in de totale prijsberekening" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Aankoopgeschiedenis overschrijven" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Historische order prijzen overschrijven de prijzen van de leverancier" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Gebruik voorraaditem prijzen" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Gebruik prijzen van handmatig ingevoerde voorraadgegevens voor prijsberekeningen" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Voorraad artikelprijs leeftijd" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Voorraaditems ouder dan dit aantal dagen uitsluiten van prijsberekeningen" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Gebruik variantprijzen" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Variantenprijzen opnemen in de totale prijsberekening" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Alleen actieve varianten" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Gebruik alleen actieve variantonderdelen voor het berekenen van variantprijzen" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Prijzen automatisch bijwerken" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Automatisch prijzen van onderdelen bijwerken wanneer interne gegevens veranderen" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Prijzen Herbouw interval" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Aantal dagen voordat de prijzen voor onderdelen automatisch worden bijgewerkt" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Interne Prijzen" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Inschakelen van interne prijzen voor onderdelen" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Interne prijs overschrijven" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Indien beschikbaar, interne prijzen overschrijven berekeningen van prijsbereik" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "BOM Zero Quantity toestaan" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Printen van labels Inschakelen" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Printen van labels via de webinterface inschakelen" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Label Afbeelding DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "DPI resolutie bij het genereren van afbeelginsbestanden voor label printer plugins" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Activeer Rapportages" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Activeer het genereren van rapporten" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Foutopsporingsmodus" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Rapporten genereren in debug modus (HTML uitvoer)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Log fouten" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Registreer fouten die optreden bij het genereren van rapporten" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Paginagrootte" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Standaard paginagrootte voor PDF rapporten" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Forceer Parameter Eenheden" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Als er eenheden worden opgegeven, moeten parameterwaarden overeenkomen met de opgegeven eenheden" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Globaal unieke serienummers" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Serienummers voor voorraaditems moeten globaal uniek zijn" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Verwijder uitgeputte voorraad" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Bepaalt standaard gedrag wanneer een voorraadartikel leeg is" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Batchcode Sjabloon" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Sjabloon voor het genereren van standaard batchcodes voor voorraadartikelen" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Verlopen Voorraad" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Verlopen voorraad functionaliteit inschakelen" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Verkoop Verlopen Voorraad" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Verkoop verlopen voorraad toestaan" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Voorraad Vervaltijd" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Aantal dagen voordat voorraadartikelen als verouderd worden beschouwd voor ze verlopen" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Produceer Verlopen Voorraad" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Sta productie met verlopen voorraad toe" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Voorraad Eigenaar Toezicht" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Eigenaarstoezicht over voorraadlocaties en items inschakelen" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Voorraadlocatie standaard icoon" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Standaard locatie pictogram (leeg betekent geen icoon)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Geïnstalleerde voorraad items weergeven" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Geïnstalleerde voorraadartikelen in voorraadtabellen tonen" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Controleer BOM bij het installeren van items" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Geïnstalleerde voorraad items moeten in de BOM voor het bovenliggende deel bestaan" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Sta 'Niet op voorraad overschrijving' toe" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Toestaan dat voorraadartikelen die niet op voorraad zijn worden overgebracht tussen voorraadlocaties" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Productieorderreferentiepatroon" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Vereist patroon voor het genereren van het Bouworderreferentieveld" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Vereis verantwoordelijke eigenaar" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Een verantwoordelijke eigenaar moet worden toegewezen aan elke bestelling" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Vereist een actief onderdeel" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Voorkom het maken van orders voor inactieve onderdelen" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Vergrendeld onderdeel vereisen" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Voorkom het maken van orders voor ontgrendelde onderdelen" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Vereist een geldige BOM" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Voorkom het creëren van bouworders tenzij BOM is gevalideerd" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Onderliggende bestellingen vereist" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Voorkom voltooiing van de bouw tot alle sub orders gesloten zijn" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Externe Bouw Orders" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Inschakelen externe build order functionaliteit" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blokkeren tot test geslaagd" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Voorkom dat de bouw van de uitvoer wordt voltooid totdat alle vereiste testen zijn geslaagd" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Retourorders inschakelen" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Retourorder functionaliteit inschakelen in de gebruikersinterface" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Retourorder referentie patroon" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Verplicht patroon voor het genereren van Retourorder referentie veld" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Bewerk voltooide retourorders" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Bewerken van retourorders toestaan nadat deze zijn voltooid" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Verkooporderreferentiepatroon" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Vereist patroon voor het genereren van het Verkooporderreferentieveld" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Standaard Verzending Verkooporder" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Aanmaken standaard verzending bij verkooporders inschakelen" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Bewerk voltooide verkooporders" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Bewerken van verkooporders toestaan nadat deze zijn verzonden of voltooid" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "Zending moet gecontroleerd worden" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Voorkom voltooiing van verzendingen totdat items zijn gecontroleerd" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Verstuurde bestellingen markeren als voltooid" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Verkooporders gemarkeerd als verzonden zullen automatisch worden voltooid, zonder de status \"verzonden\"" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Inkooporderreferentiepatroon" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Vereist patroon voor het genereren van het Inkooporderreferentieveld" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Bewerk voltooide verkooporders" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Bewerken van inkooporders toestaan nadat deze zijn verzonden of voltooid" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Valuta converteren" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Verander artikelwaarde naar basisvaluta bij het ontvangen van voorraad" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Inkooporders automatisch voltooien" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Markeer orders automatisch als voltooid wanneer alle regelitems worden ontvangen" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Wachtwoord vergeten functie inschakelen" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Wachtwoord vergeten functie inschakelen op de inlogpagina's" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Registratie inschakelen" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Zelfregistratie voor gebruikers op de inlogpagina's inschakelen" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "SSO inschakelen" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "SSO inschakelen op de inlogpagina's" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Schakel gebruikersregistratie met SSO in" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Zelfregistratie voor gebruikers middels SSO op de inlogpagina's inschakelen" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "SSO-groep synchroniseren inschakelen" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Inschakelen van het synchroniseren van InvenTree groepen met groepen geboden door de IdP" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSO groep sleutel" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "De naam van de groepen claim attribuut van de IdP" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "SSO groep kaart" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Een mapping van SSO-groepen naar lokale InvenTree groepen. Als de lokale groep niet bestaat, zal deze worden aangemaakt." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Verwijder groepen buiten SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Of groepen die zijn toegewezen aan de gebruiker moeten worden verwijderd als ze geen backend zijn door de IdP. Het uitschakelen van deze instelling kan beveiligingsproblemen veroorzaken" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "E-mailadres verplicht" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Vereis gebruiker om e-mailadres te registreren bij aanmelding" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "SSO-gebruikers automatisch invullen" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Gebruikersdetails van SSO-accountgegevens automatisch invullen" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "E-mail twee keer" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Bij inschrijving gebruikers twee keer om hun e-mail vragen" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Wachtwoord tweemaal" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Laat gebruikers twee keer om hun wachtwoord vragen tijdens het aanmelden" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Toegestane domeinen" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Inschrijven beperken tot bepaalde domeinen (komma-gescheiden, beginnend met @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Groep bij aanmelding" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Groep waaraan nieuwe gebruikers zijn toegewezen op registratie. Als SSO-groepssynchronisatie is ingeschakeld, is deze groep alleen ingesteld als er geen groep vanuit de IdP kan worden toegewezen." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "MFA afdwingen" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Gebruikers moeten multifactor-beveiliging gebruiken." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "Het inschakelen van deze instelling zal ervoor zorgen dat alle gebruikers multifactor authenticatie instellen. Alle sessies worden onmiddellijk verbroken." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Controleer plugins bij het opstarten" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Controleer of alle plug-ins zijn geïnstalleerd bij het opstarten - inschakelen in container-omgevingen" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Controleren op plug-in updates" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Schakel periodieke controles voor updates voor geïnstalleerde plug-ins in" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Activeer URL-integratie" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Plugins toestaan om URL-routes toe te voegen" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Activeer navigatie integratie" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Plugins toestaan om te integreren in navigatie" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Activeer app integratie" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Activeer plug-ins om apps toe te voegen" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Activeer planning integratie" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Activeer plugin om periodiek taken uit te voeren" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Activeer evenement integratie" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Activeer plugin om op interne evenementen te reageren" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Interface integratie activeren" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Plug-ins inschakelen om te integreren in de gebruikersinterface" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "E-mail integratie inschakelen" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Schakel plug-ins in om uitgaande / inkomende mails te verwerken" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Activeer project codes" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Schakel projectcodes in voor het bijhouden van projecten" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "Voorraadcontrole inschakelen" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Functionaliteit voor het opnemen van historische voorraadniveaus en -waarde inschakelen" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Externe locaties uitsluiten" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "Voorraadartikelen op externe locaties uitsluiten van voorraadberekeningen" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Automatische Voorraadcontrole Periode" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "Aantal dagen tussen automatische voorraadgegevens opnemen" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "Oude voorraadgegevens verwijderen" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "Voorraadgegevens verwijderen die ouder zijn dan het opgegeven aantal dagen" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "Interval Voorraadgegevens verwijderen" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "Voorraadgegevens zal worden verwijderd na het opgegeven aantal dagen" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "Oude voorraadgegevens verwijderen" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "Inverval voor verwijderen van voorraadtracking" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Gebruikers volledige namen weergeven" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Laat gebruikers volledige namen zien in plaats van gebruikersnamen" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Gebruikersprofielen tonen" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Toon gebruikersprofielen op hun profielpagina" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" -msgstr "" +msgstr "De week begint op" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" -msgstr "" +msgstr "Eerste dat van de week, voor in de kalenderweergaven" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" -msgstr "" +msgstr "Zondag" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" -msgstr "" +msgstr "Maandag" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" -msgstr "" +msgstr "Dinsdag" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" -msgstr "" +msgstr "woensdag" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" -msgstr "" +msgstr "Donderdag" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" -msgstr "" +msgstr "Vrijdag" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" +msgstr "Zaterdag" + +#: common/setting/system.py:1277 +msgid "Calendar Horizon" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "maanden" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Inschakelen van teststation data" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Schakel teststation gegevensverzameling in voor testresultaten" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "Machine Ping inschakelen" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Schakel periodieke ping taak van geregistreerde machines in om hun status te controleren" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Aantal resultaten om weer te geven in elk gedeelte van het zoekvenster" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Regex zoeken" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Schakel reguliere expressies in zoekopdrachten in" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Hele woorden zoeken" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Zoekopdrachten geven resultaat voor hele woord overeenkomsten" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Zoek notities" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Zoekopdrachten geven resultaten voor overeenkomsten met artikel notities" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Escape-toets sluit formulieren" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Gebruik de Escape-toets om standaard formulieren te sluiten" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Vaste navigatiebalk" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "De navigatiebalk positie is gefixeerd aan de bovenkant van het scherm" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "Vaste tabelkoppen" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Tabelkoppen zijn vast aan de bovenkant van de tabel" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Spotlight tonen" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Spotlight navigatie functie inschakelen" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Navigatiepictogrammen" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Pictogrammen weergeven in de navigatiebalk" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Datum formaat" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Voorkeursindeling voor weergave van datums" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Voorraadgeschiedenis weergeven" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Toon informatie van de voorraadgeschiedenis op de detailpagina van het onderdeel" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Toon laatste broodkruimel" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Toon de huidige pagina in het kruimelpad" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Toon de volledige voorraadlocatie in de tabellen" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Uitgeschakeld: Het volledige pad van de locatie wordt weergegeven als een zwevende tooltip. Ingeschakeld: Het volledige locatie pad wordt weergegeven als platte tekst." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Toon alle onderdeel categorieën in tabellen" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Uitgeschakeld: Het volledige categorie pad wordt weergegeven als hover tooltip. Ingeschakeld: Het pad van de volledige categorie wordt weergegeven als platte tekst." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Foutrapportages ontvangen" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Meldingen ontvangen van systeemfouten" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Laatst gebruikte printer" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Sla de laatst gebruikte printer op voor een gebruiker" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Alle modellen" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Geen bijlage model type opgegeven" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Ongeldig bijlage type" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "Ongeldige bestandsnaam" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Minimale plaatsen mogen niet groter zijn dan het maximum" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Maximum aantal plaatsen kan niet minder zijn dan minimaal" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Een leeg domein is niet toegestaan." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Ongeldige domeinnaam: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "De waarde moet hoofdletters zijn" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Waarde moet een geldige variabele id zijn" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Onderdeel is actief" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Fabrikant is actief" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Leveranciersonderdelen is actief" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "Primaire leverancierdeel" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Intern onderdeel is actief" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Leverancier is actief" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Fabrikant" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Bedrijf" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Heeft voorraad" @@ -4123,8 +4387,8 @@ msgstr "Telefoonnummer voor contact" msgid "Contact email address" msgstr "Contact e-mailadres" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Contact" @@ -4176,283 +4440,283 @@ msgstr "Btw-nr" msgid "Company Tax ID" msgstr "BTW-nummer van bedrijf" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adres" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adres" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Selecteer bedrijf" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Adres titel" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Titel die het adres beschrijft" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Primair adres" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Instellen als primair adres" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Lijn 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Adresregel 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Lijn 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Adresregel 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Post code" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Plaats/regio" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Postcode plaats/regio" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Staat/provincie" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Staat of provincie" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Land" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Adres land" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Koerier verzend notities" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Opmerkingen voor verzending koerier" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Interne verzend notities" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Verzend notities voor intern gebruik" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Link naar adres gegevens (extern)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Fabrikant onderdeel" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Basis onderdeel" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Onderdeel selecteren" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Fabrikant selecteren" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "Fabrikant artikel nummer" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Fabrikant artikel nummer (MPN)" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL voor externe link van het fabrikant onderdeel" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Omschrijving onderdeel fabrikant" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Pakket eenheden moeten compatibel zijn met de basis onderdeel eenheden" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Hoeveelheid moet groter zijn dan nul" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Gekoppeld fabrikant onderdeel moet verwijzen naar hetzelfde basis onderdeel" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Leverancier" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Leverancier selecteren" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Voorraad beheers eenheid voor leveranciers" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Is dit leveranciersdeel actief?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "Primair" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Selecteer fabrikant onderdeel" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL voor link externe leveranciers onderdeel" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Omschrijving leveranciersdeel" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "basisprijs" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimale kosten (bijv. voorraadkosten)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Verpakking" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Onderdeel verpakking" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Pakket hoeveelheid" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Totale hoeveelheid geleverd in één pakket. Laat leeg voor enkele afzonderlijke items." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "meerdere" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Order meerdere" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Beschikbare hoeveelheid van leverancier" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Beschikbaarheid bijgewerkt" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Datum van de laatste update van de beschikbaarheid gegevens" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Prijsverschil van leverancier" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Standaardvaluta die gebruikt wordt voor deze leverancier" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Bedrijfsnaam" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Op voorraad" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Prijsverschillen" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" -msgstr "" +msgstr "Weergavenaam" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Fout opgetreden tijdens data export" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Gegevensexport plug-in geeft onjuiste gegevensindeling terug" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Exporteer formaat" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Selecteer export bestandsindeling" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Plug-in exporteren" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Export plug-in selecteren" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Additionele statusinformatie voor dit item" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Aangepaste status sleutel" @@ -4476,123 +4740,152 @@ msgstr "Geplaatst" msgid "Invalid status code" msgstr "Ongeldige statuscode" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Data bestand" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Te importeren databestand" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Kolommen" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Doel modeltype voor deze importsessie" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Status van importeren" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Veld standaard" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Veld overschrijven" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Veld filters" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Bestaande Records Bijwerken" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Indien ingeschakeld, zullen bestaande records worden bijgewerkt met nieuwe gegevens" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Sommige verplichte velden zijn niet toegewezen" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Bestaande database-identifier voor het record" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "De kolom is al toegewezen aan een database veld" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Het veld is al toegewezen aan een data-kolom" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Kolom toewijzing moet worden gekoppeld aan een geldige importsessie" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Kolom bestaat niet in het gegevensbestand" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Veld bestaat niet in het doel model" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Geselecteerde veld is alleen lezen" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Importeer sessie" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Veld" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Kolom" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Rij index" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Oorspronkelijke rij gegevens" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Fouten" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Geldig" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "ID is vereist voor het bijwerken van bestaande records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Geen record gevonden met het opgegeven ID" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Ongeldig ID formaat opgegeven" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "ID is vereist voor het bijwerken van bestaande records." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Niet ondersteunde gegevens bestandsindeling" @@ -4600,43 +4893,47 @@ msgstr "Niet ondersteunde gegevens bestandsindeling" msgid "Failed to open data file" msgstr "Kan het databestand niet openen" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Ongeldige afmetingen van gegevensbestand" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Ongeldig veld standaard" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Ongeldige veld overschrijvingen" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Ongeldige veld filters" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Rijen" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Lijst van te accepteren rij IDs" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Geen rijen opgegeven" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "Regel behoort niet tot deze sessie" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "Regel bevat ongeldige gegevens" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "Regel is al voltooid" @@ -4672,115 +4969,115 @@ msgstr "Gegevensbestand bevat te veel kolommen" msgid "Data file contains too many rows" msgstr "Gegevensbestand bevat te veel rijen" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Waarde moet een geldig woordenboek teken zijn" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopieën" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Aantal afdrukken voor elk label" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Verbonden" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Onbekend" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Afdrukken" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Waarschuwing" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Geen media" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Het papier is vastgelopen" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Verbinding verbroken" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Error" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Label printer" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Direct labels afdrukken voor verschillende items." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Printer locatie" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Bereik de printer naar een specifieke locatie" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Naam van de machine" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Machine type" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Type machine" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Stuurprogramma" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Stuurprogramma gebruikt voor de machine" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Machines kunnen worden uitgeschakeld" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Stuurprogramma beschikbaar" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Geen fouten" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Geïnitialiseerd" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Machine status" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Machine" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Machine configuratie" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Configuratie type" @@ -4792,7 +5089,7 @@ msgstr "Sleutel van de eigenschap" msgid "Value of the property" msgstr "Waarde van de eigenschap" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Groep" @@ -4816,117 +5113,118 @@ msgstr "Maximale voortgang" msgid "Maximum value for progress type, required if type=progress" msgstr "Maximale waarde voor voortgangsttype, vereist als type=progress" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Order Referentie" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Uitmuntend" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Heeft een projectcode" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Aangemaakt Door" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Gemaakt vóór" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Gemaakt na" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Heeft vervaldatum" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Vervaldatum voor" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Vervaldatum na" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Heeft doel datum" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Doel datum voor" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Doel datum na" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "Bijgewerkt voor" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "Bijgewerkt na" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Heeft prijsstelling" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Voltooid voor" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Voltooid na" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Externe Bouw Opdracht" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Bestellen" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Bestelling voltooid" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Intern onderdeel" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Bestelling in behandeling" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Voltooid" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Heeft verzending" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Inkooporder" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,783 +5232,892 @@ msgstr "Inkooporder" msgid "Sales Order" msgstr "Verkooporder" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Retour bestelling" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Totaalprijs" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Totaalprijs van deze bestelling" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Valuta bestelling" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Valuta voor deze order (laat leeg om de standaard van het bedrijf te gebruiken)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Deze bestelling is vergrendeld en kan niet worden gewijzigd" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Contact komt niet overeen met het geselecteerde bedrijf" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "Startdatum moet voor einddatum liggen" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "Adres komt niet overeen met het geselecteerde bedrijf" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Bestelling beschrijving (optioneel)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Selecteer projectcode voor deze bestelling" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Link naar externe pagina" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Start datum" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Geplande startdatum voor deze bestelling" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Streefdatum" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Verwachte datum voor levering van de bestelling. De bestelling wordt achterstallig na deze datum." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Datum van uitgifte" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Order uitgegeven op datum" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "Bijgewerkt op" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Gebruiker of groep verantwoordelijk voor deze order" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Contactpunt voor deze volgorde" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Bedrijf adres voor deze bestelling" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Orderreferentie" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Inkooporder status" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Bedrijf waar de artikelen van worden besteld" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Leveranciersreferentie" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Order referentiecode van leverancier" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "ontvangen door" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Order voltooid op datum" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Bestemming" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Bestemming voor ontvangen items" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Onderdeelleverancier moet overeenkomen met de Inkooporderleverancier" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Artikelregel komt niet overeen met inkooporder" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "Regelitem mist een gekoppeld deel" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Hoeveelheid moet een positief getal zijn" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Klant" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Bedrijf waaraan de artikelen worden verkocht" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Verkooporder status" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Klantreferentie " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Klant order referentiecode" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Verzenddatum" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "verzonden door" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Artikelregel is niet gekoppeld aan deze bestelling" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Geen overeenkomst gevonden voor de volgende serienummers" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "De volgende serienummers zijn niet beschikbaar" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Bestelling is al afgerond" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Order is al geannuleerd" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Alleen een open bestelling kan als voltooid worden gemarkeerd" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Bestelling kan niet worden voltooid omdat er onvolledige verzendingen aanwezig zijn" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Order kan niet worden voltooid omdat er onvolledige artikelen aanwezig zijn" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Order kan niet worden voltooid omdat er onvolledige artikelen aanwezig zijn" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "De bestelling is vergrendeld en kan niet worden gewijzigd" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Hoeveelheid artikelen" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Artikelregel referentie" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Artikel notities" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Doeldatum voor dit regelitem (laat leeg om de doeldatum van de bestelling te gebruiken)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Regelomschrijving (optioneel)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Additionele context voor deze regel" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Stukprijs" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Inkooporder regel item" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Leveranciersonderdeel moet overeenkomen met leverancier" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "Bouw bestelling moet worden gemarkeerd als extern" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Bestellingen kunnen alleen aan assemblageonderdelen worden gekoppeld" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "De bouw van het order deel moet overeenkomen met regel onderdeel" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Leveranciersonderdeel" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Ontvangen" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Aantal ontvangen artikelen" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Inkoopprijs" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Aankoopprijs per stuk" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Externe Build Order moet aan deze regel voldoen" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Extra regel inkooporder" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Verkooporder regel item" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Alleen verkoopbare onderdelen kunnen aan een verkooporder worden toegewezen" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Verkoopprijs" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Prijs per stuk" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Verzonden" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Verzonden hoeveelheid" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Verzending van verkooporder" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "Verzendadres moet overeenkomen met de klant" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Verzendadres voor deze zending" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Datum van verzending" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Leveringsdatum" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Datum van levering van zending" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Gecontroleerd door" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Gebruiker die deze zending gecontroleerd heeft" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Zending" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Zendingsnummer" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Volgnummer" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Zending volginformatie" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Factuurnummer" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Referentienummer voor bijbehorende factuur" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Verzending is al verzonden" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Zending heeft geen toegewezen voorraadartikelen" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "Verzending moet worden gecontroleerd voordat deze kan worden voltooid" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Verkooporder extra regel" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Toewijzing verkooporder" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Voorraadartikel is niet toegewezen" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Kan het voorraadartikel niet toewijzen aan een regel met een ander onderdeel" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Kan voorraad niet toewijzen aan een regel zonder onderdeel" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Toewijzingshoeveelheid kan niet hoger zijn dan de voorraadhoeveelheid" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Toewijzing hoeveelheid moet groter zijn dan nul" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Hoeveelheid moet 1 zijn voor geserialiseerd voorraadartikel" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Verkooporder komt niet overeen met zending" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Verzending komt niet overeen met verkooporder" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Regel" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Verzendreferentie verkooporder" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Artikel" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Selecteer voorraadartikel om toe te wijzen" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Voer voorraadtoewijzingshoeveelheid in" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Retour order referentie" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Bedrijf van waaruit items worden teruggestuurd" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Retour bestelling status" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Retourneer bestelregel item" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Voorraad item moet worden opgegeven" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Retour hoeveelheid overschrijdt voorraad hoeveelheid" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "Het retour aantal moet groter zijn dan nul" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Ongeldige hoeveelheid voor geserialiseerde voorraad" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Selecteer te retourneren product van de klant" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Ontvangst datum" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "De datum waarop dit retour item is ontvangen" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Resultaat" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Resultaat van deze regel item" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Kosten geassocieerd met teruggave of reparatie voor deze regel item" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Retourneren extra regel" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "Bestelling ID" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID van de bestelling om te dupliceren" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Kopieer regels" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Kopieer regelitems uit de oorspronkelijke bestelling" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Extra regels kopiëren" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Extra regelitems van de oorspronkelijke bestelling kopiëren" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Parameters kopiëren" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Artikelen" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Afgeronde regel items" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Artikel dupliceren" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Specificeer opties voor het dupliceren van deze bestelling" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Ongeldige order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Leveranciers Naam" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Order kan niet worden geannuleerd" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Toestaan order te sluiten met onvolledige regelitems" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Bestelling heeft onvolledige regelitems" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Order is niet open" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Automatisch prijzen" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Koopprijs automatisch berekenen gebaseerd op leveranciers \n" " onderdelen gegevens" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Valuta Inkoopprijs" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Items samenvoegen" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Items met hetzelfde onderdeel, bestemming en doeldatum samenvoegen in één regelitem" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Intern Onderdeelnummer" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Interne naam onderdeel" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Leveranciersonderdeel moet worden gespecificeerd" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Inkooporder moet worden gespecificeerd" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "De leverancier moet overeenkomen met de inkooporder" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Inkooporder moet overeenkomen met de leverancier" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Artikel" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Selecteer bestemmingslocatie voor ontvangen artikelen" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Voer batch code in voor inkomende voorraad items" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Vervaldatum" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Voer vervaldatum in voor inkomende voorraad items" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Voer serienummers in voor inkomende voorraadartikelen" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Overschrijf verpakkingsinformatie voor binnenkomende voorraad" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Extra opmerking voor inkomende voorraad items" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Streepjescode" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Gescande streepjescode" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Streepjescode is al in gebruik" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Artikelen moeten worden opgegeven" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Bestemmingslocatie moet worden opgegeven" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Geleverde streepjescodewaarden moeten uniek zijn" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Verzendingen" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Voltooide Verzendingen" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "Toegewezen lijnen" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Valuta verkoopprijs" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Toegewezen items" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Geen verzenddetails opgegeven" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Artikelregel is niet gekoppeld aan deze bestelling" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Hoeveelheid moet positief zijn" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Voer serienummers in om toe te wijzen" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Verzending is al verzonden" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Zending is niet gekoppeld aan deze bestelling" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Geen overeenkomst gevonden voor de volgende serienummers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "De volgende serienummers zijn niet beschikbaar" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Retourneer regel item" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Artikelregel komt niet overeen met inkooporder" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Regel item is al ontvangen" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Artikelen kunnen alleen worden ontvangen tegen lopende bestellingen" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Hoeveelheid te retourneren" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Lijn prijs valuta" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Kwijt" @@ -5719,1279 +6126,1312 @@ msgstr "Kwijt" msgid "Returned" msgstr "Retour" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "In Behandeling" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Retour" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Herstel" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Vervangen" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Restitutie" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Afwijzen" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Uitgegeven" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Achterstallige inkooporder" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Inkooporder {po} is nu achterstallig" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Achterstallige Verkooporder" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Verkooporder {so} is nu achterstallig" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Achterstallige retour orders" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Productieorder {ro} is nu achterstallig" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Favoriet" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Filter op categorieën met ster" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Diepte" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filteren op categorie diepte" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Hoogste niveau" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filteren op topniveau categorieën" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Stapelen" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Inclusief subcategorieën in gefilterde resultaten" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Bovenliggend" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Filter op bovenliggende categorie" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Subcategorieën uitsluiten in de opgegeven categorie" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Heeft resultaten" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Is een variant" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Is revisie" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Heeft revisies" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "BOM Valid" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Cascade Categorieën" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Indien waar, inclusief items op de onderliggende categorieën van de opgegeven categorie" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Filter op numerieke categorie-ID of de letterlijke 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "Bouw onderdeel is actief" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "Bouw onderdeel is te volgen" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Assemblage deel is testbaar" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "Onderdeel is actief" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "Onderdeel is trackable" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Component onderdeel is testbaar" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "Onderdeel is nog te bouwen" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "Onderdeel is virtueel" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "Heeft beschikbare voorraad" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Gebruik" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Onderdeel Categorie" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Onderdeel Categorieën" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Standaard locatie" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Standaard locatie voor onderdelen in deze categorie" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Structureel" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Onderdelen mogen niet rechtstreeks aan een structurele categorie worden toegewezen, maar kunnen worden toegewezen aan subcategorieën." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Standaard trefwoorden" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Standaard trefwoorden voor delen in deze categorie" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Pictogram" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Pictogram (optioneel)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "U kunt deze voorraadlocatie niet structureel maken omdat sommige voorraadartikelen er al in liggen!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Sjabloon categorie parameters onderdeel" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Standaard waarde" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Standaard Parameter Waarde" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Onderdelen" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "Kan parameters van een vergrendeld onderdeel niet verwijderen" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "Kan de parameters van een vergrendeld onderdeel niet wijzigen" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Kan dit deel niet verwijderen omdat het vergrendeld is" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Kan dit deel niet verwijderen omdat het nog actief is" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Kan dit deel niet verwijderen omdat het in een groep gebruikt is" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "{self}' kan niet worden gebruikt in BOM voor '{parent}' (recursief)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "{parent}' wordt gebruikt in BOM voor '{self}' (recursief)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN moet overeenkomen met regex patroon {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Onderdeel kan geen herziening van zichzelf zijn" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Herzieningen zijn alleen toegestaan voor assemblageonderdelen" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Kan geen revisie maken van een sjabloon onderdeel" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "Bovenliggend onderdeel moet naar dezelfde sjabloon verwijzen" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Voorraadartikel met dit serienummer bestaat al" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Dubbele IPN niet toegestaan in deelinstellingen" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Dubbele onderdeel revisie bestaat al." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Onderdeel met deze naam, IPN en Revisie bestaat al." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Onderdelen kunnen niet worden toegewezen aan categorieën van structurele onderdelen!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Onderdeel naam" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Is een sjabloon" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Is dit deel van een sjabloon?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Is dit een variant van een ander deel?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variant van" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Beschrijving (optioneel)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Sleutelwoorden" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Deel sleutelwoorden om de zichtbaarheid van de zoekresultaten te verbeteren" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Onderdeel Categorie" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Onderdeel revisie of versienummer" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revisie" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Is dit deel een herziening van een ander deel?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Revisie van" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Waar wordt dit item normaal opgeslagen?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Standaard verval datum" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Verlooptijd (in dagen) voor voorraadartikelen van dit deel" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimum voorraad" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Minimaal toegelaten stock niveau" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Eenheden voor dit onderdeel" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Kan dit onderdeel uit andere delen worden gebouwd?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Kan dit onderdeel gebruikt worden om andere onderdelen te bouwen?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Heeft dit onderdeel een tracking voor unieke items?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Kunnen de testresultaten van dit onderdeel tegen dit onderdeel worden geregistreerd?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Kan dit onderdeel worden gekocht van externe leveranciers?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Kan dit onderdeel aan klanten worden verkocht?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Is dit onderdeel actief?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Vergrendelde onderdelen kunnen niet worden bewerkt" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Is dit een virtueel onderdeel, zoals een softwareproduct of licentie?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "Stuklijst BOM gecontroleerd" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Is de BOM voor dit deel geldig?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "BOM checksum" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Checksum van BOM opgeslagen" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOM gecontroleerd door" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "BOM gecontroleerd datum" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Aanmaken gebruiker" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Eigenaar verantwoordelijk voor dit deel" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Verkopen van meerdere" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Valuta die gebruikt wordt voor de cache berekeningen" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimale BOM kosten" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Minimale kosten van onderdelen" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maximale BOM kosten" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Maximale kosten van onderdelen" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimale aankoop kosten" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Minimale historische aankoop kosten" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maximale aanschaf kosten" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Maximum historische aankoop kosten" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimale interne prijs" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Minimale kosten op basis van interne prijsschommelingen" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maximale interne prijs" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Maximale kosten gebaseerd op interne prijsvoordelen" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Minimale leverancier prijs" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Minimale prijs van onderdeel van externe leveranciers" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Maximale leverancier prijs" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Maximale prijs van onderdeel van externe leveranciers" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Minimale variant kosten" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Berekende minimale kosten van variant onderdelen" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Maximale variant kosten" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Berekende maximale kosten van variant onderdelen" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimale kostprijs" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Overschrijf minimale kosten" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maximale kosten" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Overschrijf maximale kosten" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Berekende minimale kosten" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Berekende totale maximale kosten" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Minimale verkoop prijs" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Minimale verkoopprijs gebaseerd op prijsschommelingen" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Maximale verkoop prijs" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Maximale verkoopprijs gebaseerd op prijsschommelingen" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Minimale verkoop prijs" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Minimale historische verkoop prijs" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Maximale verkoop prijs" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Maximale historische verkoop prijs" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Onderdeel voor voorraadcontrole" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Getelde items" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Aantal individuele voorraadvermeldingen op het moment van voorraadcontrole" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Totale voorraad op het moment van voorraadcontrole" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Datum" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Datum waarop voorraad werd uitgevoerd" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Minimale voorraadprijs" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Geschatte minimum kosten van de voorraad op de hand" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maximale voorraadkosten" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Geschatte maximale kosten van de hand van voorraad" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Periodieke verkoopprijs voor onderdelen" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Sjabloon test onderdeel" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Ongeldige sjabloonnaam - moet minstens één alfanumeriek teken bevatten" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Test sjablonen kunnen alleen worden gemaakt voor testbare onderdelen" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Test template met dezelfde sleutel bestaat al voor een deel" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Test naam" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Geef een naam op voor de test" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Test sleutel" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Vereenvoudigde sleutel voor de test" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Test beschrijving" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Voer beschrijving in voor deze test" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Is deze test ingeschakeld?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Vereist" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Is deze test nodig om te doorlopen?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Waarde vereist" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Heeft deze test een waarde nodig bij het toevoegen van een testresultaat?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Vereist bijlage" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Vereist deze test een bestandsbijlage bij het toevoegen van een testresultaat?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Geldige keuzes voor deze parameter (komma gescheiden)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOM item kan niet worden gewijzigd - assemblage is vergrendeld " -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM item kan niet worden gewijzigd - assemblage is vergrendeld" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Selecteer boven liggend onderdeel" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Sub onderdeel" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Selecteer onderdeel dat moet worden gebruikt in BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "BOM hoeveelheid voor dit BOM item" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Dit BOM item is optioneel" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Dit BOM item is verbruikbaar (het wordt niet bijgehouden in build orders)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Totale hoeveelheid" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Extra benodigde hoeveelheid voor een build, rekening houdend met verliezen van de setup" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Attriatie" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Geschatte uitstraling voor een gebouw, uitgedrukt in percentage (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Afronden meerdere" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Afronden met omhoog vereiste productiehoeveelheid naar dichtstbijzijnde meerdere van deze waarde" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Artikelregel referentie" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "BOM item notities" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Controle som" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "BOM lijn controle som" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Goedgekeurd" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Dit BOM item is goedgekeurd" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Wordt overgenomen" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Dit BOM item wordt overgenomen door BOMs voor variant onderdelen" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Voorraaditems voor variant onderdelen kunnen worden gebruikt voor dit BOM artikel" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Hoeveelheid moet een geheel getal zijn voor trackable onderdelen" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Onderdeel moet gespecificeerd worden" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "BOM Item vervangingen bewerken" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Vervanging onderdeel kan niet hetzelfde zijn als het hoofddeel" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Bovenliggend BOM item" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Vervanging onderdeel" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Eerste deel" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Tweede deel" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Selecteer gerelateerd onderdeel" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Opmerking voor deze relatie" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Onderdeel relatie kan niet worden gecreëerd tussen een deel en zichzelf" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Dubbele relatie bestaat al" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Bovenliggende categorie" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Bovenliggende onderdeel categorie" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Subcategorieën" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Resultaten" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Aantal resultaten opgenomen ten opzichte van deze template" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Inkooporder voor dit voorraadartikel" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Bestand is geen afbeelding" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Oorspronkelijk onderdeel" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Selecteer origineel onderdeel om te dupliceren" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Afbeelding kopiëren" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Afbeelding kopiëren van het oorspronkelijke onderdeel" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Copy BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Kopieer materiaal van het oorspronkelijke deel" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Parameter data kopiëren van het originele onderdeel" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Notities kopiëren" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Kopieer notities van het originele deel" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Tests kopiëren" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "Test sjablonen kopiëren van het originele deel" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Eerste voorraad hoeveelheid" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Specificeer de initiële voorraad hoeveelheid voor dit onderdeel. Als het aantal nul is, wordt er geen voorraad toegevoegd." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Eerste voorraad locatie" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Specificeer locatie van de eerste voorraad voor dit onderdeel" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Selecteer leverancier (of laat leeg om niets in te vullen)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Selecteer fabrikant (of laat leeg om niets in te vullen)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Fabrikant artikel nummer" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Geselecteerde onderneming is geen geldige leverancier" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Geselecteerde bedrijf is geen geldige fabrikant" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Fabrikant deel dat overeenkomt met deze MPN bestaat al" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Leveranciersdeel dat overeenkomt met deze SKU bestaat al" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Categorie naam" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Bouwen" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Hoeveelheid van dit deel dat momenteel in productie is" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Er zal een onuitputtelijke hoeveelheid van dit deel worden gebouwd" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Voorraadartikelen" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Revisies" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Totale Voorraad" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Niet toegewezen voorraad" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Variant voorraad" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Dupliceer onderdeel" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Kopieer eerste gegevens uit een ander onderdeel" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Afbeelding kopiëren" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Afbeelding kopiëren van het oorspronkelijke onderdeel" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Copy BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Kopieer materiaal van het oorspronkelijke deel" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Notities kopiëren" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Kopieer notities van het originele deel" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Tests kopiëren" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Test sjablonen kopiëren van het originele deel" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Eerste voorraad" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Maak onderdeel met eerste voorraad" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Leveranciersgegevens" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Aanvankelijke leveranciersinformatie voor dit deel toevoegen" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Categorie parameters kopiëren" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Parameter sjablonen kopiëren uit geselecteerde onderdeel categorie" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Bestaande afbeelding" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Bestandsnaam van een bestaande onderdeel afbeelding" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Afbeeldingsbestand bestaat niet" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Valideer de gehele materiaalbon" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Kan bouwen" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Vereist voor bouworders" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Toegewezen aan bouwen van orders" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Vereist voor verkooporders" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Toegewezen aan verkooporders" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "IPN onderdeel" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "Onderdeel omschrijving" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "Rapport Maken" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Minimale prijs" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Overschrijf berekende waarde voor minimale prijs" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Minimale prijs valuta" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Maximale prijs" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Overschrijf de berekende waarde voor de maximale prijs" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Maximale prijs valuta" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Bijwerken" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Prijzen voor dit onderdeel bijwerken" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Kan niet converteren van de verstrekte valuta naar {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Minimumprijs mag niet hoger zijn dan de maximale prijs" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Maximale prijs mag niet lager zijn dan de minimale prijs" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Selecteer de bovenliggende assemblage" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Selecteer het onderdeel" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Selecteer onderdeel om BOM van te kopiëren" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Bestaande gegevens verwijderen" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Verwijder bestaande BOM items voor het kopiëren" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Inclusief overgenomen" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Inclusief stuklijst BOM items die worden overgenomen van getemplated onderdelen" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Ongeldige regels overslaan" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Schakel deze optie in om ongeldige rijen over te slaan" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Verwijder vervangend deel" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopieer vervangende onderdelen bij dubbele stuklijst BOM items" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Lage voorraad melding" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "De beschikbare voorraad voor {part.name} is onder het ingestelde minimumniveau gedaald" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "Lage voorraad melding" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "U heeft 1 voorraad product dat de vervaldatum nadert" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "U hebt {item_count} voorraaditems die hun vervaldatum naderen" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "Geen vervaldatum" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "{abs(days_diff)} dagen geleden" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Verloopt vandaag" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} dagen" @@ -7012,7 +7452,7 @@ msgstr "Voorbeeld" msgid "Installed" msgstr "Geïnstalleerd" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "De plug-in kan niet worden verwijderd omdat deze momenteel actief is" @@ -7024,23 +7464,23 @@ msgstr "Geen actie gespecificeerd" msgid "No matching action found" msgstr "Geen overeenkomende actie gevonden" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Geen overeenkomst gevonden voor streepjescodegegevens" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Overeenkomst gevonden voor streepjescodegegevens" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Model wordt niet ondersteund" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Model instantie niet gevonden" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Barcode komt overeen met bestaand item" @@ -7056,51 +7496,67 @@ msgstr "Geen overeenkomende leveranciers onderdelen gevonden" msgid "Multiple matching supplier parts found" msgstr "Meerdere overeenkomende leveranciers onderdelen gevonden" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Geen overeenkomende plug-in gevonden voor barcode gegevens" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Overeenkomende leverancier onderdeel" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Regel item is al ontvangen" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Er komt geen plug-in overeen met de barcode van de leverancier" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Meerdere overeenkomende regelitems gevonden" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Geen overeenkomend voorraaditem gevonden" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Geen verkooporder opgegeven" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Streepjescode komt niet overeen met een bestaand voorraadartikel" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Voorraad item komt niet overeen met regelitem" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Onvoldoende voorraad beschikbaar" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Voorraad item toegewezen aan verkooporder" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Te weinig informatie" @@ -7109,23 +7565,23 @@ msgstr "Te weinig informatie" msgid "Found matching item" msgstr "Gevonden overeenkomend item" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Leveranciersdeel komt niet overeen met regelitem" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Regelitem is al voltooid" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Verdere informatie vereist om regelitem te ontvangen" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Inkoopregel ontvangen" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Kon geen regelitem ontvangen" @@ -7262,21 +7718,21 @@ msgid "Provides native support for barcodes" msgstr "Biedt ondersteuning voor barcodes" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7306,11 +7762,11 @@ msgstr "Korte barcode voorvoegsel" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Aanpassen van prefix voor korte streepjescodes, kan handig zijn voor omgevingen met meerdere InvenTree instanties" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "Automatisch builds aanmaken" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "Automatisch bouworders voor assemblages aanmaken" @@ -7508,74 +7964,82 @@ msgid "Include Variant Items" msgstr "Inclusief variant items" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "Voeg gedeeltelijk variant voorraad toe aan de prijsberekeningen." +msgid "Include part variant stock in stocktake data" +msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "Voorraadexporteur onderdelen" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "Exporteerder voor voorraadgegevens van onderdelen" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "Minimale kostprijs" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "Maximale kosten" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "Minimale totale kosten" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "Maximale totale kosten" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "InvenTree meldingen" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "Geïntegreerde UI notificatiemethoden" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree e-mail notificaties" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "Geïntegreerde methoden voor e-mailmeldingen" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "Email notificaties toestaan" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "E-mailberichten naar deze gebruiker sturen toestaan" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree slack meldingen" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "Geïntegreerde Slack meldingsmethoden" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "Slack inkomende webhook url" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL die wordt gebruikt om berichten te verzenden naar een slack kanaal" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Open link" @@ -7629,12 +8093,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Biedt ondersteuning voor het drukken van PDF labels" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Foutopsporing modus" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Schakel debug modus in - retourneert ruwe HTML in plaats van PDF" @@ -7654,55 +8118,55 @@ msgstr "laatst gebruikt" msgid "Options" msgstr "Opties" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Paginaformaat voor het label blad" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Labels overslaan" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Dit aantal labels bij het afdrukken van labels overslaan" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Rand" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Print een rand rond elk label" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Liggend" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Print het label blad in liggende modus" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Paginamarges" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Marge rondom de pagina in mm" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree label plaat printer" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Arrays multiple labels op een enkele plaat" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Label is te groot voor pagina grootte" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Geen labels gegenereerd" @@ -7754,77 +8218,85 @@ msgstr "Biedt ondersteuning voor het scannen van TME barcodes " msgid "The Supplier which acts as 'TME'" msgstr "De leverancier die als \"TME” optreedt " -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Plug-in installatie is uitgeschakeld" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Plug-in succesvol geïnstalleerd" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plug-in geïnstalleerd in {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "De plug-in is niet gevonden in het register" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "De plug-in is geen verpakte plug-in" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Naam van plug-in pakket niet gevonden" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Alleen medewerker gebruikers kunnen plug-ins beheren" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Verwijderen van plug-in is uitgeschakeld" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "De plug-in kan niet worden verwijderd omdat deze momenteel actief is" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "De plug-in kan niet gedeïnstalleerd worden omdat deze verplicht is" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "De plug-in kan niet worden gedeïnstalleerd omdat het een voorbeeld plug-in is" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "De plug-in kan niet worden gedeïnstalleerd omdat het een ingebouwde plug-in is" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "De plug-in is niet geïnstalleerd" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Plug-in installatie niet gevonden" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Deïnstalleerde plug-in succesvol" @@ -7872,25 +8344,25 @@ msgstr "Mandatory Plugin" msgid "Package Plugin" msgstr "Pakket plug-in" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Plug-in" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Geen auteur gevonden" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "De plug-in '{p}' is niet compatibel met de huidige InvenTree versie {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "De plug-in vereist minimaal versie {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plug-in vereist op de hoogste versie {v}" @@ -8115,176 +8587,184 @@ msgstr "Configuratie verwijderen" msgid "Delete the plugin configuration from the database" msgstr "Verwijder de plug-in configuratie uit de database" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "De gebruiker waarvoor deze instelling van toepassing is" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Items" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Plug-in niet gevonden" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Plug-in ondersteunt geen label printen" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Ongeldige label afmetingen" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Geen geldige items aan de template verstrekt" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Juridisch" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Brief" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Sjabloonbestand met deze naam bestaat al" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Template naam" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Template beschrijving" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Revisie nummer (auto verhogen)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Bevestig aan het model bij afdrukken" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Sla rapport output op als bijlage ten opzichte van gekoppelde model instantie bij afdrukken" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Bestandsnaam Patroon" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Patroon voor het genereren van bestandsnamen" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Template is ingeschakeld" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Doel type model voor sjabloon" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filters" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Sjabloon zoekfilters (door komma's gescheiden lijst van sleutel=waarde paren)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Sjabloon bestand" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Standaard paginagrootte voor PDF rapport" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Rapportage weergeven in liggende stand" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "Samenvoegen" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "Geef een enkel rapport tegen geselecteerde items" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Rapport gegenereerd door template {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "Sjabloon syntaxis fout" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "Fout bij het renderen rapport" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Fout bij genereren rapport" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "Fout bij samenvoegen rapport uitvoer" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Breedte [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Label breedte, gespecificeerd in mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Hoogte [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Label hoogte, gespecificeerd in mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Fout afdrukken van labels" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Tekstfragment" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Rapporteer snippet bestand" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Snippet bestandsbeschrijving" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Asset" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Rapporteer asset bestand" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Beschrijving asset bestand" @@ -8292,23 +8772,23 @@ msgstr "Beschrijving asset bestand" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Selecteer rapport template" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Lijst van primaire productsleutels op te nemen in het verslag" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Selecteer label sjabloon" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Plug-in printen" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Selecteer de plug-in voor het afdrukken van labels" @@ -8339,13 +8819,10 @@ msgstr "Benodigde materialen" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Afbeelding onderdeel" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Uitgegeven" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Vereist Voor" @@ -8381,8 +8858,8 @@ msgstr "Totaal" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serienummer" @@ -8406,7 +8883,7 @@ msgstr "Rapport voorraadcontrole" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Geïnstalleerde items" @@ -8439,810 +8916,922 @@ msgstr "Geen resultaat (verplicht)" msgid "No result" msgstr "Geen resultaat" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Afbeelding bestand niet gevonden" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image tag vereist een onderdeel instantie" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "bedrijf_imagetag vereist een bedrijfsinstantie" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Filter op locatie diepte" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Filter op topniveau locaties" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Inclusief sublocaties in gefilterde resultaten" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Bovenliggende locatie" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filter op bovenliggende locatie" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Naam van onderdeel (hoofdletter ongevoelig)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Naam van onderdeel bevat (hoofdletter ongevoelig)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Naam onderdeel (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "Deel IPN (hoofdletter ongevoelig)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "Onderdeel IPN bevat (hoofdletter ongevoelig)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "Deel IPN (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Minimale voorraad" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Maximale voorraad" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Status code" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Externe locatie" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Verbruikt door productieorder" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Geïnstalleerd in een ander voorraadartikel" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Boomstructuur onderdeel" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Eerder bijgewerkt" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Bijgewerkt na" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Voorraadcontrole voor" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Voorraadcontrole na" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Vervaldatum voor" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Vervaldatum na" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Verouderd" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "Voorraad PK om dit item en al zijn afstammelingen uit te sluiten" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "Cascade locaties" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "Indien waar, inclusief items op de onderliggende locaties van de opgegeven locatie" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Filter op numerieke locatie ID of de letterlijke 'null'" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Hoeveelheid is vereist" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Geldig onderdeel moet worden opgegeven" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Het opgegeven leveranciers onderdeel bestaat niet" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Het leveranciersdeel heeft een pakketgrootte gedefinieerd, maar vlag use_pack_size niet ingesteld" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Serienummers kunnen niet worden meegeleverd voor een niet traceerbaar onderdeel" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "Inclusief geïnstalleerde" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Als correct, geef testresultaten voor items die onder het opgegeven voorraadartikel zijn geïnstalleerd" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "Filter op numerieke voorraadartikel ID" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Voorraadartikel met ID {id} bestaat niet" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "Inclusief Onderdeel varianten" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "Datum na" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "Datum voor" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Voorraad locatie soort" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Voorraad locatie soorten" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Standaardpictogram voor alle locaties waarvoor geen pictogram is ingesteld (optioneel)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Voorraadlocatie" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Voorraadlocaties" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Eigenaar" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Selecteer eigenaar" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Voorraaditems kunnen niet direct worden geplaatst op een structurele voorraadlocatie, maar kunnen zich op onderliggende locaties bevinden." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Extern" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Dit is een externe voorraadlocatie" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Locatie type" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Voorraad locatie type van deze locatie" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "U kunt deze voorraadlocatie niet structureel maken omdat sommige voorraadartikelen er al in liggen!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field} bestaat niet" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Onderdeel moet gespecificeerd worden" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Voorraaditems kunnen niet worden geplaatst in structurele voorraadlocaties!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Voorraadartikel kan niet worden aangemaakt voor virtuele onderdelen" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Onderdeel type ('{self.supplier_part.part}') moet {self.part} zijn" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Hoeveelheid moet 1 zijn voor item met een serienummer" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Serienummer kan niet worden ingesteld als de hoeveelheid groter is dan 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Item kan niet tot zichzelf behoren" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Item moet een bouw referentie hebben als is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Bouw referentie verwijst niet naar hetzelfde deel object" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Bovenliggend voorraad item" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Basis onderdeel" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Selecteer een leveranciersdeel voor dit voorraadartikel" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Waar bevindt zich dit voorraaditem?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Het verpakken van dit voorraaditem is opgeslagen in" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Geïnstalleerd in" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Is dit item geïnstalleerd in een ander item?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Serienummer van dit item" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Batch code voor dit voorraaditem" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Voorraad hoeveelheid" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Bron Bouw" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Build voor dit voorraaditem" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Verbruikt door" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Bestelling bouwen welke dit voorraadartikel heeft verbruikt" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Inkooporder Bron" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Inkooporder voor dit voorraadartikel" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Bestemming Verkooporder" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Vervaldatum voor voorraadartikel. Voorraad zal worden beschouwd als verlopen na deze datum" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Verwijderen bij leegmaken" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Verwijder dit voorraadproduct wanneer de voorraad is leeg" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Enkele eenheidsprijs van de aankoop op het moment van aankoop" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Omgezet tot onderdeel" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "Hoeveelheid overschrijdt beschikbare voorraad" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "Kan voorraad niet toewijzen aan structurele locatie" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Onderdeel is niet ingesteld als traceerbaar" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Hoeveelheid moet heel getal zijn" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Hoeveelheid mag niet hoger zijn dan de beschikbare voorraad ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Serienummers moeten als lijst worden opgegeven" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Hoeveelheid komt niet overeen met serienummers" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "Kan voorraad niet toewijzen aan structurele locatie" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Testsjabloon bestaat niet" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Voorraadartikel is toegewezen aan een verkooporder" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Voorraad item is geïnstalleerd in een ander item" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Voorraadartikel bevat andere producten" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Voorraadartikel is aan een klant toegewezen" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Voorraad item is momenteel in productie" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Geserialiseerde voorraad kan niet worden samengevoegd" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Dupliceer voorraadartikelen" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Voorraadartikelen moeten hetzelfde onderdeel verwijzen" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Voorraadartikelen moeten verwijzen naar dezelfde leveranciersdeel" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "De voorraad statuscodes moeten overeenkomen" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Voorraadartikel kan niet worden verplaatst omdat het niet op voorraad is" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Voorraad item volgen" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Item notities" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Resultaat voorraad test resultaten" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Waarde moet voor deze test worden opgegeven" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Bijlage moet worden geüpload voor deze test" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "Ongeldige waarde voor deze test" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Test resultaat" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Test uitvoer waarde" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Test resultaat bijlage" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Test notities" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Test station" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "De identificatie van het teststation waar de test werd uitgevoerd" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Gestart" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Het tijdstip van de start test" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Afgerond" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Het tijdstip van de afgeronde test" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Gegenereerde batch code" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Selecteer build order" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Selecteer het voorraaditem om een batchcode te genereren voor" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Selecteer locatie om batch code voor te genereren" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Selecteer onderdeel voor het genereren van batchcode voor" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Selecteer bestelling" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Voer aantal voor batch code in" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Gegenereerd serienummer" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Selecteer onderdeel voor het genereren van het serienummer voor" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Aantal serienummers om te genereren" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Test template voor dit resultaat" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "Geen overeenkomende test gevonden voor dit onderdeel" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "SjabloonID of testnaam moet worden opgegeven" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "De testtijd kan niet eerder zijn dan de starttijd van de test" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Bovenliggend Item" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Bovenliggende voorraad item" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Gebruik pakketgrootte bij het toevoegen: de hoeveelheid gedefinieerd is het aantal pakketten" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "Gebruik pakketgrootte" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Voer serienummers voor nieuwe items in" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Leverancier artikelnummer" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Verlopen" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Onderliggende items" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Items volgen" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Inkoopprijs van dit voorraadartikel, per eenheid of pakket" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Aantal voorraaditems om serienummers voor te maken" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "Geen voorraad item opgegeven" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Hoeveelheid mag niet hoger zijn dan de beschikbare voorraad ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Locatie van bestemming" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Serienummers kunnen niet worden toegewezen aan dit deel" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Serienummers bestaan al" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Selecteer voorraaditem om te installeren" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Te installeren hoeveelheid" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Voer de te installeren hoeveelheid items in" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Transactienotitie toevoegen (optioneel)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Te installeren hoeveelheid moet minimaal 1 zijn" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Voorraadartikel is niet beschikbaar" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Het geselecteerde deel zit niet in de materialen lijst" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "De te installeren hoeveelheid mag niet groter zijn dan de beschikbare hoeveelheid" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Bestemmingslocatie voor verwijderd item" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Selecteer onderdeel om voorraaditem om te zetten in" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Het geselecteerde deel is geen geldige optie voor de omzetting" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Kan voorraadartikel niet converteren met toegewezen leverancier deel" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Voorraad status code" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Selecteer onderdeel om voorraaditem om te zetten in" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Het geselecteerde deel is geen geldige optie voor de omzetting" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Kan voorraadartikel niet converteren met toegewezen leverancier deel" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Selecteer voorraadartikelen om status te wijzigen" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Geen voorraaditems geselecteerd" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Sublocaties" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Bovenliggende voorraad locatie" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Onderdeel moet verkoopbaar zijn" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Artikel is toegewezen aan een verkooporder" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Artikel is toegewezen aan een productieorder" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Klant om voorraadartikelen toe te wijzen" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Geselecteerde bedrijf is geen klant" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Voorraad toewijzing notities" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Een lijst met voorraad artikelen moet worden opgegeven" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Voorraad samenvoegen notities" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Niet overeen komende leveranciers toestaan" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Toestaan dat voorraadartikelen met verschillende leveranciers onderdelen worden samengevoegd" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Sta onjuiste status toe" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Toestaan dat voorraadartikelen met verschillende statuscodes worden samengevoegd" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Er moeten ten minste twee voorraadartikelen worden opgegeven" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Geen wijziging" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Voorraaditem primaire sleutel waarde" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Voorraad artikel is niet op voorraad" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "Voorraad artikel is al in voorraad" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "Hoeveelheid mag niet negatief zijn" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Voorraad transactie notities" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "Samenvoegen in bestaande voorraad" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Voorraad transactie notities" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "Voeg indien mogelijk geretourneerde items samen in bestaande voorraad" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Volgend serienummer" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Vorig serienummer" @@ -9343,42 +9932,50 @@ msgid "Merged stock items" msgstr "Samengevoegde voorraadartikelen" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Geconverteerd naar variant" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Product aangemaakt" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Product voltooid" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Build order uitvoer afgewezen" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Verbruikt door productieorder" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Verzonden onder verkooporder" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Ontvangen onder verkooporder" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Geretourneerd onder retourorder" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Naar klant verzonden" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Geretourneerd door klant" @@ -9528,19 +10125,19 @@ msgstr "Gebruikers" msgid "Select which users are assigned to this group" msgstr "Selecteer welke gebruikers zijn toegewezen aan deze groep" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Persoonlijke info" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Machtigingen" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Belangrijke data" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Token is ingetrokken" @@ -9548,279 +10145,283 @@ msgstr "Token is ingetrokken" msgid "Token has expired" msgstr "Token is verlopen" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API Token" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API tokens" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Token naam" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Aangepaste token naam" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Token vervaldatum" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Laatst gezien" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Laatste keer dat het token werd gebruikt" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Intrekken" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Toestemming set" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Weergeven" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Machtiging om items te bekijken" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Toevoegen" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Machtiging om items toe te voegen" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Wijzigen" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Machtigingen om items te bewerken" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Verwijderen" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Toestemming om items te verwijderen" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Bot" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Intern" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Gast" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Taal" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Voorkeurstaal voor gebruiker" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Thema" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Instellingen voor webinterface als JSON - niet handmatig bewerken!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Widget" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Instellingen voor de dashboard widgets als JSON - wijzig niet handmatig!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Naam weergeven" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Gekozen weergavenaam voor de gebruiker" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Functie" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Titel of positie hoofdtaken" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Gebruiker status bericht" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Informatie over locatie gebruiker" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "Gebruiker gebruikt actief het systeem" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Voorkeursinformatie voor de gebruiker" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Gebruikers type" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "Welk type gebruiker is dit?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organisatie" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Gebruikers primaire organisatie/affiliatie" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Primaire groep" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Primaire groep van de gebruiker" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Administrator" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Inkooporders" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Verkooporders" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Retour orders" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Gebruikersnaam" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Voornaam :" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Voornaam van de gebruiker" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Achternaam" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Achternaam van de gebruiker" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "E-mailadres van de gebruiker" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Administrator " -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Is deze gebruiker een administrator " -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Is dit gebruikersaccount actief" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Enkel een supergebruiker kan dit veld aanpassen" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Wachtwoord" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Wachtwoord voor de gebruiker" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "Overschrijf waarschuwing" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Overschrijf de waarschuwing over wachtwoord regels" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "U hebt geen toestemming om gebruikers aan te maken" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Je account is aangemaakt." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Gebruik de wachtwoordreset functie om in te loggen" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Welkom bij InvenTree" diff --git a/src/backend/InvenTree/locale/no/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/no/LC_MESSAGES/django.po index a522c27bd5..4694da6457 100644 --- a/src/backend/InvenTree/locale/no/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/no/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Norwegian\n" "Language: no_NO\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API-endepunkt ikke funnet" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Brukeren har ikke rettigheter til å se denne modellen" @@ -65,150 +69,155 @@ msgstr "Bekreft e-postaddresse" msgid "You must type the same email each time." msgstr "Du må angi samme e-post hver gang." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Den oppgitte primære e-postadressen er ikke gyldig." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Det oppgitte e-postdomenet er ikke godkjent." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Ugyldig enhet angitt ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Ingen verdi angitt" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Kunne ikke konvertere {original} til {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Ugyldig mengde oppgitt" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Feildetaljer kan finnes i admin-panelet" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Oppgi dato" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Notater" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Verdi '{name}' vises ikke i mønsterformat" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Angitt verdi samsvarer ikke med påkrevd mønster: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Tom serienummerstreng" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Duplisert serienummer" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Gruppesekvens {group} overskrider tillatt antall ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Ingen serienummer funnet" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Fjern HTML-tagger fra denne verdien" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Tilkoblingsfeil" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Serveren svarte med ugyldig statuskode" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Det har oppstått et unntak" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Serveren svarte med ugyldig \"Content-Length\"-verdi" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Bildestørrelsen er for stor" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Bildenedlasting overskred maksimal størrelse" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Ekstern server returnerte tomt svar" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Angitt URL er ikke en gyldig bildefil" @@ -216,159 +225,203 @@ msgstr "Angitt URL er ikke en gyldig bildefil" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-post" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Feil under validering av utvidelse" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata må være et python dict-objekt" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Utvidelse-metadata" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON-metadatafelt, for bruk av eksterne utvidelser" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Uriktig formatert mønster" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Ukjent formatnøkkel spesifisert" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Mangler nødvendig formatnøkkel" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Referansefeltet kan ikke være tomt" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referansen må samsvare påkrevd mønster" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referansenummeret er for stort" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Ugyldig valg" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Navn" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Beskrivelse" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Beskrivelse (valgfritt)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Sti" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplikatnavn kan ikke eksistere under samme overordnede" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown-notater (valgfritt)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Strekkodedata" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Tredjeparts strekkodedata" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Strekkode-hash" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Unik hash av strekkodedata" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Eksisterende strekkode funnet" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Serverfeil" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "En feil har blitt logget av serveren." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Bilde" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Må være et gyldig tall" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Velg valuta ut fra tilgjengelige alternativer" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Ugyldig verdi" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Kopier parametere" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabisk" @@ -521,46 +574,48 @@ msgstr "Kinesisk (forenklet)" msgid "Chinese (Traditional)" msgstr "Kinesisk (tradisjonell)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Ugyldig fysisk enhet" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Ikke en gyldig valutakode" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Ordrestatus" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Overordnet produksjon" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Del" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategori" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Produksjonen må avbrytes før den kan slettes" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Forbruksvare" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Valgfritt" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Sammenstilling" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Spores" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Tildelt" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Tilgjengelig" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "I bestilling" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Produksjonsordre" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Plassering" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Produksjonsordrer" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Sammenstillings-BOMen er ikke godkjent" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Produksjonsordre kan ikke opprettes for en inaktiv del" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Produksjonsordre kan ikke opprettes for en ulåst del" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Ansvarlig bruker eller gruppe må spesifiseres" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Produksjonsordrens del kan ikke endres" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Produksjonsordre-referanse" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referanse" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Kort beskrivelse av produksjonen (valgfritt)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Velg del å produsere" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Salgsordrereferanse" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Kildeplassering" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Velg plassering å ta lagerbeholdning fra for denne produksjonen (la stå tomt for a ta fra alle lagerplasseringer)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Fullført plassering" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Velg plassering der fullførte artikler vil bli lagret" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Produksjonsmengde" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Antall lagervarer å produsere" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Fullførte artikler" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Antall lagervarer som er fullført" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Produksjonsstatus" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Produksjonsstatuskode" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Batchkode" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Batchkode for denne produksjonsartikkelen" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Opprettelsesdato" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Forventet sluttdato" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Måldato for ferdigstillelse. Produksjonen vil være forfalt etter denne datoen." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Fullført dato" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "fullført av" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Utstedt av" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Brukeren som utstedte denne produksjonsordren" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ansvarlig" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Bruker eller gruppe ansvarlig for produksjonsordren" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Ekstern lenke" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Lenke til ekstern URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Produksjonsprioritet" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Produksjonsordrens prioritet" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Prosjektkode" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Prosjektkode for denne produksjonsordren" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Kunne ikke delegere bort oppgaven for å fullføre tildelinger" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Produksjonsordre {build} er fullført" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "En produksjonsordre er fullført" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Serienumre må angis for sporbare deler" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Ingen produksjonsartikkel spesifisert" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Produksjonsartikkelen er allerede fullført" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Produksjonsartikkelen samsvarer ikke med produksjonsordren" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Mengden må være større enn null" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Kvantitet kan ikke være større enn utgangsantallet" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Produksjonsartikkel {serial} har ikke bestått alle påkrevde tester" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Tilgjengelig antall ({q}) overskredet" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Produksjonsartikkel" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Produksjonsobjekt" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Produksjonsobjekt" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Antall" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Påkrevd antall for produksjonsordre" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Produksjonselement må spesifisere en produksjonsartikkel, da master-del er merket som sporbar" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Valgt lagervare samsvarer ikke med BOM-linjen" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Mengden må være 1 for serialisert lagervare" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Tildelt antall ({q}) kan ikke overstige tilgjengelig lagerbeholdning ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Lagervaren er overtildelt" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Lagervare" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Kildelagervare" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Lagerantall å tildele til produksjonen" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Monteres i" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Lagervare for montering" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Delnavn" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Produksjonsartikkel" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Produksjonsartikkel samsvarer ikke med overordnet produksjon" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Resultatdel samsvarer ikke med produksjonsordredel" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Denne produksjonsartikkelen er allerede fullført" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Denne produksjonsartikkelen er ikke fullt tildelt" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Angi antall for produksjonsartikkel" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Heltallsverdi kreves for sporbare deler" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Heltallsverdi kreves, da stykklisten inneholder sporbare deler" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Serienummer" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Angi serienummer for produksjonsartikler" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Lagerplassering for produksjonsartikkel" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Automatisk tildeling av serienummer" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatisk tildeling av nødvendige artikler med tilsvarende serienummer" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Følgende serienummer finnes allerede eller er ugyldige" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "En liste over produksjonsartikler må oppgis" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Lagerplassering for skrotede produksjonsartikler" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Forkast tildelinger" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Forkast tildelinger fra skrotede produksjonsartikler" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Grunn for skroting av produksjonsartikler" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Plassering for ferdige produksjonsartikler" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Godta ufullstendig tildeling" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Fullfør artikler dersom lagerbeholdning ikke er fullt tildelt" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Bruk tildelt lagerbeholdning" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Bruk all lagerbeholdning som allerede er tildelt denne produksjonen" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Fjern ufullstendige artikler" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Slett alle produksjonsartikler som ikke er fullført" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Ikke tillatt" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Godta som brukt av denne produksjonsordren" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Fjern tildeling før produksjonsordren fullføres" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Overtildelt lagerbeholdning" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Hvordan vil du håndtere ekstra lagervarer tildelt produksjonsordren" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Noen lagervarer har blitt overtildelt" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Godta ikke tildelt" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Godta at lagervarer ikke er fullt tildelt til denne produksjonsordren" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Nøvendig lagerbeholdning er ikke fullt tildelt" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Godta uferdig" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Godta at nødvendig antall fullførte produksjonsartikler ikke er nådd" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Nødvendig produksjonsmengde er ikke nådd" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Produksjonsordren har uferdige artikler" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Produksjonslinje" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Produksjonsartikkel" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Produksjonsartikkel må peke til samme produksjon" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Produksjonsartikkel" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part må peke på den samme delen som produksjonsordren" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Artikkelen må være på lager" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Tilgjengelig antall ({q}) overskredet" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Produksjonsartikkel må spesifiseres for tildeling av sporede deler" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Produksjonsartikkel kan ikke spesifiseres for tildeling av usporede deler" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Tildelingsartikler må oppgis" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Lagerplassering hvor deler skal hentes (la stå tomt for å ta fra alle plasseringer)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Eksluderer plassering" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Ekskluder lagervarer fra denne valgte plasseringen" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Utskiftbar lagerbeholdning" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Lagervarer ved flere plasseringer kan brukes om hverandre" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Erstatning-lagerbeholdning" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Tilatt tildelling av erstatningsdeler" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Valgfrie artikler" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Tildel valgfrie BOM-artikler til produksjonsordre" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "BOM-referanse" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Leverandørdel" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Tildelt antall" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Produksjonsreferanse" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Delkategorinavn" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Sporbar" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Nedarvet" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Tillat Varianter" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "BOM-artikkel" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "I produksjon" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Ekstern lagerbeholdning" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Tilgjengelig lagerbeholdning" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Tilgjengelige erstatningsvarer" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Tilgjengelige variantvarer" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Ventende" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Produksjon" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Kansellert" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Fullført" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Produksjonsordre {build} er fullført" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "En produksjonsordre er fullført" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Lagerbeholdning kreves for produksjonsordre" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Forfalt produksjonsordre" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Produksjonsordre {bo} er nå forfalt" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "Er lenke" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Er fil" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Brukeren har ikke tillatelse til å slette dette vedlegget" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Ugyldig valutakode" @@ -1539,15 +1641,20 @@ msgstr "Ingen gyldige valutakoder angitt" msgid "No plugin" msgstr "Ingen programtillegg" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Etikett for prosjektkode" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Oppdatert" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Tidsstempel for forrige oppdatering" @@ -1567,794 +1674,844 @@ msgstr "Unik prosjektkode" msgid "Project description" msgstr "Prosjektbeskrivelse" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Bruker eller gruppe ansvarlig for dette prosjektet" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Innstillings verdi" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Valgt verdi er ikke et gyldig alternativ" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Verdien må være en boolsk verdi" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Verdien må være et heltall" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Nøkkelstreng må være unik" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Bruker" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Antall for prisbrudd" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Pris" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Enhetspris på spesifisert antall" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Endepunkt" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Endepunktet hvor denne webhooken er mottatt" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Navn for webhooken" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktiv" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Bruker eller gruppe ansvarlig for dette prosjektet" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Innstillings verdi" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Valgt verdi er ikke et gyldig alternativ" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Verdien må være en boolsk verdi" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Verdien må være et heltall" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Nøkkelstreng må være unik" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Bruker" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Antall for prisbrudd" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Pris" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Enhetspris på spesifisert antall" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Endepunkt" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Endepunktet hvor denne webhooken er mottatt" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Navn for webhooken" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Er webhooken aktiv" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Sjetong" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Nøkkel for tilgang" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Hemmelig" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Delt hemmlighet for HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Melding ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Unik Id for denne meldingen" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Vert" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Verten denne meldingen ble mottatt fra" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Tittel" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Overskrift for denne meldingen" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Brødtekst" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Innholdet i meldingen" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Endepunktet meldingen ble mottatt fra" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Arbeidet med" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Var arbeidet med denne meldingen ferdig?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Tittel" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Lenke" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publisert" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Forfatter" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Sammendrag" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Les" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Er dette nyhetselementet lest?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Bildefil" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Enhetssymbolet må være unikt" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Enhetsnavn må være en gyldig identifikator" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Enhetsnavn" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Valgfritt enhetssymbol" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definisjon" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Enhetsdefinisjon" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Vedlegg" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Fil mangler" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Mangler eksternlenke" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Velg fil å legge ved" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Vedleggskommentar" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Opplastet dato" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Datoen som filen ble lastet opp" -#: common/models.py:2118 -msgid "File size" -msgstr "Filstørrelse" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "Filstørrelse i byte" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "Ugyldig modelltype spesifisert for vedlegg" - -#: common/models.py:2177 -msgid "Custom State" +#: common/models.py:2178 +msgid "Is image" msgstr "" -#: common/models.py:2178 -msgid "Custom States" +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Filstørrelse" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "Filstørrelse i byte" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "Ugyldig modelltype spesifisert for vedlegg" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Verdi" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Opprettet" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Sist oppdatert" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Parametermal" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Sjekkboksparameter kan ikke ha enheter" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Sjekkboksparameter kan ikke ha valg" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Valg må være unike" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Navn på parametermal må være unikt" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Parameternavn" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Enheter" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Fysisk enheter for denne parameteren" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Parameterbeskrivelse" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Sjekkboks" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Er dette parameteret en sjekkboks?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Valg" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Gyldige valg for denne parameteren (kommaseparert)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Aktivert" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Ugyldig valg for parameterverdi" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Mal" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Parameterverdi" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Notat" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Valgfritt notatfelt" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Kontekst" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Resultat" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Nøkkel" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} kansellert" msgid "A order that is assigned to you was canceled" msgstr "En ordre som er tildelt til deg ble kansellert" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Artikler mottatt" @@ -2388,104 +2545,100 @@ msgstr "Artikler har blitt mottatt mot en innkjøpsordre" msgid "Items have been received against a return order" msgstr "Artikler har blitt mottatt mot en returordre" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Kjører" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Ventende oppgaver" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Planlagte oppgaver" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Mislykkede oppgaver" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Oppgave-ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Unik oppgave-ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Lås" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Låsetidspunkt" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Oppgavenavn" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funksjon" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Funksjonsnavn" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumenter" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Oppgaveargumenter" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Nøkkelordargumenter" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Nøkkelordargumenter for oppgave" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Filnavn" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Modelltype" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Brukeren har ikke tillatelse tillatelse å opprette eller endre vedlegg for denne modellen" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "Ingen gruppe" @@ -2614,13 +2767,13 @@ msgstr "Oppdateringsintervall for valuta" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Hvor ofte valutakurser skal oppdateres (sett til null for å deaktiverere)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dager" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Valgt valutaoppdaterings-plugin" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Streng URL-validering" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "Delrevisjoner" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "Aktiver revisjonsfeltet for Del" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 +msgid "Part Revisions" +msgstr "Delrevisjoner" + +#: common/setting/system.py:413 +msgid "Enable revision field for Part" +msgstr "Aktiver revisjonsfeltet for Del" + +#: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Regulært uttrykksmønster for matching av internt delnummer" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Tilat duplikat av internt delnummer" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Tillat flere deler å dele samme interne delnummer" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Tillat redigering av internt delnummer" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Tillat endring av IPN-verdien mens du redigerer en del" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Kopier BOM-data fra del" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Kopier BOM-data som standard når du dupliserer en del" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Kopier parameterdata fra del" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Kopier parameterdata som standard ved duplisering av en del" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Kopier testdata fra del" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Kopier testdata som standard ved duplisering av en del" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kopier designmaler for kategoriparametere" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Kopier parametermaler for kategori ved oppretting av en del" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Deler er maler som standard" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Deler kan settes sammen fra andre komponenter som standard" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Deler kan bli brukt som underkomponenter som standard" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Kjøpbar" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Deler er kjøpbare som standard" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Salgbar" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Deler er salgbare som standard" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Deler er sporbare som standard" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuelle" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Deler er virtuelle som standard" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Vis relaterte deler" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Vis relaterte deler i en del" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Innledende lagerbeholdningsdata" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Tillat oppretting av innledende lagerbeholdning når en ny del opprettes" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Innledende leverandørdata" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Tillat oppretting av innledende leverandørdata når en ny del opprettes" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Visningsformat for delnavn" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Format for å vise delnavnet" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Standardikon for delkategorier" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Standardikon for delkategorier (tomt betyr ingen ikon)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Minimum antall desimalplasser for priser" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Minimum antall desimalplasser som skal vises når man gjengir prisdata" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Maksimalt antall desimalplasser for priser" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Maksimalt antall desimalplasser som skal vises når man gjengir prisdata" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Bruk leverandørpriser" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Inkluder leverandørprisbrudd i beregninger av totalpriser" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Innkjøpshistorikkoverstyring" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Historiske innkjøpspriser overstyrer leverandørprisnivåer" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Bruk lagervarepriser" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Bruk priser fra manuelt innlagte lagervarer for prisberegninger" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Lagervare prisalder" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Unnta lagervarer som er eldre enn dette antall dager fra prisberegninger" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Bruk Variantpriser" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Inkluder variantpriser i beregninger av totale priser" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Kun aktive varianter" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Bruk kun aktive variantdeler til beregning av variantprising" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Intervall for rekalkulering av priser" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Antall dager før delpriser blir automatisk oppdatert" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Interne Priser" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Aktiver interne priser for deler" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Intern prisoverstyring" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Hvis tilgjengelig, overstyrer interne priser kalkulering av prisområde" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Aktiver etikettutskrift" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Aktiver utskrift av etiketter fra nettleseren" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Etikettbilde-DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "DPI-oppløsning når når det genereres bildefiler for sending til utvidelser for etikettutskrift" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Aktiver Rapporter" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Aktiver generering av rapporter" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Feilsøkingsmodus" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Generer rapporter i feilsøkingsmodus (HTML-output)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Sidestørrelse" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Standard sidestørrelse for PDF-rapporter" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Tving parameterenheter" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Hvis det er angitt en enhet, skal parameterverdiene samsvare med de angitte enhetene" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Globalt Unike Serienummer" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Serienummer for lagervarer må være globalt unike" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Slett oppbrukt lagerbeholdning" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Batchkodemal" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Mal for generering av standard batchkoder for lagervarer" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Lagerbeholdning utløper" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Aktiver funksjonalitet for utløp av lagerbeholdning" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Selg utløpt lagerbeholdning" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Tillat salg av utgått lagerbeholdning" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Foreldet lagerbeholdning tidsintervall" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Antall dager før lagervarer er ansett som foreldet før utløp" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Produsér Utløpt Lagerbeholdning" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Tillat produksjon med utløpt lagerbeholdning" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Kontroll over eierskap av lagerbeholdning" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Aktiver eierskap over lagerplasseringer og -varer" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Lagerplassering standard ikon" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Lagerplassering standard ikon (tomt betyr ingen ikon)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Vis installerte lagervarer" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Vis installerte lagervarer i lagertabeller" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Produksjonsordre-referansemønster" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Nødvendig mønster for å generere Produksjonsordre-referansefeltet" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Aktiver returordrer" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Aktiver returordrefunksjonalitet i brukergrensesnittet" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Returordre-referansemønster" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Rediger fullførte returordrer" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Tillat redigering av returordrer etter de er fullført" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Salgsordre-referansemønster" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Påkrevd mønster for å generere salgsordrereferansefelt" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Salgsordre standard fraktmetode" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Aktiver opprettelse av standard forsendelse med salgsordrer" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Rediger fullførte salgsordrer" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Tillat redigering av salgsordrer etter de har blitt sendt eller fullført" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Referansemønster for innkjøpsordre" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Obligatorisk mønster for generering av referansefelt for innkjøpsordre" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Rediger fullførte innkjøpsordre" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Tillat redigering av innkjøpsordre etter at de har blitt sendt eller fullført" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Autofullfør innkjøpsordrer" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Automatisk merk innkjøpsordre som fullført når alle ordrelinjer er mottatt" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Aktiver passord glemt" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Ativer funskjon for glemt passord på innloggingssidene" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Aktiver registrering" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "Aktiver egenregistrerting for brukerer på påloggingssidene" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Aktiver SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "Aktiver SSO på innloggingssidene" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "Aktiver SSO-registrering" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Aktiver selvregistrering via SSO for brukere på innloggingssiden" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Aktiver passord glemt" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Ativer funskjon for glemt passord på innloggingssidene" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Aktiver registrering" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "Aktiver egenregistrerting for brukerer på påloggingssidene" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "Aktiver SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "Aktiver SSO på innloggingssidene" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "Aktiver SSO-registrering" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "Aktiver selvregistrering via SSO for brukere på innloggingssiden" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "" + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 msgid "Email required" msgstr "E-postadresse kreves" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Krevt at brukere angir e-post ved registrering" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Auto-utfyll SSO-brukere" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Fyll automatisk ut brukeropplysninger fra SSO-kontodata" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "E-post to ganger" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Spør brukeren om e-post to ganger ved registrering" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Passord to ganger" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Spør brukeren om passord to ganger ved registrering" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Tillatte domener" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Begrens registrering til bestemte domener (kommaseparert, begynner med @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Gruppe ved registrering" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Krev MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Brukere må bruke flerfaktorsikkerhet." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Sjekk utvidelser ved oppstart" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Sjekk at alle utvidelser er installert ved oppstart - aktiver i containermiljøer" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Aktiver URL-integrasjon" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Tillat utvidelser å legge til URL-ruter" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Aktiver navigasjonsintegrasjon" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Tillat utvidelser å integrere mot navigasjon" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Aktiver app-integrasjon" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Tillat utvidelser å legge til apper" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Aktiver tidsplanintegrasjon" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Tillat utvidelser å kjøre planlagte oppgaver" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Aktiver hendelsesintegrasjon" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Tillat utvidelser å reagere på interne hendelser" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Ekskluder eksterne plasseringer" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Automatisk varetellingsperiode" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Vis brukernes fulle navn" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Vis brukernes fulle navn istedet for brukernavn" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Antall resultater å vise i hver seksjon av søkeresultatsforhåndsvisningen" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Regex-søk" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Aktiver regulære uttrykk i søkeord" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Helordsøk" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Søk returnerer resultater for treff med hele ord" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Escape-knappen lukker skjemaer" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Bruk Escape-knappen for å lukke modal-skjemaer" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Fast navigasjonsbar" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Navigasjonsbarens posisjon er fast på toppen av skjermen" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Datoformat" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Foretrukket format for å vise datoer" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Motta feilrapporter" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Motta varsler om systemfeil" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Ingen modelltype angitt for vedlegg" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Ugyldig modelltype for vedlegg" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Minste antall plasser kan ikke være mer enn største antall plasser" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Største antall plasser kan ikke være mindre enn minste antall plasser" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Et tomt domene er ikke tillatt." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Ugyldig domenenavn: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Delen er aktiv" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Leverandør er aktiv" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Leverandørdel er aktiv" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Intern del er aktiv" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Leverandør er aktiv" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Produsent" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Firma" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "Kontakt-telefonnummer" msgid "Contact email address" msgstr "Kontakt e-post" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontakt" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adresse" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adresser" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Velg selskap" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Adressetittel" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Tittel som beskriver addressen" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Hovedadresse" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Sett som hovedadresse" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Linje 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Adresselinje 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Linje 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Adresselinje 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Postnummer" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Poststed/område" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Postnummerets by/område" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Delstat/provins" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Delstat eller provins" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Land" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Adressens land" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Notater til transportør" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Notater for transportør" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Interne fraktnotater" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Fraktnotater for internt bruk" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Lenke til adresseinformasjon (ekstern)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Produsentdeler" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Basisdel" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Velg del" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Velg produsent" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Produsentens varenummer" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL for ekstern produsentdel-lenke" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Produsentens delbeskrivelse" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Pakkeenhetene må være komptible med delens basisenhet" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Pakkeenhet må være mer enn null" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Den sammenkoblede produsentdelen må referere til samme basisdel" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Leverandør" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Velg leverandør" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Leverandørens lagerbeholdningsenhet" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Er denne leverandørdelen aktiv?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Velg produsentdel" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL for ekstern leverandørdel-lenke" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Leverandørens delbeskrivelse" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "grunnkostnad" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimum betaling (f.eks. lageravgift)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Emballasje" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Delemballasje" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Pakkeantall" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Totalt antall i en enkelt pakke. La være tom for enkeltenheter." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "flere" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Bestill flere" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Antall tilgjengelig fra leverandør" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Tilgjengelighet oppdatert" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Dato for siste oppdatering av tilgjengelighetsdata" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Leverandørens prisbrudd" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Standardvaluta brukt for denne leverandøren" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Bedriftsnavn" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "På lager" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Plassert" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Datafil" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Gyldig" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Ukjent" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Gruppe" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Ordrereferanse" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Opprettet av" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Ordre" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Intern del" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Fullført" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Innkjøpsordre" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Innkjøpsordre" msgid "Sales Order" msgstr "Salgsordre" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Returordre" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Total pris" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Total pris for denne ordren" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Ordrevaluta" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Valuta for denne ordren (la stå tom for å bruke firmastandard)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Kontakten samsvarer ikke med valgt firma" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Ordrebeskrivelse (valgfritt)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Velg prosjektkode for denne ordren" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Lenke til ekstern side" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Måldato" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Forventet dato for levering av ordre. Bestillingen vil være forfalt etter denne datoen." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Sendt dato" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Dato bestillingen ble sendt" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Bruker eller gruppe ansvarlig for ordren" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Kontaktpunkt for denne ordren" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Selskapsadresse for denne ordren" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Ordrereferanse" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Status for innkjøpsordre" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Firma som varene blir bestilt fra" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Leverandørreferanse" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Leverandørens ordrereferanse" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "mottatt av" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Dato ordre ble fullført" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Destinasjon" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Delleverandør må matche PO-leverandør" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Linjeelementet samsvarer ikke med innkjøpsordre" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Mengde må være positiv" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Kunde" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Firma som varene selges til" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Kundereferanse " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Kundens ordrereferanse" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Forsendelsesdato" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "sendt av" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Linjeelement er ikke knyttet til denne ordren" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Ingen treff funnet for følgende serienummer" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Kun en åpen ordre kan merkes som fullført" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Bestillingen kan ikke fullføres da det finnes ufullstendige forsendelser" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Denne ordren kan ikke fullføres da det fortsatt er ufullstendige artikler" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Antall" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Linjereferanse" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Linjenotater" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Måldato for denne linjen (la stå tomt for å bruke måldatoen fra ordren)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Linjeelementbeskrivelse (valgfritt)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Ytterligere kontekst for denne linjen" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Enhetspris" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Delens leverandør må samsvare med leverandør" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Leverandørdel" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Mottatt" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Antall enheter mottatt" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Innkjøpspris" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Enhet-innkjøpspris" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Kun salgbare deler kan tildeles en salgsordre" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Salgspris" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Enhets-salgspris" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Sendt" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Sendt antall" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Dato for forsendelse" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Leveringsdato" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Dato for levering av forsendelse" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Sjekket Av" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Brukeren som sjekket forsendelsen" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Forsendelse" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Forsendelsesnummer" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Sporingsnummer" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Sporingsinformasjon for forsendelse" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Fakturanummer" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Referansenummer for tilknyttet faktura" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Forsendelsen er allerede sendt" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Forsendelsen har ingen tildelte lagervarer" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Lagervarer er ikke blitt tildelt" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Kan ikke tildele lagervare til en linje med annen del" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Kan ikke tildele lagerbeholdning til en linje uten en del" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Tildelingsantall kan ikke overstige tilgjengelig lagerbeholdning" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Tildelingsantall må være større enn null" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Antall må være 1 for serialisert lagervare" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Salgsordre samsvarer ikke med forsendelse" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Forsendelsen samsvarer ikke med salgsordre" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Linje" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Forsendelsesreferanse for salgsordre" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Artikkel" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Velg lagervare å tildele" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Angi lagertildelingsmengde" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Returordre-referanse" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Firmaet delen skal returneres fra" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Returordrestatus" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Velg artikkel som skal returneres fra kunde" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Mottatt Dato" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Utfall" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Utfall for dette linjeelementet" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Kostnad forbundet med retur eller reparasjon for dette linjeelementet" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Kopier parametere" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Linjeelementer" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Leverandørnavn" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Ordren kan ikke kanselleres" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Tillat ordre å lukkes med ufullstendige linjeelementer" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Ordren har ufullstendige linjeelementer" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Ordren er ikke åpen" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Innkjøpsvaluta" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU-kode" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Internt delnummer" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Leverandørdel må angis" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Innkjøpsordre må angis" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Leverandør må samsvare med innkjøpsordre" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Innkjøpsordre må samsvare med leverandør" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Ordrelinje" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Velg lagerplassering for mottatte enheter" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Angi batchkode for innkommende lagervarer" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Utløpsdato" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Angi serienummer for innkommende lagervarer" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Strekkode" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Skannet strekkode" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Strekkode allerede i bruk" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Linjeelementer må være oppgitt" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Målplassering må angis" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Angitte strekkodeverdier må være unike" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Fullførte forsendelser" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Valuta for salgspris" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Ingen forsendelsesopplysninger oppgitt" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Linjeelement er ikke knyttet til denne ordren" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Mengden må være positiv" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Skriv inn serienummer for å tildele" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Forsendelsen er allerede sendt" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Forsendelsen er ikke knyttet til denne ordren" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Ingen treff funnet for følgende serienummer" - -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" + +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Returordrelinje" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Linjeelementet samsvarer ikke med returordre" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Linjeelementet er allerede mottatt" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Artikler kan bare mottas mot ordrer som pågår" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Valuta for linje" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Tapt" @@ -5718,1279 +6125,1312 @@ msgstr "Tapt" msgid "Returned" msgstr "Returnert" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Pågående" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Retur" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Reparasjon" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Erstatt" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Refusjon" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Avvis" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Utstedt" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Forfalt Innkjøpsordre" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Innkjøpsordre {po} er nå forfalt" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Forfalt Salgsordre" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Salgsordre {so} er nå forfalt" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Delkategori" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Delkategorier" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Standard plassering" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Standardplassering for deler i denne kategorien" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Strukturell" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Deler kan ikke tilordnes direkte til en strukturell kategori, men kan tilordnes til underkategorier." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Standard nøkkelord" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Standard nøkkelord for deler i denne kategorien" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ikon" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ikon (valgfritt)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Du kan ikke gjøre denne delkategorien strukturell fordi noen deler allerede er tilordnet den!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Standardverdi" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Standard Parameterverdi" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Deler" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Delen '{self}' kan ikke brukes i BOM for '{parent}' (rekursiv)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Delen '{parent}' er brukt i BOM for '{self}' (rekursiv)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN må samsvare med regex-mønsteret {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Lagervare med dette serienummeret eksisterer allerede" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Duplikat av internt delnummer er ikke tillatt i delinnstillinger" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Del med dette Navnet, internt delnummer og Revisjon eksisterer allerede." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Deler kan ikke tilordnes strukturelle delkategorier!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Delnavn" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Er Mal" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Er delen en maldel?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Er delen en variant av en annen del?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variant av" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Delbeskrivelse (valgfritt)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Nøkkelord" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Del-nøkkelord for å øke synligheten i søkeresultater" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Delkategori" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Delrevisjon eller versjonsnummer" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revisjon" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Hvor er denne artikkelen vanligvis lagret?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Standard utløp" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Utløpstid (i dager) for lagervarer av denne delen" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimal lagerbeholdning" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Minimum tillatt lagernivå" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Måleenheter for denne delen" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Kan denne delen bygges fra andre deler?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Kan denne delen brukes til å bygge andre deler?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Har denne delen sporing av unike artikler?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Kan denne delen kjøpes inn fra eksterne leverandører?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Kan denne delen selges til kunder?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Er denne delen aktiv?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Er dette en virtuell del, som et softwareprodukt eller en lisens?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Kontrollsum for BOM" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Lagret BOM-kontrollsum" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Stykkliste sjekket av" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Stykkliste sjekket dato" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Opprettingsbruker" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Eier ansvarlig for denne delen" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Selg flere" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Valuta som brukes til å bufre prisberegninger" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimal BOM-kostnad" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Minste kostnad for komponentdeler" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maksimal BOM-kostnad" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Maksimal kostnad for komponentdeler" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimal innkjøpskostnad" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Minimal historisk innkjøpskostnad" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maksimal innkjøpskostnad" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Maksimal historisk innkjøpskostnad" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimal intern pris" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Minimal kostnad basert på interne prisbrudd" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maksimal intern pris" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Maksimal kostnad basert på interne prisbrudd" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Minimal leverandørpris" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Minimumspris for del fra eksterne leverandører" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Maksimal leverandørpris" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Maksimalpris for del fra eksterne leverandører" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Minimal Variantkostnad" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Beregnet minimal kostnad for variantdeler" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Maksimal Variantkostnad" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Beregnet maksimal kostnad for variantdeler" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimal kostnad" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Overstyr minstekostnad" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maksimal kostnad" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Overstyr maksimal kostnad" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Beregnet samlet minimal kostnad" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Beregnet samlet maksimal kostnad" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Minimal salgspris" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Minimal salgspris basert på prisbrudd" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Maksimal Salgspris" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Maksimal salgspris basert på prisbrudd" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Minimal Salgskostnad" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Minimal historisk salgspris" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Maksimal Salgskostnad" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Maksimal historisk salgspris" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Del for varetelling" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Antall" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Antall individuelle lagerenheter på tidspunkt for varetelling" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Total tilgjengelig lagerbeholdning på tidspunkt for varetelling" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Dato" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Dato for utført lagertelling" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Minimal lagerkostnad" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Estimert minimal kostnad for lagerbeholdning" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maksimal lagerkostnad" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Estimert maksimal kostnad for lagerbeholdning" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Testnavn" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Angi et navn for testen" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Testbeskrivelse" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Legg inn beskrivelse for denne testen" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Påkrevd" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Er det påkrevd at denne testen bestås?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Krever verdi" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Krever denne testen en verdi når det legges til et testresultat?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Krever vedlegg" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Krever denne testen et filvedlegg når du legger inn et testresultat?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Velg overordnet del" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Underordnet del" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Velg del som skal brukes i BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "BOM-antall for denne BOM-artikkelen" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Denne BOM-artikkelen er valgfri" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Denne BOM-artikkelen er forbruksvare (den spores ikke i produksjonsordrer)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "BOM-artikkelreferanse" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "BOM-artikkelnotater" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Kontrollsum" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "BOM-linje kontrollsum" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Godkjent" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Denne BOM-artikkelen er godkjent" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Arves" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Denne BOM-artikkelen er arvet fra stykkliste for variantdeler" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Lagervarer for variantdeler kan brukes for denne BOM-artikkelen" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Antall må være heltallsverdi for sporbare deler" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Underordnet del må angis" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "BOM-artikkel erstatning" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Erstatningsdel kan ikke være samme som hoveddelen" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Overordnet BOM-artikkel" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Erstatningsdel" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Del 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Del 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Velg relatert del" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Del-forhold kan ikke opprettes mellom en del og seg selv" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Duplikatforhold eksisterer allerede" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Underkategorier" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Innkjøpsvaluta for lagervaren" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Original Del" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Velg original del å duplisere" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kopier Bilde" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Kopier bilde fra originaldel" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Kopier Stykkliste" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Kopier stykkliste fra original del" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Kopier parameterdata fra originaldel" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Kopier notater" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Kopier notater fra originaldel" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Innledende lagerbeholdning" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Angi initiell lagermengde for denne delen. Hvis antall er null, er ingen lagerbeholdning lagt til." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Innledende lagerplassering" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Angi initiell lagerplasering for denne delen" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Velg leverandør (eller la stå tom for å hoppe over)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Velg produsent (eller la stå tom for å hoppe over)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Produsentens delenummer" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Valgt firma er ikke en gyldig leverandør" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Valgt firma er ikke en gyldig produsent" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Produsentdel som matcher dette MPN-et, finnes allerede" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Leverandørdel som matcher denne SKU-en, finnes allerede" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Kategorinavn" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Produseres" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Lagervarer" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Total lagerbeholdning" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Dupliser del" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Kopier innledende data fra en annen del" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kopier Bilde" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Kopier bilde fra originaldel" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Kopier Stykkliste" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Kopier stykkliste fra original del" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Kopier notater" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Kopier notater fra originaldel" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Innledende lagerbeholdning" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Lag en del med innledende lagermengde" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Leverandøropplysninger" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Legg til innledende leverandørinformasjon for denne delen" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Kopier kategoriparametre" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Kopier parametermaler fra valgt delkategori" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Eksisterende bilde" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Filnavn for et eksisterende del-bilde" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Bildefilen finnes ikke" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Godkjenn hele Stykklisten" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Kan Produsere" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Minstepris" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Overstyr beregnet verdi for minimumspris" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Valuta for minstepris" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Makspris" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Overstyr beregnet verdi for maksimal pris" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Valuta for maksimal pris" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Oppdater" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Oppdater priser for denne delen" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Kan ikke konvertere fra gitte valutaer til {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Minsteprisen kan ikke være større enn maksimal pris" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Maksimal pris kan ikke være mindre enn minstepris" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Velg del å kopiere BOM fra" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Fjern eksisterende data" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Fjern eksisterende BOM-artikler før kopiering" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Inkluder arvede" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Inkluder BOM-artikler som er arvet fra maldeler" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Hopp over ugyldige rader" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Aktiver dette alternativet for å hoppe over ugyldige rader" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Kopier erstatningsdeler" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopier erstatningsdeler når BOM-elementer dupliseres" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Varsel om lav lagerbeholdning" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Tilgjengelig lagerbeholdning for {part.name} har falt under det konfigurerte minimumsnivået" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Installert" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "Ingen handling spesifisert" msgid "No matching action found" msgstr "Ingen samsvarende handling funnet" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Ingen treff funnet for strekkodedata" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Treff funnet for strekkodedata" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Strekkode samsvarer med ekisterende element" @@ -7055,51 +7495,67 @@ msgstr "Finner ingen matchende leverandørdeler" msgid "Multiple matching supplier parts found" msgstr "Flere samsvarende leverandørdeler funnet" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Fant leverandørdel" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Artikkelen er allerede mottatt" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Flere samsvarende elementer funnet" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Ingen samsvarende element funnet" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Strekkoden samsvarer ikke med eksisterende lagervare" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Lagervare samsvarer ikke med linjeelement" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Utilstrekkelig lagerbeholdning" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Lagervaren er tildelt en salgsordre" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Ikke nok informasjon" @@ -7108,23 +7564,23 @@ msgstr "Ikke nok informasjon" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Mer informasjon nødvendig for å motta artikkelen" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Mottok ordreartikkelen" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Gir innebygd støtte for strekkoder" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL brukt til å sende meldinger til en Slack-kanal" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Åpne lenke" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Gir innebygd støtte for å skrive ut PDF-etiketter" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Feilsøkingsmodus" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Aktiver feilsøkingsmodus - returnerer rå HTML i stedet for PDF" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Sidestørrelse på etikett-arket" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Hopp over etiketter" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Hopp over dette antallet etiketter når det skrives ut etiketterark" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Kantlinjer" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Skriv ut en kant rundt hver etikett" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Liggende" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Skriv ut etikett-arket i liggende modus" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree etikett-ark skriver" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Sprer ut flere etiketter på ett enkelt ark" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Etiketten er for stor for sidestørrelse" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Ingen etiketter ble generert" @@ -7753,77 +8217,85 @@ msgstr "Gir støtte for å skanne TME-strekkoder" msgid "The Supplier which acts as 'TME'" msgstr "Leverandøren som fungerer som \"TME\"" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Installasjon av utvidelse vellykket" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Installerte utvidelsen til {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Utvidelse" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Ingen forfatter funnet" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Utvidensen '{p}' er ikke kompatibel med nåværende InvenTree-versjon {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Utvidelsen krever minst versjon {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Utvidelsen krever maks versjon {v}" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Malnavn" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Filnavnmønster" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtre" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Sidestørrelse for PDF-rapporter" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Generer rapport i landskapsorientering" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Bredde [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Etikettbredde, spesifisert i mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Høyde [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Etiketthøyde, spesifisert i mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Snutt" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Rapportsnuttfil" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Filbeskrivelse for snutt" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Ressurs" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Rapportressursfil" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Ressursfilbeskrivelse" @@ -8291,23 +8771,23 @@ msgstr "Ressursfilbeskrivelse" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "Nødvendige materialer" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Bilde av del" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Utstedt" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Kreves for" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serienummer" @@ -8405,7 +8882,7 @@ msgstr "Testrapport for lagervare" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Installerte artikler" @@ -8438,810 +8915,922 @@ msgstr "Ingen resultat (obligatorisk)" msgid "No result" msgstr "Ingen resultat" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Bildefil ikke funnet" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image-taggen krever en Part-instans" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image-taggen krever en Company-instans" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Statuskode" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Ekstern plassering" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Del-tre" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Utløpsdato før" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Utløpsdato etter" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Foreldet" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Antall kreves" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Gyldig del må oppgis" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Oppgitt leverandørdel eksisterer ikke" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Leverandørdelen har en pakkestørrelse definert, men flagget \"use_pack_size\" er ikke satt" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Serienumre kan ikke angis for en ikke-sporbar del" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Lagerplasseringstype" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Lagerplasseringstyper" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Standard ikom for alle plasseringer som ikke har satt et ikon (valgfritt)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Lagerplassering" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Lagerplasseringer" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Eier" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Velg eier" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Lagervarer kan ikke knyttes direkte mot en strukturell lagerplassering, men kan knyttes mot underplasseringer." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Ekstern" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Dette er en ekstern lagerplassering" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Plasseringstype" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Lagerplasseringstype for denne plasseringen" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "De kan ikke gjøre denne plasseringen strukturell, da noen lagervarer allerede er plassert i den!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Lagervarer kan ikke plasseres i strukturelle plasseringer!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Lagervare kan ikke opprettes for virtuelle deler" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Deltype ('{self.supplier_part.part}') må være {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Antall må være 1 for produkt med et serienummer" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Serienummeret kan ikke angis hvis antall er større enn 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Elementet kan ikke tilhøre seg selv" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Elementet må ha en produksjonsrefereanse om is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Produksjonsreferanse peker ikke til samme del-objekt" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Overordnet lagervare" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Basisdel" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Velg en tilsvarende leverandørdel for denne lagervaren" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Hvor er denne lagervaren plassert?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Inpakningen denne lagervaren er lagret i" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Installert i" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Er denne artikkelen montert i en annen artikkel?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Serienummer for denne artikkelen" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Batchkode for denne lagervaren" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Lagerantall" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Kildeproduksjon" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Produksjon for denne lagervaren" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Brukt av" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Produksjonsordren som brukte denne lagervaren" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Kildeinnkjøpsordre" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Innkjøpsordre for denne lagervaren" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Tildelt Salgsordre" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Utløpsdato for lagervare. Lagerbeholdning vil bli ansett som utløpt etter denne datoen" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Slett når oppbrukt" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Slett lagervaren når beholdningen er oppbrukt" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Innkjøpspris per enhet på kjøpstidspunktet" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Konvertert til del" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Delen er ikke angitt som sporbar" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Antall må være heltall" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Antall kan ikke overstige tilgjengelig lagerbeholdning ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Antallet stemmer ikke overens med serienumrene" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Lagervare har blitt tildelt en salgsordre" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Lagervare er montert i en annen artikkel" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Lagervare inneholder andre artikler" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Lagervare har blitt tildelt til en kunde" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Lagervare er for tiden i produksjon" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Serialisert lagerbeholdning kan ikke slås sammen" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Duplisert lagervare" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Lagervarer må referere til samme del" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Lagervarer må referere til samme leverandørdel" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Lagerstatuskoder må være like" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Lagervare kan ikke flyttes fordi den ikke er på lager" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Oppføringsnotater" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Verdi må angis for denne testen" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Vedlegg må lastes opp for denne testen" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Testresultat" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Testens verdi" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Vedlegg til testresultat" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Testnotater" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Overodnet element" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Bruk pakningsstørrelse når du legger til: antall definert er antall pakker" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Angi serienummer for nye artikler" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Leverandørens delnummer" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Utløpt" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Underordnede artikler" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Innkjøpspris for denne lagervaren, per enhet eller forpakning" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Angi antall lagervarer som skal serialiseres" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Antall kan ikke overstige tilgjengelig lagerbeholdning ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Til Lagerplassering" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Serienummer kan ikke tilordnes denne delen" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Seriernummer eksisterer allerede" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Velg lagervare å montere" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Antall å installere" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Angi antallet elementer som skal installeres" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Legg til transaksjonsnotat (valgfritt)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Antall å installere må være minst 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Lagervaren er utilgjengelig" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Valgt del er ikke i stykklisten" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Antall å installere må ikke overskride tilgjengelig antall" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Lagerplassering for den avinstallerte artikkelen" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Velg del å konvertere lagervare til" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Valgt del er ikke et gyldig alternativ for konvertering" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Kan ikke konvertere lagerprodukt med tildelt leverandørdel" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Lagervare statuskode" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Velg del å konvertere lagervare til" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Valgt del er ikke et gyldig alternativ for konvertering" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Kan ikke konvertere lagerprodukt med tildelt leverandørdel" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Velg lagervarer for å endre status" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Ingen lagervarer valgt" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Underplasseringer" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Delen må være salgbar" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Artikkelen er tildelt en salgsordre" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Artikkelen er tildelt en produksjonsordre" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Kunde å tilordne lagervarer" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Valgt firma er ikke en kunde" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Lagervare-tildelignsnotater" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "En liste av lagervarer må oppgis" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Notater om lagersammenslåing" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Tillat forskjellige leverandører" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Tillat lagervarer med forskjellige leverandørdeler å slås sammen" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Tillat forskjellig status" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Tillat lagervarer med forskjellige statuskoder å slås sammen" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Minst to lagervarer må oppgis" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Lagervare primærnøkkel verdi" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Lager transaksjonsnotater" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Lager transaksjonsnotater" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Sammenslåtte lagervarer" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Konvertert til variant" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Produksjonsartikkel opprettet" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Produksjonsartikkel fullført" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Produksjonsartikkel avvist" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Brukt av produksjonsordre" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Sendt mot salgsordre" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Mottatt mot innkjøpsordre" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Returnert mot returordre" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Sendt til kunde" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Returnert av kunde" @@ -9527,19 +10124,19 @@ msgstr "Brukere" msgid "Select which users are assigned to this group" msgstr "Velg hvilke brukere som er tilordnet denne gruppen" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Personlig informasjon" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Tillatelser" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Viktige datoer" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Token er tilbakekalt" @@ -9547,279 +10144,283 @@ msgstr "Token er tilbakekalt" msgid "Token has expired" msgstr "Token har utløpt" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API-Token" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API-Tokener" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Tokennavn" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Egendefinert tokennavn" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Token utløpsdato" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Sist sett" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Sist gang tokenet ble brukt" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Tilbakekalt" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Tillatelse satt" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Visning" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Tillatelse til å se elementer" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Legg til" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Tillatelse til å legge til elementer" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Endre" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Tillatelse til å endre elementer" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Slett" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Tillatelse til å slette elementer" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Administrator" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Innkjøpsordrer" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Salgsordre" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Returordrer" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Brukernavn" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Fornavn" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Fornavn på brukeren" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Etternavn" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Etternavn på brukeren" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "E-postadressen til brukeren" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superbruker" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Er denne brukeren en superbruker" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Er denne brukerkontoen aktiv" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Din konto er opprettet." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Vennligst bruk funksjonen for å tilbakestille passord for å logge inn" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Velkommen til InvenTree" diff --git a/src/backend/InvenTree/locale/pl/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/pl/LC_MESSAGES/django.po index 502ba10bcd..8f8e097954 100644 --- a/src/backend/InvenTree/locale/pl/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/pl/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Nie znaleziono punktu końcowego API" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Elementy muszą być podane jako lista" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Podano nieprawidłową listę artykułów" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Wszystkie filtry muszą być używane tylko z true" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Żaden element nie spełnia podanych kryteriów" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Nie dostarczono danych" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Użytkownik nie ma uprawnień do przeglądania tego modelu" @@ -65,150 +69,155 @@ msgstr "Potwierdzenie adresu email" msgid "You must type the same email each time." msgstr "Należy ponownie wpisać ten sam adres e-mail." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Podany podstawowy adres e-mail jest nieprawidłowy." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Podany e-mail domeny nie został zatwierdzony." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Nieprawidłowa jednostka ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nie podano wartości" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Nie udało się przeliczyć {original} na {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Podano nieprawidłową ilość" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Szczegóły błędu można znaleźć w panelu administracyjnym" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Wprowadź dane" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Niepoprawna wartość dziesiętna" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Uwagi" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Wartość '{name}' nie pojawia się w formacie wzoru" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Podana wartość nie pasuje do wymaganego wzoru: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Nie można serializować więcej niż 1000 przedmiotów naraz" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Pusty ciąg numeru seryjnego" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Podwójny numer seryjny" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Nieprawidłowa grupa: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Zakres grupy {group} przekracza dozwoloną ilość ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Nie znaleziono numerów seryjnych" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Liczba niepowtarzających się numerów seryjnych ({n}) musi odpowiadać ilości / liczbie ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Usuń znaczniki HTML z tej wartości" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Dane zawierają zabronione treści znacznika" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Błąd połączenia" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Serwer odpowiedział z nieprawidłowym kodem statusu" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Wystąpił wyjątek" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Serwer odpowiedział z nieprawidłową wartością Content-Length" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Rozmiar obrazu jest zbyt duży" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Przekroczono maksymalny rozmiar pobieranego obrazu" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Zdalny serwer zwrócił pustą odpowiedź" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Podany adres URL nie jest poprawnym plikiem obrazu" @@ -216,159 +225,203 @@ msgstr "Podany adres URL nie jest poprawnym plikiem obrazu" msgid "Log in to the app" msgstr "Logowanie do aplikacji" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Adres E-Mail" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Musisz włączyć uwierzytelnianie dwuskładnikowe przed wykonaniem czegokolwiek innego." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Błąd podczas walidacji wtyczki" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadane muszą być obiektem typu dict w Python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Wtyczka Metadane" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Pole metadanych JSON, do użycia przez wtyczki zewnętrzne" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Nieprawidłowo sformatowany wzór" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Określono nieznany format klucza" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Brak wymaganego formatu klucza" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Pole odniesienia nie może być puste" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Odniesienie musi być zgodne z wymaganym wzorem" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Numer odniesienia jest zbyt duży" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Błędny wybór" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nazwa" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Opis" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Opis (opcjonalny)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Ścieżka" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplikaty nazw nie mogą istnieć pod tym samym rodzicem" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Notatki Markdown (opcjonalne)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Dane kodu kreskowego" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Dane kodu kreskowego stron trzecich" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hasz kodu kreskowego" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Unikalny hasz danych kodu kreskowego" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Znaleziono istniejący kod kreskowy" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Błąd serwera" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Błąd został zapisany w logach serwera." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Obraz" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Numer musi być prawidłowy" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Waluta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Wybierz walutę z dostępnych opcji" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Nieprawidłowa wartość" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Kopiuj parametry" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabski" @@ -521,46 +574,48 @@ msgstr "chiński (uproszczony)" msgid "Chinese (Traditional)" msgstr "chiński (tradycyjny)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Dostępna aktualizacja" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Dostępna jest aktualizacja dla InvenTree" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Niewłaściwa jednostka fizyczna" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Nieprawidłowy kod waluty" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Status zamówienia" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Budowa nadrzędna" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Obejmuje warianty" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Obejmuje warianty" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Obejmuje warianty" msgid "Part" msgstr "Komponent" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategoria" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Budowa poprzednika" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Przypisane do mnie" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Stworzony przed" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Stworzony po" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Ma datę rozpoczęcia" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Data rozpoczęcia przed" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Data rozpoczęcia po" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Posiada docelową datę" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Data docelowa przed" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Docelowa data po" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Zakończone przed" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Zakończone po" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Minimalna data" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Maksymalna data" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Wyklucz drzewo" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Kompilacja musi zostać anulowana, zanim będzie mogła zostać usunięta" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Materiał eksploatacyjny" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opcjonalne" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Złożenie" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Śledzony" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testowalne" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Zaległe zamówienie" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Przydzielono" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Dostępne" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "W Zamówieniu" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Zlecenie Budowy" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Lokalizacja" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Wyjście" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Zlecenia budowy" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Zbiór BOM nie został zatwierdzony" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Zlecenie budowy nie może być utworzone dla nieaktywnej części" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Zlecenie budowy nie może zostać utworzone dla odblokowanej części" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Odpowiedzialny użytkownik lub grupa muszą być określone" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Nie można zmienić elementu kompletacji" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Data docelowa musi być po dacie rozpoczęcia" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Odwołanie do zamówienia wykonania" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referencja" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Krótki opis produkcji (opcjonalny)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Wybierz część do budowy" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Odwołanie do zamówienia sprzedaży" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Lokalizacja źródła" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Wybierz lokalizację, z której pobrać element do budowy (pozostaw puste, aby wziąć z dowolnej lokalizacji)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Budowa zewnętrzna" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Lokalizacja docelowa" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Wybierz lokalizację, w której będą przechowywane ukończone elementy" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Ilość do stworzenia" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Ilość przedmiotów do zbudowania" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Ukończone elementy" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Ilość produktów magazynowych które zostały ukończone" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Status budowania" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Kod statusu budowania" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Kod partii" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Kod partii dla wyjścia budowy" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Data utworzenia" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Data rozpoczęcia budowy" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Zaplanowana data rozpoczęcia dla tego zamówienia budowy" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Docelowy termin zakończenia" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Docelowa data zakończenia kompilacji. Po tej dacie kompilacja będzie zaległa." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Data zakończenia" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "zrealizowane przez" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Wydany przez" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Użytkownik, który wydał to zamówienie" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odpowiedzialny" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Użytkownik lub grupa odpowiedzialna za te zlecenie produkcji" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Link Zewnętrzny" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link do zewnętrznego adresu URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Priorytet budowy" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Priorytet tego zamówienia produkcji" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Kod projektu" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Kod projektu dla tego zlecenia produkcji" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Nie udało się wyładować zadania, aby ukończyć alokację budowli" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Kolejność kompilacji {build} została zakończona" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Kolejność kompilacji została zakończona" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Należy podać numery seryjne dla lokalizowania części" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nie określono danych wyjściowych budowy" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Budowanie wyjścia jest już ukończone" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Skompilowane dane wyjściowe nie pasują do kolejności kompilacji" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Ilość musi być większa niż zero" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Ilość nie może być większa niż ilość wyjściowa" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Wyjście budowy {serial} nie przeszło wszystkich testów" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Dostępna ilość ({q}) przekroczona" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Zbuduj obiekt" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Zbuduj obiekt" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Ilość" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Wymagana ilość dla zlecenia produkcji" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Element kompilacji musi określać dane wyjściowe kompilacji, ponieważ część główna jest oznaczona jako możliwa do śledzenia" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Wybrana pozycja magazynowa nie pasuje do pozycji w zestawieniu BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Ilość musi wynosić 1 dla serializowanych zasobów" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Przydzielona ilość ({q}) nie może przekraczać dostępnej ilości zapasów magazynowych ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Pozycja magazynowa jest nadmiernie przydzielona" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Element magazynowy" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Lokalizacja magazynowania przedmiotu" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Ilość zapasów do przydzielenia do produkcji" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Zainstaluj do" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Docelowa lokalizacja magazynowa przedmiotu" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Poziom budowania" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Nazwa komponentu" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Numer seryjny" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Automatycznie przydzielaj numery seryjne" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatycznie przydzielaj wymagane elementy z pasującymi numerami seryjnymi" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Poniższe numery seryjne już istnieją lub są nieprawidłowe" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Odrzuć przydziały" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Zaakceptuj niekompletną alokację" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Usuń produkcje, które nie zostały zakończone" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Niedozwolone" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Zaakceptuj jako zużyte przez zlecenie produkcji" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Nadmierny przydział zasobów" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Zaakceptuj nieprzydzielone" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Zaakceptuj, że przedmioty magazynowe nie zostały w pełni przypisane do tego zlecenia budowy" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Wymagany stan nie został w pełni przypisany" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Akceptuj niekompletne" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Towar musi znajdować się w magazynie" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Dostępna ilość ({q}) przekroczona" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Magazyn, z którego mają być pozyskane elementy (pozostaw puste, aby pobrać z dowolnej lokalizacji)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Wyklucz lokalizację" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Wyklucz produkty magazynowe z wybranej lokalizacji" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Magazyn wymienny" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Towary magazynowe w wielu lokalizacjach mogą być stosowane zamiennie" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Zastępczy magazyn" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Przedmiot opcjonalny" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Przydziel opcjonalne elementy BOM do zbudowania zamówienia" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Odniesienie BOM" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID części BOM" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Nazwa części BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Wersja" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Część dostawcy" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Ilość zarezerwowana" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Możliwość śledzenia" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Zezwalaj na warianty" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Element BOM" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "W produkcji" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Zew. zasoby magazynowe" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Dostępna ilość" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Dostępny magazyn zastępczy" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "W toku" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Produkcja" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Wstrzymane" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Anulowano" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Zakończono" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Kolejność kompilacji {build} została zakończona" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Kolejność kompilacji została zakończona" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Jest plikiem" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Lista wyboru jest zablokowana" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "Brak wtyczki" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Zaktualizowany" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Data ostatniej aktualizacji" @@ -1567,794 +1674,844 @@ msgstr "Unikalny kod projektu" msgid "Project description" msgstr "Opis projektu" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Użytkownik lub grupa odpowiedzialna za to zamówienie" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Klucz ustawień" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Ustawienia wartości" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Wybrana wartość nie jest poprawną opcją" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Wartość musi być wartością binarną" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Wartość musi być liczbą całkowitą" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Wartość musi być poprawną liczbą" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Wartość nie zgadza się z kontrolą poprawności" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Ciąg musi być unikatowy" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Użytkownik" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Cena" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Cena jednostkowa po określonej ilości" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Punkt końcowy" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktywny" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Użytkownik lub grupa odpowiedzialna za to zamówienie" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Klucz ustawień" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Ustawienia wartości" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Wybrana wartość nie jest poprawną opcją" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Wartość musi być wartością binarną" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Wartość musi być liczbą całkowitą" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Wartość musi być poprawną liczbą" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Wartość nie zgadza się z kontrolą poprawności" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Ciąg musi być unikatowy" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Użytkownik" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Cena" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Cena jednostkowa po określonej ilości" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Punkt końcowy" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token dostępu" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Sekret" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Współdzielony sekret dla HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Id wiadomości" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Unikalny identyfikator dla tej wiadomości" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Host" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Host, od którego otrzymano tę wiadomość" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Nagłówek" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Nagłówek tej wiadomości" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Zawartość" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Treść tej wiadomości" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Opracowany na" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Czy prace nad tą wiadomością zostały zakończone?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Tytuł" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Łącze" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Opublikowano" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Podsumowanie" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Czytaj" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Czy ta wiadomość była przeczytana?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Plik obrazu" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Jednostka Niestandardowa" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Symbol jednostki musi być unikalny" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Nazwa jednostki musi być prawidłowym identyfikatorem" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Nazwa jednostki" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Opcjonalny symbol jednostki" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definicja" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definicja jednostki" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Załącznik" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Brak pliku" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Brak zewnętrznego odnośnika" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Typ modelu" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Docelowy typ modelu dla obrazu" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Wybierz plik do załączenia" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Komentarz" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Komentarz do załącznika" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Data dodania" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Data przesłania pliku" -#: common/models.py:2118 -msgid "File size" -msgstr "Rozmiar pliku" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "Rozmiar pliku w bajtach" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Rozmiar pliku" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "Rozmiar pliku w bajtach" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Wartość" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etykieta" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Kolor" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Model musi być wybrany" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Klucz musi być wybrany" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Zablokowany" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Utworzony" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Ostatnia aktualizacja" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Jednostki" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Aktywne" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Szablon" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Dane" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Wartość parametru" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Uwaga" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Wynik" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Doręczono" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Klucz" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} anulowany" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Nadpisz" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Jest uruchomiony" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Oczekujce zadania" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Zaplanowane zadania" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Zadania zakończone błędem" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID zadania" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Unikalny identyfikator zadania" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Blokada" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Czas blokady" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Nazwa zadania" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funkcja" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nazwa funkcji" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumenty" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argumenty zadania" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nazwa pliku" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Typ modelu" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Użytkownik nie ma uprawnień do tworzenia lub edytowania załączników dla tego modelu" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Lista wyboru jest zablokowana" - #: common/setting/system.py:97 msgid "No group" msgstr "Brak grupy" @@ -2614,13 +2767,13 @@ msgstr "Interwał aktualizacji waluty" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Jak często aktualizować kursy wymiany walut (ustaw zero aby wyłączyć)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dni" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Ścisła weryfikacja adresu URL" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 +msgid "Part Revisions" +msgstr "" + +#: common/setting/system.py:413 +msgid "Enable revision field for Part" +msgstr "" + +#: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Wyrażenie regularne IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Zezwól na powtarzający się IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Zezwól na edycję IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Skopiuj BOM komponentu" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Możliwość zakupu" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Części są domyślnie z możliwością zakupu" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Możliwość sprzedaży" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Części są domyślnie z możliwością sprzedaży" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Części są domyślnie z możliwością śledzenia" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Wirtualny" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Części są domyślnie wirtualne" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Pokaż powiązane części" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Użyj cennika dostawcy" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Nadpisanie historii zakupów" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Ceny wewnętrzne" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Włącz drukowanie etykiet" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Włącz drukowanie etykiet z interfejsu WWW" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "DPI etykiety" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Włącz raporty" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Tryb Debugowania" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "Rozmiar strony" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "Domyślna wielkość strony dla raportów PDF" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" -msgstr "" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" +msgstr "Rozmiar strony" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" -msgstr "" +msgid "Default page size for PDF reports" +msgstr "Domyślna wielkość strony dla raportów PDF" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Przekonwertuj walutę" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Konwertuj wartość przedmiotu na walutę bazową podczas otrzymywania zapasów" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Automatycznie wypełniaj zlecenia zakupu" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Automatycznie oznacz zlecenia jako zakończone po odebraniu wszystkich pozycji" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Włącz opcję zapomnianego hasła" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Włącz funkcję zapomnianego hasła na stronach logowania" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Włącz rejestrację" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "Włącz samodzielną rejestrację dla użytkowników na stronach logowania" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Włącz SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "Włącz SSO na stronach logowania" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "Włącz rejestrację SSO" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Włącz samodzielną rejestrację przez SSO dla użytkowników na stronach logowania" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "Włącz synchronizację grupy SSO" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "Włącz synchronizację grup InvenTree z grupami dostarczonymi przez IdP" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Włącz opcję zapomnianego hasła" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Włącz funkcję zapomnianego hasła na stronach logowania" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Włącz rejestrację" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "Włącz samodzielną rejestrację dla użytkowników na stronach logowania" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "Włącz SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "Włącz SSO na stronach logowania" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "Włącz rejestrację SSO" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "Włącz samodzielną rejestrację przez SSO dla użytkowników na stronach logowania" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "Włącz synchronizację grupy SSO" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "Włącz synchronizację grup InvenTree z grupami dostarczonymi przez IdP" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "" + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 msgid "Email required" msgstr "Adres e-mail jest wymagany" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Autouzupełnianie użytkowników SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Automatycznie wypełnij dane użytkownika z danych konta SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "E-mail dwa razy" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Przy rejestracji dwukrotnie zapytaj użytkowników o ich adres e-mail" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Hasło dwukrotnie" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Przy rejestracji dwukrotnie zapytaj użytkowników o ich hasło" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grupuj przy rejestracji" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Wymuś MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Użytkownicy muszą używać zabezpieczeń wieloskładnikowych." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Sprawdź wtyczki przy starcie" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Sprawdź dostępność aktualizacji wtyczek" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Włącz okresowe sprawdzanie aktualizacji zainstalowanych wtyczek" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Włącz integrację URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Włącz wtyczki, aby dodać ścieżki URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Włącz integrację z aplikacją" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Włącz wtyczki, aby dodać aplikacje" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Włącz wtyczki, aby uruchamiać zaplanowane zadania" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Włącz kody projektów" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Włącz kody projektów do śledzenia projektów" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Włącz funkcjonalność dla zapisywania historycznych poziomów zapasów i wartości" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Stały pasek nawigacyjny" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Format daty" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Preferowany format wyświetlania dat" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Pusta domena nie jest dozwolona." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Niepoprawna nazwa domeny: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Komponent jest aktywny" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Producent jest aktywny" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Producent" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Firma" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "Numer telefonu kontaktowego" msgid "Contact email address" msgstr "Kontaktowy adres e-mail" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontakt" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adres" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Miasto/Region" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Kod pocztowy miasto/region" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Stan/Województwo" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Stan lub województwo" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Kraj" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Kraj" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Notatki przewozowe kuriera" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Notatki dla kuriera" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Wewnętrzne notatki przewozowe" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Notatki wysyłkowe do użytku wewnętrznego" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Komponent producenta" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Część bazowa" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Wybierz część" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Wybierz producenta" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Numer producenta komponentu" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Dostawca" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Wybierz dostawcę" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "koszt podstawowy" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Opakowanie" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Opakowanie części" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Ilość w opakowaniu" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "wielokrotność" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Zamów wiele" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Dostępność zaktualizowana" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Domyślna waluta używana dla tego dostawcy" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Na stanie" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Umieszczony" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Plik danych" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Status importu" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Ważny" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopie" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Liczba kopii do wydrukowania dla każdej etykiety" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Połączono" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Nieznany" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Drukowanie" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Brak mediów" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Rozłączono" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Drukarka etykiet" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Bezpośrednio wydrukuj etykiety dla różnych elementów." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Lokalizacja drukarki" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Nazwa maszyny" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Typ maszyny" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Typ maszyny" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Sterownik" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Sterownik użyty dla tego urządzenia" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Brak błędów" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Zainicjalizowany" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupa" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Numer zamówienia" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Utworzony przez" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Posiada ceny" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Zamówienie" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Komponent wewnętrzny" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Zamówienie oczekujące" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Zakończone" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Zlecenie zakupu" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Zlecenie zakupu" msgid "Sales Order" msgstr "Zamówienie zakupu" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Cena całkowita" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Link do zewnętrznej witryny" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Data docelowa" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Data wydania" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Data wystawienia zamówienia" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Użytkownik lub grupa odpowiedzialna za to zamówienie" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Odniesienie zamówienia" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Status zamówienia zakupu" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "odebrane przez" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Przeznaczenie" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Pozycja nie pasuje do zlecenia zakupu" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Wartość musi być liczbą dodatnią" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Klient" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Data wysyłki" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "wysłane przez" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Ilość elementów" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Odebrane" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Cena zakupu" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Cena zakupu jednostkowego" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Cena sprzedaży" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Jednostkowa cena sprzedaży" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Wysłane" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Wysłana ilość" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Data wysyłki" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Sprawdzone przez" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Użytkownik, który sprawdził tę wysyłkę" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Przesyłka" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Numer przesyłki" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Numer śledzenia" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Informacje o śledzeniu przesyłki" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Przesyłka została już wysłana" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Zarezerwowana ilość nie może przekraczać ilości na stanie" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Alokowana ilość musi być większa niż zero" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Linia" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Komponent" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Kopiuj parametry" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Zamówienie nie może zostać anulowane" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Zlecenie zakupu musi być określone" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Dostawca musi być zgodny ze zleceniem zakupu" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Zlecenie zakupu musi być zgodne z dostawcą" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Data ważności" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Kod kreskowy" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Zagubiono" @@ -5718,1279 +6125,1312 @@ msgstr "Zagubiono" msgid "Returned" msgstr "Zwrócone" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "W trakcie" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Zwrot" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Naprawa" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Wymiana" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Zwrot pieniędzy" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Odrzuć" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Wydany" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Zaległe zlecenie zakupu" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Zlecenie zakupu {po} jest teraz zaległe" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Kategoria komponentu" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Kategorie części" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Domyślna lokalizacja" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Domyślna lokalizacja dla komponentów w tej kategorii" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Domyślne słowa kluczowe" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Wartość domyślna" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Części" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Nazwa komponentu" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Czy szablon" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Czy ta część stanowi szablon części?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Czy ta część jest wariantem innej części?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Wariant" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Słowa kluczowe" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Wersja" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Domyślne wygasanie" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimalny stan magazynowy" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Czy ten komponent może być zbudowany z innych komponentów?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Czy ta część może być użyta do budowy innych części?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Czy ta część wymaga śledzenia każdego towaru z osobna?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Czy ta część jest aktywna?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Czy to wirtualna część, taka jak oprogramowanie lub licencja?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Tworzenie użytkownika" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Sprzedaj wiele" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Data" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Nazwa testu" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Testowy opis" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Wprowadź opis do tego testu" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Wymagane" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Wymaga wartości" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Wymaga załącznika" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Wybierz część nadrzędną" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Podczęść" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Ten element BOM jest opcjonalny" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Notatki pozycji BOM" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Suma kontrolna" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Zatwierdzone" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Część zastępcza" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Część 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Część 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Wybierz powiązaną część" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Podkategorie" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Waluta zakupu tego towaru" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kopiuj obraz" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Kopiuj BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Towary" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Duplikuj część" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kopiuj obraz" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Kopiuj BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Usuń istniejące dane" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Pomiń nieprawidłowe wiersze" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Włącz tę opcję, aby pominąć nieprawidłowe wiersze" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Zainstalowane" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "Nie określono działania" msgid "No matching action found" msgstr "Nie znaleziono pasującej akcji" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Nie znaleziono wyników dla danych kodu kreskowego" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Znaleziono wyniki dla danych kodu kreskowego" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Kod kreskowy pasuje do istniejącego elementu" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Kod kreskowy nie pasuje do istniejących pozycji magazynowych" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Dalsze informacje wymagane do odbioru pozycji" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Otrzymana pozycja zlecenia zakupu" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Tryb Debugowania" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Wtyczka" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Nie znaleziono autora" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Nazwa szablonu" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Wzór nazwy pliku" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtry" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Domyślna wielkość strony dla raportów PDF" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Renderuj raport w orientacji poziomej" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Szerokość [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Wysokość [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Wycinek" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Obraz części" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Wydany" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "Razem" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Numer Seryjny" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Zainstalowane elementy" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Lokacje stanu magazynowego" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Właściciel" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Wybierz właściciela" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Nadrzędny towar" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Część podstawowa" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Wybierz pasującą część dostawcy dla tego towaru" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Zainstalowane w" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Ilość w magazynie" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Wyszukaj zlecenie zakupu" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Zlecenie zakupu dla tego towaru" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Usuń po wyczerpaniu" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Ilość musi być liczbą całkowitą" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Notatki do wpisu" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Należy podać wartość dla tego testu" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Wynik testu" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Element nadrzędny" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Termin minął" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Elementy podrzędne" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Numer seryjny już istnieje" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Podlokalizacje" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Część musi być dostępna do sprzedaży" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Scalone przedmioty magazynowe" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Przekonwertowano na wariant" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Dane wyjściowe kolejności kompilacji utworzone" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Dane wyjściowe kolejności kompilacji ukończone" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Odrzucono wynik zlecenia produkcji" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Zużyte przez kolejność kompilacji" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Wysłane na podstawie zlecenia sprzedaży" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Otrzymane na podstawie zlecenia zakupu" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Zwrócone na podstawie zlecenia zwrotu" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Wyślij do klienta" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Zwrócony od klienta" @@ -9527,19 +10124,19 @@ msgstr "Użytkownicy" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Informacje osobiste" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Uprawnienia" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Ważne daty" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Uprawnienia nadane" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Widok" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Uprawnienie do wyświetlania przedmiotów" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Dodaj" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Uprawnienie do dodawania przedmiotów" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Zmień" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Uprawnienie do edycji przedmiotów" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Usuń" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Uprawnienie do usuwania przedmiotów" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Zlecenia zakupu" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Czy to konto użytkownika jest aktywne" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Twoje konto zostało utworzone." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Zresetuj hasło" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Witamy w InvenTree" diff --git a/src/backend/InvenTree/locale/pt/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/pt/LC_MESSAGES/django.po index 34935b3cd2..d34fd0f40f 100644 --- a/src/backend/InvenTree/locale/pt/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/pt/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API endpoint não encontrado" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Usuário não tem permissão para ver este modelo" @@ -65,150 +69,155 @@ msgstr "Confirmação do endereço de email" msgid "You must type the same email each time." msgstr "Você deve digitar o mesmo e-mail todas as vezes." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "O endereço primário de e-mail não é válido." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "O domínio de e-mail providenciado não foi aprovado." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Unidade inválida fornecida ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nenhum valor fornecido" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Não foi possível converter {original} para {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Quantidade fornecida inválida" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Detalhes do erro podem ser encontrados no painel de administrador" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Insira uma Data" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Anotações" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Valor '{name}' não está no formato correto" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "O valor fornecido não corresponde ao padrão exigido: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Número serial em branco" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Número de série duplicado" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Intervalo do grupo {group} excede a quantidade permitida ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Nenhum número de série foi encontrado" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Remova as \"tags\" HTML deste valor" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Erro de conexão" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "O servidor respondeu com código estado inválido" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Ocorreu uma exceção" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "O servidor respondeu com valor inválido do tamanho de conteúdo" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Tamanho da imagem muito grande" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "O download da imagem excedeu o tamanho máximo" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "O servidor remoto retornou resposta vazia" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "A URL fornecida não é um arquivo de imagem válido" @@ -216,159 +225,203 @@ msgstr "A URL fornecida não é um arquivo de imagem válido" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Erro ao executar validação do plugin" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadados deve ser um objeto dict python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metadados da Extensão" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Campo de metadados JSON, para uso por extensões externas" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Padrão formatado incorretamente" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Chave de formato desconhecida especificada" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Chave de formato obrigatória ausente" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "O campo de referência não pode ficar vazio" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "A referência deve corresponder ao padrão exigido" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "O número de referência é muito grande" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Escolha inválida" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nome" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Descrição" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Descrição (opcional)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Caminho" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Nomes duplicados não podem existir sob o mesmo parental" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Notas Markdown (opcional)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Dados de código de barras" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Dados de código de barras de terceiros" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash de código de barras" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hash exclusivo de dados de código de barras" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Erro de servidor" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Log de erro salvo pelo servidor." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Imagem" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Preicsa ser um numero valido" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Moeda" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Selecione a Moeda nas opções disponíveis" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Copiar Parâmetros" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "Chinês (Simplificado)" msgid "Chinese (Traditional)" msgstr "Chinês (Tradicional)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Unidade física inválida" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Não é um código de moeda válido" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Situação do pedido" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Produção Progenitor" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Peça" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Categoria" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Produção deve ser cancelada antes de ser deletada" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Consumível" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opcional" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Montagem" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Monitorado" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Alocado" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Disponível" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "No pedido" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Ordem de Produção" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Local" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Ordens de Produções" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Usuário ou grupo responsável deve ser especificado" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Peça da ordem de produção não pode ser alterada" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Referência do pedido de produção" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referência" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Breve descrição da produção (opcional)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Selecionar peça para produção" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referência do pedido de venda" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Local de Origem" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Selecione a localização para pegar do estoque para esta produção (deixe em branco para tirar a partir de qualquer local de estoque)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Local de Destino" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Selecione o local onde os itens concluídos serão armazenados" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Quantidade de Produção" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Número de itens em estoque para produzir" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Itens concluídos" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Número de itens em estoque concluídos" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Progresso da produção" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Código de situação da produção" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Código de Lote" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Código do lote para esta saída de produção" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Criado em" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Data alvo final" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Data alvo para finalização de produção. Estará atrasado a partir deste dia." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Data de conclusão" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "Concluído por" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Usuário que emitiu este pedido de produção" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsável" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Usuário ou grupo responsável para este pedido de produção" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Link Externo" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link para URL externa" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Prioridade de Produção" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Prioridade deste pedido de produção" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Código do projeto" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Código do projeto para este pedido de produção" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Falha ao descarregar tarefa para concluir alocações de construção" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "O Pedido de produção {build} foi concluído!" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Um pedido de produção foi concluído" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Números de série devem ser fornecidos para peças rastreáveis" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nenhuma saída de produção especificada" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Saída de produção já completada" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Saída da produção não corresponde ao Pedido de Produção" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Quantidade deve ser maior que zero" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Quantidade não pode ser maior do que a quantidade de saída" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "O item de produção {serial} não passou todos os testes necessários" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Quantidade disponível ({q}) excedida" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Item da linha de Produção" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Objeto de produção" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Objeto de produção" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantidade" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Quantidade necessária para o pedido de produção" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Item de produção deve especificar a saída, pois peças mestres estão marcadas como rastreáveis" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Item estoque selecionado não coincide com linha da LDM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Quantidade deve ser 1 para estoque serializado" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Quantidade alocada ({q}) não deve exceder a quantidade disponível em estoque ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "O item do estoque está sobre-alocado" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Item de estoque" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Origem do item em estoque" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Quantidade do estoque para alocar à produção" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Instalar em" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Destino do Item do Estoque" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Nome da Peça" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Saída da Produção" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Saída de produção não coincide com a produção progenitora" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Peça de saída não coincide com a peça da ordem de produção" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Esta saída de produção já foi concluída" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "A saída de produção não está completamente alocada" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Entre a quantidade da saída de produção" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Quantidade inteira necessária para peças rastreáveis" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Quantidade inteira necessária, pois a lista de materiais contém peças rastreáveis" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Números de Série" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Digite os números de série para saídas de produção" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Local de estoque para a produção" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Alocar Números de Série Automaticamente" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Alocar automaticamente os itens necessários com os números de série correspondentes" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Os seguintes números de série já existem ou são inválidos" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Uma lista de saídas de produção deve ser fornecida" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Local de estoque para saídas recicladas" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Descartar alocações" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar quaisquer alocações de estoque para saídas sucateadas" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Motivo para sucatear saída(s) de produção" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Local para saídas de produção concluídas" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Aceitar Alocação Incompleta" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Concluir saídas se o estoque não tiver sido totalmente alocado" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Consumir Estoque Alocado" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Consumir qualquer estoque que já tenha sido alocado para esta produção" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Remover Saídas Incompletas" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Excluir quaisquer saídas de produção que não tenham sido completadas" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Não permitido" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Aceitar conforme consumido por esta ordem de produção" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Desatribua antes de completar este pedido de produção" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Estoque sobrealocado" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Como deseja manejar itens de estoque extras atribuídos ao pedido de produção" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Alguns itens de estoque foram sobrealocados" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Aceitar não alocados" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Aceitar que os itens de estoque não foram totalmente alocados para esta produção" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Estoque obrigatório não foi totalmente alocado" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Aceitar Incompleto" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Aceitar que o número requerido de saídas de produção não foi concluído" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Quantidade de produção requerida não foi concluída" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Pedido de produção tem saídas incompletas" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Linha de produção" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Saída da Produção" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Saída de produção deve indicar a mesma produção" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Item da linha de produção" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bin_item.part deve indicar a mesma peça do pedido de produção" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Item deve estar em estoque" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Quantidade disponível ({q}) excedida" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Saída de produção deve ser definida para alocação de peças rastreadas" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Saída de produção deve ser definida para alocação de peças não rastreadas" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Alocação do Item precisa ser fornecida" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Local de estoque onde peças serão extraídas (deixar em branco para qualquer local)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Local não incluso" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Não incluir itens de estoque deste local" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Estoque permutável" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Itens de estoque em múltiplos locais pode ser permutável" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Substituir Estoque" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Permitir alocação de peças substitutas" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Itens opcionais" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Alocar itens LDM opcionais para o pedido de produção" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Fornecedor da Peça" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Quantidade Alocada" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Rastreável" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Permitir variações" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Item LDM" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "Em Produção" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Estoque Disponível" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Pendente" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Produção" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Completado" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "O Pedido de produção {build} foi concluído!" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Um pedido de produção foi concluído" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Estoque obrigatório para o pedido de produção" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Pedido de produção vencido" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Pedido de produção {bo} está atrasada" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "É uma Ligação" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "É um arquivo" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "O Utilizador não tem permissão para remover este anexo" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Código da Moeda invalida" @@ -1539,15 +1641,20 @@ msgstr "Nenhum código de moeda válido foi fornecido" msgid "No plugin" msgstr "Sem extensão" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Atualizado" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Tempo da última atualização" @@ -1567,794 +1674,844 @@ msgstr "Código único do projeto" msgid "Project description" msgstr "Descrição do projeto" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Usuário ou grupo responsável por este projeto" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Valor da Configuração" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Valor escolhido não é uma opção válida" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Valor deve ser um valor booleano" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Valor deve ser um número inteiro" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "A frase senha deve ser diferenciada" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Usuario" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Quantidade de Parcelamentos" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Preço" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Preço unitário na quantidade especificada" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Ponto final" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Ponto final em qual o gancho web foi recebido" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Nome para este webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Ativo" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Usuário ou grupo responsável por este projeto" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Valor da Configuração" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Valor escolhido não é uma opção válida" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Valor deve ser um valor booleano" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Valor deve ser um número inteiro" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "A frase senha deve ser diferenciada" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Usuario" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Quantidade de Parcelamentos" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Preço" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Preço unitário na quantidade especificada" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Ponto final" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Ponto final em qual o gancho web foi recebido" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Nome para este webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Este gancho web está ativo" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token de acesso" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Segredo" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Segredo compartilhado para HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID da Mensagem" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Identificador exclusivo desta mensagem" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Servidor" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Servidor do qual esta mensagem foi recebida" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Cabeçalho" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Cabeçalho da mensagem" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Corpo" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Corpo da mensagem" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Ponto do qual esta mensagem foi recebida" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Trabalhado em" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "O trabalho desta mensagem foi concluído?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Título" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Ligação" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publicado" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Resumo" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Lida" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Esta notícia do item foi lida?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Arquivo de imagem" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Nome da unidade deve ser um identificador válido" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Nome da unidade" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Símbolo de unidade opcional" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definição" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definição de unidade" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Anexo" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Arquivo ausente" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Link externo não encontrado" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Selecione arquivo para anexar" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Comentario" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Valor" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Criado" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Última atualização" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Modelo de parâmetro" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Parâmetros da caixa de seleção não podem ter unidades" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Os parâmetros da caixa de seleção não podem ter escolhas" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Escolhas devem ser únicas" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Nome do modelo de parâmetro deve ser único" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Nome do Parâmetro" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Unidades" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Unidades físicas para este parâmetro" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Descrição do Parâmetro" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Caixa de seleção" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Este parâmetro é uma caixa de seleção?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Escolhas" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Opções válidas para este parâmetro (separadas por vírgulas)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Escolha inválida para valor do parâmetro" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Modelo" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Dados" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Valor do Parâmetro" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Anotação" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Campo opcional de notas" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Resultado" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Chave" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} cancelado" msgid "A order that is assigned to you was canceled" msgstr "Um pedido atribuído a você foi cancelado" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Itens Recebidos" @@ -2388,104 +2545,100 @@ msgstr "Os itens de um pedido de compra foram recebidos" msgid "Items have been received against a return order" msgstr "Os itens de um pedido de devolução foram recebidos" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Executando" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Tarefas Pendentes" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Tarefas Agendadas" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Tarefas com Falhas" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID da Tarefa" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "ID Único da Tarefa" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Tempo de bloqueio" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Nome da tarefa" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Função" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nome da função" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argumentos da tarefa" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Argumentos de Palavra-chave" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Argumentos Palavra-chave da Tarefa" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nome do arquivo" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "Nenhum grupo" @@ -2614,13 +2767,13 @@ msgstr "Intervalo de Atualização da Moeda" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Com que frequência atualizar as taxas de câmbio (defina como zero para desativar)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dias" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Extensão de Atualização de Moeda a utilizar" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validação rigorosa de URL" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Revisões de peças" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Habilitar campo de revisão para a Peça" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Permitir a exclusão da Montagem" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Permitir a remoção de peças usadas em uma montagem" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Padrão de expressão regular adequado para Peça IPN" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Permitir Duplicação IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que várias peças compartilhem o mesmo IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Permitir Edição IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Permitir trocar o valor do IPN enquanto se edita a peça" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Copiar dados da LDM da Peça" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Copiar dados da LDM por padrão quando duplicar a peça" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Copiar Dados de Parâmetro da Peça" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Copiar dados de parâmetros por padrão quando duplicar uma peça" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Copiar Dados Teste da Peça" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Copiar dados de teste por padrão quando duplicar a peça" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Copiar Parâmetros dos Modelos de Categoria" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Copiar parâmetros do modelo de categoria quando criar uma peça" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Peças são modelos por padrão" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Peças podem ser montadas a partir de outros componentes por padrão" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Componente" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Peças podem ser usadas como sub-componentes por padrão" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Comprável" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Peças são compráveis por padrão" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Vendível" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Peças vão vendíveis por padrão" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Peças vão rastreáveis por padrão" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Peças são virtuais por padrão" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Mostra peças relacionadas" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Mostrar peças relacionadas para uma peça" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Dados Iniciais de Estoque" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Permitir Criação de estoque inicial quando adicional uma nova peça" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Dados Iniciais de Fornecedor" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Permitir criação de dados iniciais de fornecedor quando adicionar uma nova peça" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Formato de Exibição do Nome da Peça" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formato para exibir o nome da peça" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Ícone de Categoria de Peça Padrão" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Ícone padrão de categoria de peça (vazio significa sem ícone)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Mínimo de Casas Decimais do Preço" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Mínimo número de casas decimais a exibir quando renderizar dados de preços" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Máximo Casas Decimais de Preço" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Número máximo de casas decimais a exibir quando renderizar dados de preços" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Usar Preços do Fornecedor" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Incluir quebras de preço do fornecedor nos cálculos de preços globais" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Sobrescrever histórico de compra" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Histórico do pedido de compra substitui os intervalos dos preços do fornecedor" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Usar Preços do Item em Estoque" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Usar preço inserido manualmente no estoque para cálculos de valores" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Idade do preço do Item em Estoque" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Não incluir itens em estoque mais velhos que este número de dias no cálculo de preços" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Usar Preço Variável" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir preços variáveis nos cálculos de valores gerais" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Apenas Ativar Variáveis" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Apenas usar peças variáveis ativas para calcular preço variáveis" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Intervalo de Reconstrução de Preços" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Número de dias antes da atualização automática dos preços das peças" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Preços Internos" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Habilitar preços internos para peças" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Sobrepor Valor Interno" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Se disponível, preços internos sobrepõe variação de cálculos de preço" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Ativar impressão de etiquetas" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Ativar impressão de etiqueta pela interface da internet" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "DPI da Imagem na Etiqueta" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Resolução de DPI quando gerar arquivo de imagens para fornecer à extensão de impressão de etiquetas" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Habilitar Relatórios" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Ativar geração de relatórios" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Modo de depuração" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Gerar relatórios em modo de depuração (saída HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Relatório de erros" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Registro de erros que ocorrem ao gerar relatórios" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Tamanho da página" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Tamanho padrão da página PDF para relatórios" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Forçar Unidades de Parâmetro" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Se as unidades são fornecidas, os valores do parâmetro devem corresponder às unidades especificadas" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Seriais Únicos Globais" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Números de série para itens de estoque devem ser globalmente únicos" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Excluir Estoque Esgotado" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Determina o comportamento padrão quando um item de estoque é esgotado" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Modelo de Código de Lote" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Modelo para gerar códigos de lote padrão para itens de estoque" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Validade do Estoque" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Ativar função de validade de estoque" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Vender estoque expirado" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Permitir venda de estoque expirado" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Tempo de Estoque Inativo" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Número de dias em que os itens em estoque são considerados obsoleto antes de vencer" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Produzir Estoque Vencido" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Permitir produção com estoque vencido" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Controle de propriedade do estoque" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Ativar controle de propriedade sobre locais e itens de estoque" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Ícone padrão do local de estoque" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Ícone padrão de local de estoque (vazio significa sem ícone)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Mostrar Itens de Estoque Instalados" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Exibir itens de estoque instalados nas tabelas de estoque" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Verificar BOM ao instalar itens" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Itens de estoque instalados devem existir na BOM para a peça parente" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Permitir Transferência Fora do Estoque" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Permitir que os itens que não estão em estoque sejam transferidos entre locais de estoque" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Produção" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Modelo necessário para gerar campo de referência do Pedido de Produção" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Requer Proprietário Responsável" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Um proprietário responsável deve ser atribuído a cada ordem" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Bloquear até os Testes serem Aprovados" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Impedir que as saídas da produção sejam concluídas até que todos os testes sejam aprovados" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Ativar Pedidos de Devolução" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Ativar funcionalidade de pedido de retorno na interface do usuário" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Devolução" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Editar os Pedidos de Devolução Concluídos" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Permitir a edição de pedidos de devolução após serem enviados ou concluídos" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Venda" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Modelo necessário para gerar campo de referência do Pedido de Venda" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Envio Padrão de Pedidos de Venda" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Habilitar criação de envio padrão com Pedidos de Vendas" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Editar os Pedidos de Vendas concluídos" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Permitir a edição de pedidos de vendas após serem enviados ou concluídos" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Modelo de Referência de Pedidos de Compras" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Modelo necessário para gerar campo de referência do Pedido de Compra" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Editar Pedidos de Compra Concluídos" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Permitir a edição de pedidos de compras após serem enviados ou concluídos" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Autocompletar Pedidos de Compra" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Marcar automaticamente os pedidos de compra como concluídos quando todos os itens de linha forem recebidos" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Habitar esquecer senha" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Habilitar a função \"Esqueci minha senha\" nas páginas de acesso" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Habilitar cadastro" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "Ativar auto-registro para usuários na página de entrada" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Ativar SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "Ativar SSO na página de acesso" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "Ativar registro SSO" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Ativar auto-registro por SSO para usuários na página de entrada" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Habitar esquecer senha" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Habilitar a função \"Esqueci minha senha\" nas páginas de acesso" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Habilitar cadastro" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "Ativar auto-registro para usuários na página de entrada" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "Ativar SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "Ativar SSO na página de acesso" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "Ativar registro SSO" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "Ativar auto-registro por SSO para usuários na página de entrada" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "" + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email obrigatório" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Exigir do usuário o e-mail no cadastro" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Auto-preencher usuários SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Preencher automaticamente os detalhes do usuário a partir de dados da conta SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Enviar email duplo" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "No registro pedir aos usuários duas vezes pelo email" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Senha duas vezes" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "No registro pedir aos usuários duas vezes pela senha" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Domínios permitidos" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Restringir registros a certos domínios (separados por vírgula, começando com @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grupo no cadastro" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Forçar AMF" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Os usuários devem usar uma segurança multifator." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Checar extensões no início" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Checar que todas as extensões instaladas no início — ativar em ambientes de contêineres" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Verificar por atualizações de plugin" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Habilitar verificações periódicas de atualizações para plugins instalados" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Ativar integração URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Ativar extensão para adicionar rotas URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Ativar integração de navegação" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Ativar extensões para integrar à navegação" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Ativa integração com aplicativo" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Ativar extensões para adicionar aplicativos" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Ativar integração do calendário" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Ativar extensões para executar tarefas agendadas" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Ativar integração de eventos" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Ativar extensões para responder a eventos internos" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Excluir Locais Externos" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Período de Balanço Automático" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Mostrar nomes completos dos usuários" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Mostrar Nomes Completos em vez de Nomes de Usuário" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Número de resultados mostrados em cada seção da janela de visualização de pesquisa" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Pesquisa de Regex" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Permitir expressôes comuns nas conultas de pesquisas" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Busca de Palavras Inteira" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Pesquisa retorna que palavra inteira coincide" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Tecla Esc Fecha Formulários" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Usar a tecla Esc para fechar fomulários modais" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Fixar Navbar" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "A posição do Navbar é fixa no topo da tela" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Formato da data" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Formato preferido para mostrar datas" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Receber relatório de erros" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Receber notificações para erros do sistema" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Últimas máquinas de impressão utilizadas" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Salvar as últimas máquinas de impressão usadas para um usuário" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Um domínio vazio não é permitido." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Nome de domínio inválido: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Empresa" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "Número de telefone do contato" msgid "Contact email address" msgstr "Endereço de e-mail do contato" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Contato" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Endereço" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Endereços" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Selecione a Empresa" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Título do endereço" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Título descrevendo a entrada de endereço" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Endereço Principal" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Definir como endereço principal" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Linha 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Linha de endereço 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Linha 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Linha de endereço 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Código Postal" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Cidade/Região" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Código Postal Cidade / Região" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Estado/Provincia" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Estado ou Província" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "País" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "País do endereço" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Notas de envio da transportadora" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Notas para o envio da transportadora" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Notas de envio interno" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Notas de envio para uso interno" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Link para as informações do endereço (externo)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Peça do Fabricante" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Peça base" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Selecionar peça" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Selecionar fabricante" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "NPF" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Número de Peça do Fabricante" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Descrição da peça do fabricante" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Unidades de pacote devem ser compatíveis com as unidades de peça base" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Unidades de pacote deve ser maior do que zero" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Parte do fabricante vinculado deve fazer referência à mesma peça base" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fornecedor" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Selecione o fornecedor" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Unidade de reserva de estoque fornecedor" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Selecionar peça do fabricante" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Descrição da peça fornecedor" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "preço base" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Taxa mínima (ex.: taxa de estoque)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Embalagem" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Embalagem de peças" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Quantidade de embalagens" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Quantidade total fornecida em um único pacote. Deixe em branco para itens únicos." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "múltiplo" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Pedir múltiplos" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Quantidade disponível do fornecedor" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Disponibilidade Atualizada" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Data da última atualização da disponibilidade dos dados" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Moeda padrão utilizada para este fornecedor" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Em Estoque" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Colocado" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Arquivo de dados" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Colunas" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Válido" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Desconhecido" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupo" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Referência do Pedido" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Criado por" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Pedido" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Peça Interna" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Concluído" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Pedido de Compra" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Pedido de Compra" msgid "Sales Order" msgstr "Pedido de Venda" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Devolver pedido" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Preço Total" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Preço total deste pedido" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Moeda do pedido" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Moeda para este pedido (deixe em branco para usar o padrão da empresa)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "O contato não corresponde à empresa selecionada" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Descrição do pedido (opcional)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Selecione o código do projeto para este pedido" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Link para página externa" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Data alvo" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Data esperada para entrega do pedido. O Pedido estará atrasado após esta data." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Data de emissão" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Dia que o pedido foi feito" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Usuário ou grupo responsável para este pedido" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Ponto de contato para este pedido" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Endereço da empresa para este pedido" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Referência do pedido" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Situação" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Situação do pedido de compra" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Empresa da qual os itens estão sendo encomendados" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Referencia do fornecedor" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Código de referência do pedido fornecedor" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "recebido por" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Dia que o pedido foi concluído" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Destino" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Fornecedor de peça deve corresponder a fornecedor da OC" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "O item de linha não corresponde ao pedido de compra" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Quantidade deve ser um número positivo" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Empresa para qual os itens foi vendidos" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Referência do Cliente " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Código de Referência do pedido do cliente" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Data de Envio" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "enviado por" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Item de linha não está associado a este pedido" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Nenhuma correspondência encontrada para os seguintes números de série" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Apenas um pedido aberto pode ser marcado como completo" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Pedido não pode ser concluído, pois, há envios incompletos" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Pedido não pode ser concluído, pois, há itens na linha incompletos" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Quantidade do item" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Referência do Item em Linha" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Observações do Item de Linha" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Data alvo para este item de linha (deixe em branco para usar a data alvo do pedido)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Descrição item de linha (opcional)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Contexto adicional para esta linha" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Preço Unitário" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "A peça do fornecedor deve corresponder ao fornecedor" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Fornecedor da Peça" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Recebido" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Número de itens recebidos" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Preço de Compra" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Preço unitário de compra" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Apenas peças vendáveis podem ser atribuídas a um pedido de venda" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Preço de Venda" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Preço de venda unitário" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Quantidade enviada" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Data do envio" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Data de Entrega" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Data da entrega do envio" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Verificado por" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Usuário que verificou esta remessa" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Remessa" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Número do Envio" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Número de Rastreamento" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Informação de rastreamento da remessa" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Número da Fatura" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Número de referência para fatura associada" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "O pedido já foi enviado" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Remessa não foi alocada nos itens de estoque" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "O item do estoque não foi atribuído" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Não é possível alocar o item de estoque para uma linha de uma peça diferente" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Não é possível alocar uma linha sem uma peça" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "A quantidade de alocação não pode exceder a quantidade em estoque" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Quantidade alocada deve ser maior que zero" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Quantidade deve ser 1 para item de estoque serializado" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Pedidos de venda não coincidem com a remessa" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Remessa não coincide com pedido de venda" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Linha" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Referência de remessa do pedido de venda" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Selecione o item de estoque para alocar" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Insira a quantidade de atribuição de estoque" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Referência de Pedidos de Devolução" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Empresa da qual os itens estão sendo retornados" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Estado do pedido de retorno" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Selecione o item a ser devolvido pelo cliente" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Data de Recebimento" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Despesa/gastos" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Gastos com esta linha de itens" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Gastos para reparar e/ou devolver esta linha de itens" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Copiar Parâmetros" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Itens de linha" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Nome do Fornecedor" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Pedido não pode ser cancelado" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Permitir que o pedido seja fechado com itens de linha incompletos" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "O pedido tem itens da linha incompletos" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "O pedido não está aberto" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Moeda de preço de compra" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Código (SKU)" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Numero interno do produto" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "A peça do fornecedor deve ser especificada" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "O pedido de compra deve ser especificado" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "O fornecedor deve corresponder o pedido de compra" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Pedido de compra deve corresponder ao fornecedor" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Itens de linha" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Selecione o local de destino para os itens recebidos" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Digite o código do lote para itens de estoque recebidos" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Data de validade" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Digite o número de série para itens de estoque recebidos" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Código de barras lido" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Código de barras já em uso" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Itens de linha deve ser providenciados" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Loca de destino deve ser especificado" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Código de barras fornecido deve ser único" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Envios concluídos" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Moeda de preço de venda" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Nenhum detalhe da remessa fornecido" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Item de linha não está associado a este pedido" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Quantidade deve ser positiva" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Digite números de série para alocar" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "O pedido já foi enviado" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "O envio não está associado a este pedido" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Nenhuma correspondência encontrada para os seguintes números de série" - -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" + +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Devolver item do pedido" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Item do pedido não bate com o pedido de devolução" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Item do pedido já foi recebido" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Itens só podem ser recebidos de pedidos em processamento" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Tipo de moeda para o item do pedido" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Perdido" @@ -5718,1279 +6125,1312 @@ msgstr "Perdido" msgid "Returned" msgstr "Retornado" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Em Progresso" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Devolução" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Consertar" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Substituir" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Reembolsar" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Recusar" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Emitido" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Pedido de compra vencido" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Pedido de compra {po} está atrasada" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Pedido de venda vencido" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Pedido de venda {so} está atrasada" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Categoria da Peça" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Categorias de Peça" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Local Padrão" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Local padrão para peças desta categoria" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Estrutural" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Peças não podem ser diretamente atribuídas a uma categoria estrutural, mas podem ser atribuídas a categorias filhas." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Palavras-chave Padrão" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Palavras-chave padrão para peças nesta categoria" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ícone" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ícone (opcional)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Você não pode tornar esta categoria em estrutural, pois, algumas partes já estão alocadas!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Valor Padrão" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Valor Padrão do Parâmetro" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Peças" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Peça '{self}' não pode ser utilizada na BOM para '{parent}' (recursiva)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Peça '{parent}' é usada na BOM para '{self}' (recursiva)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN deve corresponder ao padrão regex {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Item em estoque com este número de série já existe" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Não é permitido duplicar IPN em configurações de partes" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Uma parte com este Nome, IPN e Revisão já existe." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Peças não podem ser atribuídas a categorias estruturais!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Nome da peça" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "É um modelo" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Esta peça é uma peça modelo?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Esta peça é variante de outra peça?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variante de" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Descrição da peça (opcional)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Palavras chave" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Palavras-chave para melhorar a visibilidade nos resultados da pesquisa" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Categoria da Peça" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Revisão de peça ou número de versão" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revisão" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Onde este item é armazenado normalmente?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Validade Padrão" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Validade (em dias) para itens do estoque desta peça" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Estoque Mínimo" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Nível mínimo de estoque permitido" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Unidade de medida para esta peça" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Essa peça pode ser construída a partir de outras peças?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Essa peça pode ser usada para construir outras peças?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Esta parte tem rastreamento para itens únicos?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Esta peça pode ser comprada de fornecedores externos?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Esta peça pode ser vendida a clientes?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Esta parte está ativa?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Esta é uma peça virtual, como um software de produto ou licença?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Soma de Verificação da LDM" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Soma de verificação da LDM armazenada" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "LDM conferida por" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "LDM verificada no dia" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Criação de Usuário" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Proprietário responsável por esta peça" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Venda múltipla" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Moeda usada para armazenar os cálculos de preços" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Custo Mínimo da LDM" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Custo mínimo das peças componentes" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Custo Máximo da LDM" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Custo máximo das peças componentes" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Custo Mínimo de Compra" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Custo mínimo histórico de compra" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Custo Máximo de Compra" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Custo máximo histórico de compra" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Preço Interno Mínimo" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Custo mínimo baseado nos intervalos de preço internos" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Preço Interno Máximo" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Custo máximo baseado nos intervalos de preço internos" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Preço Mínimo do Fornecedor" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Preço mínimo da peça de fornecedores externos" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Preço Máximo do Fornecedor" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Preço máximo da peça de fornecedores externos" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Custo Mínimo variável" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Custo mínimo calculado das peças variáveis" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Custo Máximo Variável" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Custo máximo calculado das peças variáveis" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Custo Mínimo" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Sobrepor o custo mínimo" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Custo Máximo" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Sobrepor o custo máximo" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Custo total mínimo calculado" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Custo total máximo calculado" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Preço Mínimo de Venda" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Preço mínimo de venda baseado nos intervalos de preço" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Preço Máximo de Venda" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Preço máximo de venda baseado nos intervalos de preço" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Custo Mínimo de Venda" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Preço histórico mínimo de venda" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Custo Máximo de Venda" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Preço histórico máximo de venda" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Peça para Balanço" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Total de Itens" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Número de entradas de estoques individuais no momento do balanço" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Estoque total disponível no momento do balanço" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Data" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Data de realização do balanço" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Custo Mínimo de Estoque" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Custo mínimo estimado de estoque disponível" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Custo Máximo de Estoque" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Custo máximo estimado de estoque disponível" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Nome de Teste" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Insira um nome para o teste" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Descrição do Teste" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Digite a descrição para este teste" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Requerido" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Este teste é obrigatório passar?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Requer Valor" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Este teste requer um valor ao adicionar um resultado de teste?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Anexo obrigatório" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Este teste requer um anexo ao adicionar um resultado de teste?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Selecione a Peça Parental" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Sub peça" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Selecionar peça a ser usada na LDM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Quantidade de LDM para este item LDM" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Este item LDM é opcional" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Este item LDM é consumível (não é rastreado nos pedidos de construção)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Referência do Item LDM" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Notas do Item LDM" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Soma de verificação" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Soma de Verificação da LDM da linha" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Validado" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "O item da LDM foi validado" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Obtém herdados" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Este item da LDM é herdado por LDMs para peças variáveis" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Itens de estoque para as peças das variantes podem ser usados para este item LDM" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Quantidade deve ser valor inteiro para peças rastreáveis" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Sub peça deve ser especificada" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Substituir Item da LDM" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "A peça de substituição não pode ser a mesma que a peça mestre" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Item LDM Parental" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Substituir peça" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Parte 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Parte 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Selecionar Peça Relacionada" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Relacionamento da peça não pode ser criada com ela mesma" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Relação duplicada já existe" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Categoria de peça pai" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Sub-categorias" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Moeda de compra deste item de estoque" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Peça Original" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Selecione a peça original para duplicar" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Copiar imagem" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Copiar imagem da peça original" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Copiar LDM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Copiar lista de materiais da peça original" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Copiar dados do parâmetro da peça original" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Copiar Notas" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Copiar imagem da peça original" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Quantidade Inicial de Estoque" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Especificar a quantidade inicial de estoque para a peça. Se for zero, nenhum estoque é adicionado." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Local Inicial do Estoque" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Especifique o local do estoque inicial para esta Peça" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Selecione o fornecedor (ou deixe em branco para pular)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Selecione fabricante (ou deixe em branco para pular)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Número de Peça do Fabricante" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "A empresa selecionada não é um fornecedor válido" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "A empresa selecionada não é um fabricante válido" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "A peça do fabricante que corresponde a essa MPN já existe" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "A peça do fornecedor que corresponde a essa SKU já existe" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Nome da Categoria" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Produzindo" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Itens de Estoque" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Estoque Total" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Peça duplicada" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Copiar dados iniciais de outra peça" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Copiar imagem" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Copiar imagem da peça original" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Copiar LDM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Copiar lista de materiais da peça original" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Copiar Notas" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Copiar imagem da peça original" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Estoque inicial" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Criar peça com a quantidade inicial de estoque" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Informações do Fornecedor" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Adicionar informação inicial de fornecedor para esta peça" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Copiar Parâmetros da Categoria" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Copiar modelos de parâmetros a partir de categoria de peça selecionada" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Imagem Existente" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Nome de arquivo de uma imagem de peça existente" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "A imagem não existe" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Validar a Lista de Materiais completa" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Pode Produzir" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Preço Mínimo" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Sobrepor valor calculado para preço mínimo" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Moeda do preço mínimo" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Preço Máximo" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Sobrepor valor calculado para preço máximo" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Moeda do preço máximo" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Atualizar" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Atualizar preços desta peça" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Não foi possível converter das moedas fornecidas para {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Preço mínimo não pode ser maior que o preço máximo" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Preço máximo não pode ser menor que o preço mínimo" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Selecionar peça para copiar a LDM" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Remover Dado Existente" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Remova itens LDM existentes antes de copiar" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Incluir Herdados" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Incluir itens LDM que são herdados de peças modelo" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Pular Linhas inválidas" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Habilitar esta opção para pular linhas inválidas" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Copiar Peças Substitutas" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Copiar peças de substitutas quando duplicar itens de LDM" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Notificação de estoque baixo" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "O estoque disponível para {part.name} caiu abaixo do nível mínimo definido" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Instalado" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "Nenhuma ação especificada" msgid "No matching action found" msgstr "Nenhuma ação correspondente encontrada" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Nenhum resultado encontrado para os dados do código de barras" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Coincidência encontrada para dados de código de barras" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Código de barras corresponde ao item existente" @@ -7055,51 +7495,67 @@ msgstr "Nenhuma peça de fornecedor correspondente encontrada" msgid "Multiple matching supplier parts found" msgstr "Múltiplas peças de fornecedores correspondentes encontradas" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Peça de fornecedor correspondente" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Item do pedido já foi recebido" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Diversos itens de linha correspondentes encontrados" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Nenhum item de linha correspondente encontrado" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Código de barras não corresponde a item de estoque válido" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Item do estoque não corresponde ao item de linha" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Estoque insuficiente disponível" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Item de estoque atribuído para pedido de venda" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Não há informação suficiente" @@ -7108,23 +7564,23 @@ msgstr "Não há informação suficiente" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Mais informações necessárias para receber o item de linha" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Item de linha do pedido de compra recebido" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Fornece suporte nativo para códigos de barras" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL usada para enviar mensagens para um canal do Slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Abrir link" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Providenciar suporte nativo para impressão de etiquetas em PDF" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Modo de depuração" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Ativar o modo de depuração - retorna HTML bruto em vez de PDF" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Tamanho da página para folha de etiqueta" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Pular Etiquetas" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Ignorar este número de etiquetas quando imprimir folhas de etiquetas" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Borda" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Imprima uma borda em torno de cada etiqueta" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Paisagem" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Imprimir a folha de etiqueta no modo paisagem" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "Impressora de folhas de etiqueta do InvenTree" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Matriz várias etiquetas em uma única folha" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "A etiqueta é muito grande para tamanho de página" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Nenhuma etiqueta foi gerada" @@ -7753,77 +8217,85 @@ msgstr "Fornece suporte para escanear códigos de barras TME" msgid "The Supplier which acts as 'TME'" msgstr "O fornecedor que atua como 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Plugin instalado com sucesso" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Plugin instalado na {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Extensões" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Nenhum autor encontrado" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "A extensão '{p}' não é compatível com a versão atual do InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Extensão requer pelo menos a versão {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Extensão requer no máximo a versão {v}" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Itens" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Ofício" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Carta" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Nome do modelo" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Padrão de Nome de Arquivo" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtros" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Tamanho da página para relatórios PDF" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Renderizar relatório em orientação paisagem" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Largura [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Largura da etiqueta, em mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Altura da Etiqueta, em mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Recorte" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Relatar arquivo de recorte" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Descrição do arquivo de recorte" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Patrimônio" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Reportar arquivo de ativos" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Descrição do arquivo de ativos" @@ -8291,23 +8771,23 @@ msgstr "Descrição do arquivo de ativos" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Selecione o modelo de etiqueta" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "Materiais necessários" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Imagem da peça" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Emitido" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Necessário para" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Número de Sério" @@ -8405,7 +8882,7 @@ msgstr "Relatório Teste do Item em Estoque" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Itens instalados" @@ -8438,810 +8915,922 @@ msgstr "Sem resultado (obrigatório)" msgid "No result" msgstr "Nenhum resultado" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Arquivo de imagem não encontrado" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "Tag part_image necessita de uma instância de Peça" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "Tag company_image necessita de uma instância de Empresa" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Código da situação" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Localização externa" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Árvore de Peças" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Data de validade antes" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Data de validade depois" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Inativo" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Quantidade obrigatória" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Uma peça válida deve ser fornecida" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "A peça do fornecedor informado não existe" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "A peça do fornecedor tem um tamanho de pacote definido, mas o item use_pack_size não foi definida" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Números de série não podem ser fornecidos para uma parte não rastreável" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Tipo de Local de estoque" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Tipos de Locais de estoque" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Ícone padrão para todos os locais que não tem um ícone (opcional)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Localização do estoque" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Locais de estoque" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Responsavel" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Selecionar Responsável" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Os itens de estoque podem não estar diretamente localizados em um local de estoque estrutural, mas podem ser localizados em locais filhos." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Externo" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Esta é uma localização de estoque externo" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Tipo de localização" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Tipo de Local de Estoque para esta locação" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Você não pode tornar este local do estoque estrutural, pois alguns itens de estoque já estão localizados nele!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Os itens de estoque não podem estar localizados em locais de estoque estrutural!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Item de estoque não pode ser criado para peças virtuais" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Tipo de peça('{self.supplier_part.part}') deve ser {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "A quantidade deve ser 1 para um item com número de série" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Número de série não pode ser definido se quantidade maior que 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "O item não pode pertencer a si mesmo" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Item deve ter uma referência de produção se is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Referência de produção não aponta ao mesmo objeto da peça" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Item de Estoque Parental" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Peça base" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Selecione uma peça do fornecedor correspondente para este item de estoque" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Onde está localizado este item de estoque?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Embalagem deste item de estoque está armazenado em" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Instalado em" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Este item está instalado em outro item?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Número de série para este item" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Código do lote para este item de estoque" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Quantidade de Estoque" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Produção de Origem" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Produção para este item de estoque" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Consumido por" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Pedido de produção que consumiu este item de estoque" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Pedido de compra Fonte" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Pedido de Compra para este item de estoque" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Destino do Pedido de Venda" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Data de validade para o item de estoque. Estoque será considerado expirado após este dia" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Excluir quando esgotado" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Excluir este item de estoque quando o estoque for esgotado" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Preço de compra unitário único no momento da compra" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Convertido para peça" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Peça não está definida como rastreável" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Quantidade deve ser inteira" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Quantidade não deve exceder a quantidade em estoque ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "A quantidade não corresponde aos números de série" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Item em estoque foi reservado para um pedido" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Item em estoque está instalado em outro item" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "item em estoque contem outro(s) items" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Item em estoque foi reservado para outro cliente" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Item no estoque está em produção no momento" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Itens de série não podem ser mesclados" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Item de estoque duplicado" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Itens de estoque devem se referir à mesma peça" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Itens de estoque devem se referir à mesma peça do fornecedor" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Códigos de estado do estoque devem corresponder" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Item do estoque não pode ser realocado se não houver estoque da mesma" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Observações de entrada" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Deve-se fornecer o valor desse teste" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "O anexo deve ser enviado para este teste" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Resultado do teste" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Valor da saída do teste" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Anexo do resultado do teste" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Notas do teste" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Item Primário" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Usar tamanho do pacote ao adicionar: a quantidade definida é o número de pacotes" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Inserir número de série para novos itens" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Expirado" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Itens Filhos" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Preço de compra para este item de estoque, por unidade ou pacote" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Insira o número de itens de estoque para serializar" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Quantidade não deve exceder a quantidade disponível em estoque ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Local de destino do estoque" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Números de série não podem ser atribuídos a esta peça" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Números de série já existem" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Selecione o item de estoque para instalar" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Quantidade a Instalar" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Insira a quantidade de itens a instalar" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Adicionar nota de transação (opcional)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "A quantidade para instalar deve ser pelo menos 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Item de estoque indisponível" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Peça selecionada não está na Lista de Materiais" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Quantidade a instalar não deve exceder a quantidade disponível" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Local de destino para o item desinstalado" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Selecione peça para converter o item de estoque em" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Peça selecionada não é uma opção válida para conversão" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Não é possível converter o item de estoque com a Peça de Fornecedor atribuída" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Código de estado do item estoque" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Selecione peça para converter o item de estoque em" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Peça selecionada não é uma opção válida para conversão" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Não é possível converter o item de estoque com a Peça de Fornecedor atribuída" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Selecionar itens de estoque para mudar estados" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Nenhum item de estoque selecionado" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Sub-locais" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Parte deve ser comercializável" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Item é alocado para um pedido de venda" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Item está alocado a um pedido de produção" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Cliente para atribuir itens de estoque" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "A empresa selecionada não é um cliente" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Nodas atribuídas a estoque" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Uma lista de item de estoque deve ser providenciada" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Notas de fusão de estoque" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Permitir fornecedores divergentes" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Permitir a fusão de itens de estoque de fornecedores diferentes" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Permitir estado incompatível" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Permitir a fusão de itens de estoque com estado diferentes" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Ao menos dois itens de estoque devem ser providenciados" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Valor da chave primária do Item Estoque" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Notas da transação de estoque" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Notas da transação de estoque" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Itens de estoque mesclados" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Convertido para variável" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Criação dos pedidos de produção criado" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Criação do pedido de produção completado" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Saída do pedido de produção rejeitada" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Usado no pedido de produção" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Enviado contra o Pedido de Venda" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Recebido referente ao Pedido de Compra" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Devolvido contra Pedido de Retorno" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Enviado ao cliente" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Devolvido pelo cliente" @@ -9527,19 +10124,19 @@ msgstr "Usuários" msgid "Select which users are assigned to this group" msgstr "Selecione quais usuários estão atribuídos a este grupo" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Informações pessoais" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Permissões" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Datas importantes" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "O token foi revogado" @@ -9547,279 +10144,283 @@ msgstr "O token foi revogado" msgid "Token has expired" msgstr "Token expirou" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "Token da API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Tokens de API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Nome do Token" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Nome de token personalizado" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Data de validade do token" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Visto pela Última Vez" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Última vez que o token foi usado" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Revogado" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Permissão definida" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Visualizar" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Permissão para ver itens" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Adicionar" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Permissão para adicionar itens" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Alterar" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Permissões para editar itens" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Excluir" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Permissão para excluir itens" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Administrador" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Pedidos de compra" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Pedidos de vendas" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Pedidos de Devolução" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Nome de usuário" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Primeiro Nome" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Sobrenome" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Sua conta foi criada." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Por favor, use a função de redefinir senha para acessar" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Bem-vindo(a) ao InvenTree" diff --git a/src/backend/InvenTree/locale/pt_BR/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/pt_BR/LC_MESSAGES/django.po index 96f9ded308..bdd2f5563d 100644 --- a/src/backend/InvenTree/locale/pt_BR/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/pt_BR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -17,45 +17,49 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API endpoint não encontrado" -#: InvenTree/api.py:438 -msgid "List of items must be provided for bulk operation" -msgstr "" - #: InvenTree/api.py:445 +msgid "List of items must be provided for bulk operation" +msgstr "Uma lista de itens deve ser fornecida para a operação em massa" + +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Os itens devem ser fornecidos como lista" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Lista de itens inválida fornecida" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Todos os filtros devem ser usados apenas como verdadeiro" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Nenhum item corresponde com os critérios fornecidos" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Nenhum dado fornecido" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Este campo deve ser único." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "O item não corresponde mais aos critérios fornecidos" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "O usuário não tem permissão para visualizar esse modelo" #: InvenTree/auth_overrides.py:58 msgid "Email (again)" -msgstr "Email (novamente)" +msgstr "E-mail (novamente)" #: InvenTree/auth_overrides.py:62 msgid "Email address confirmation" @@ -65,150 +69,155 @@ msgstr "E-mail de confirmação" msgid "You must type the same email each time." msgstr "Você deve digitar o mesmo e-mail todas às vezes." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "O endereço de e-mail fornecido não é válido." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "O domínio de e-mail fornecido não foi aprovado." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Unidade fornecida inválida ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nenhum valor fornecido" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Não foi possível converter {original} para {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Quantidade inválida" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "O servidor está recarregando temporariamente, tente novamente" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Detalhes do erro podem ser encontrados no painel de administração" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Informe a data" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Valor decimal inválido" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Observações" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "O valor '{name}' não aparece no formato padrão" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "O valor fornecido não corresponde ao padrão exigido: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Não é possível serializar mais de 1000 itens de uma vez" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Número serial em branco" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Número serial duplicado" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" -msgstr "Grupo invalido:{group}" +msgstr "Grupo inválido:{group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Intervalo do grupo {group} excede a quantidade permitida ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Nenhum número de série foi encontrado" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "O número de números seriais únicos ({n}) deve corresponder a quantidade ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Remover as \"tags\" HTML deste valor" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Os dados contêm conteúdo de marcação proibido" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" -msgstr "" +msgstr "URL inválida: sem nome de host" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" -msgstr "" +msgstr "URL inválida: não foi possível resolver o nome de host" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" -msgstr "" +msgstr "A URL aponta para um endereço IP privado ou reservado" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" -msgstr "" +msgstr "Redirecionamentos em excesso" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Erro de conexão" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "O servidor respondeu com código de estado inválido" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Ocorreu uma exceção" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "O servidor respondeu com valor inválido do tamanho de conteúdo" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" -msgstr "" +msgstr "O tamanho da imagem é grande demais" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "O download da imagem excedeu seu tamanho máximo" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "O servidor remoto retornou uma resposta vazia" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "A URL fornecida não é um arquivo de imagem válido" @@ -216,158 +225,202 @@ msgstr "A URL fornecida não é um arquivo de imagem válido" msgid "Log in to the app" msgstr "Entrar no aplicativo" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "Falha na verificação CSRF. Certifique-se de que INVENTREE_SITE_URL e INVENTREE_TRUSTED_ORIGINS estejam configurados corretamente." + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Você deve habilitar a autenticação de dois fatores antes de fazer qualquer coisa." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" -msgstr "" +msgstr "Erro ao executar a validação do plugin" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadados deve ser um objeto dict python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" -msgstr "Plugin de Metadados" +msgstr "Plugin de metadados" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Campo de metadados JSON, para uso de plugins externos" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Padrão formatado incorretamente" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Chave de formato desconhecida especificada" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Chave de formato obrigatório ausente" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "O campo de referência não deve ficar vazio" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "A referência deve corresponder ao padrão exigido" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "O número de referência é muito longo" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Escolha inválida" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nome" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Descrição" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Descrição (opcional)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Caminho" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Nomes duplicados não podem existir sob o mesmo parental" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" -msgstr "Notas Markdown (opcional)" +msgstr "Notas markdown (opcional)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Dados de código de barras" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Dados de código de barras de terceiros" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Hash de código de barras" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hash exclusivo de dados de código de barras" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Código de barras existente encontrado" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Erro de servidor" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Um erro foi registrado pelo servidor." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Imagem" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Deve ser um número válido" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Moeda" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Selecione a moeda entre as opções disponíveis" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Este campo não pode ser nulo." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Valor inválido" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Formato de conteúdo inválido" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Tipo de conteúdo não encontrado" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" -msgstr "" +msgstr "O tipo de conteúdo não corresponde à classe mixin exigida" + +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Copiar parâmetros" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "Copiar parâmetros do item original" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Copiar linhas" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Copiar itens de linha do pedido original" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Copiar linhas extras" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Copiar itens de linha extras do pedido original" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "Opções de duplicação" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "Especifique as opções para duplicar este item" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "Original" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "Selecione a instância para duplicar" #: InvenTree/setting/locales.py:20 msgid "Arabic" @@ -407,11 +460,11 @@ msgstr "Espanhol (mexicano)" #: InvenTree/setting/locales.py:29 msgid "Estonian" -msgstr "" +msgstr "Estoniano" #: InvenTree/setting/locales.py:30 msgid "Farsi / Persian" -msgstr "Farsi / Persa" +msgstr "Farsi / persa" #: InvenTree/setting/locales.py:31 msgid "Finnish" @@ -521,46 +574,48 @@ msgstr "Chinês (simplificado)" msgid "Chinese (Traditional)" msgstr "Chinês (tradicional)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Atualização disponível" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Uma atualização para o InvenTree está disponível" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Unidade física inválida" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "O código de moeda não é válido" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" -msgstr "Situação de pedido" +msgstr "Status de pedido" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" -msgstr "Produção Progenitora" +msgstr "Produção principal" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" -msgstr "Incluir Variáveis" +msgstr "Incluir variáveis" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,443 +624,452 @@ msgstr "Incluir Variáveis" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 #: templates/email/part_event_notification.html:15 #: templates/email/stale_stock_notification.html:17 msgid "Part" -msgstr "Parte" +msgstr "Peça" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Categoria" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" -msgstr "Construção de Ancestrais" +msgstr "Construção de ancestrais" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Atribuído a mim" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Atribuído a" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Criado antes" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Criado após" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Tem a data inicial" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Data inicial antes" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Data de início após" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Tem data limite" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Data limite antes" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Data limite depois" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Concluído antes" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Concluído após" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" -msgstr "Data Mínima" +msgstr "Data mínima" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Data máxima" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Excluir árvore" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" -msgstr "A compilação deve ser cancelada antes de ser excluída" +msgstr "A produção deve ser cancelada antes de ser excluída" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Consumível" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opcional" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Montagem" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Rastreado" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testável" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Pedido pendente" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Alocado" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" -msgstr "" +msgstr "Consumido" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Disponível" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Em pedido" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" -msgstr "" +msgstr "Produção não encontrada" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" -msgstr "Ordem da compilação" +msgstr "Pedido de produção" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Local" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Saída" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." -msgstr "" +msgstr "Filtrar por ID do item de estoque de saída. Use 'null' para encontrar itens de produção não instalados." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" -msgstr "Ordens de Produções" +msgstr "Pedidos de produção" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "O BOM da montagem não foi validado" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" -msgstr "Ordem de compilação não pode ser criada para uma parte inativa" +msgstr "Pedido de produção não pode ser criada para uma peça inativa" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" -msgstr "Ordem de compilação não pode ser criado para uma parte desbloqueada" +msgstr "Pedido de produção não pode ser criado para uma peça desbloqueada" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" -msgstr "Criar ordens só pode ser realizado externamente para partes compráveis" +msgstr "Criar ordens só pode ser realizado externamente para peças compráveis" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Usuário ou grupo responsável deve ser especificado" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" -msgstr "Parte do pedido de compilação não pode ser alterada" +msgstr "Peça do pedido de produção não pode ser alterada" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "A data limite deve ser posterior à data inicial" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Referência do pedido de produção" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referência" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Breve descrição da produção (opcional)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" -msgstr "" +msgstr "Pedido de produção ao qual esta produção está alocada" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Selecione a peça para construir" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referência do pedido de venda" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" -msgstr "" +msgstr "Pedido de venda ao qual esta produção está alocada" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" -msgstr "Local de Origem" +msgstr "Local de origem" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" -msgstr "Selecione o local para fazer estoque para esta compilação (deixe em branco para tirar a partir de qualquer local de estoque)" +msgstr "Selecione o local para fazer estoque para esta produção (deixe em branco para tirar a partir de qualquer local de estoque)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" -msgstr "Produção Externa" +msgstr "Produção externa" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" -msgstr "Esta ordem de compilação é atendida externamente" +msgstr "Este pedido de produção é atendido externamente" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" -msgstr "Local de Destino" +msgstr "Local de destino" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Selecione o local onde os itens concluídos serão armazenados" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" -msgstr "Quantidade de Produção" +msgstr "Quantidade de produção" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Número de itens em estoque para produzir" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Itens concluídos" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Número de itens em estoque concluídos" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" -msgstr "Progresso da produção" +msgstr "Status da produção" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Código de situação da produção" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Código do lote" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Código do lote para esta saída de produção" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Criado em" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Data inicial da produção" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" -msgstr "Data de início agendada para esta ordem de produção" +msgstr "Data de início agendada para este pedido de produção" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Data alvo final" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Data limite para finalização de produção. Estará atrasado a partir deste dia." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Data de conclusão" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" -msgstr "concluído por" +msgstr "Concluído por" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Emitido por" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" -msgstr "Usuário que emitiu esta ordem de produção" +msgstr "Usuário que emitiu este pedido de produção" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsável" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" -msgstr "Usuário ou grupo responsável para esta ordem de produção" +msgstr "Usuário ou grupo responsável para este pedido de produção" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" -msgstr "Link Externo" +msgstr "Link externo" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link para URL externa" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" -msgstr "Prioridade de Produção" +msgstr "Prioridade de produção" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" -msgstr "Prioridade desta ordem de compilação" +msgstr "Prioridade deste pedido de produção" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" -msgstr "Código do Projeto" +msgstr "Código do projeto" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" -msgstr "Código do projeto para esta ordem de compilação" +msgstr "Código do projeto para este pedido de produção" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Não é possível concluir o pedido de produção com pedidos secundários abertos" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Não é possível concluir o pedido com saídas incompletas" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Falha ao descarregar tarefa para concluir alocações de compilação" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "O Pedido de produção {build} foi concluído" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Um pedido de produção foi concluído" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Números de série devem ser fornecidos para peças rastreáveis" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nenhuma saída de produção especificada" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Saída da produção já está concluída" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" -msgstr "Saída da produção não corresponde à Ordem de Produção" +msgstr "Saída da produção não corresponde à pedido de produção" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "A saída de produção já foi concluída" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Quantidade deve ser maior que zero" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "A quantidade não pode ser maior que a quantidade de saída" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "A saída da produção não passou em todos os testes necessários" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "A saída da produção {serial} não passou em todos os testes necessários" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" -msgstr "" +msgstr "Os itens de estoque alocados ainda estão em produção" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" -msgstr "" +msgstr "Não é possível concluir parcialmente uma saída de produção com itens alocados" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "O item de estoque não existe mais" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Quantidade disponível ({q}) excedida" + +#: build/models.py:2167 msgid "Build Order Line Item" -msgstr "Item da ordem de produção" +msgstr "Item de linha do pedido de produção" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Compilar objeto" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Compilar objeto" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Quantidade" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Quantidade necessária para o pedido de produção" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" -msgstr "" +msgstr "Quantidade de estoque consumido" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Item de produção deve especificar a saída, pois peças mestres estão marcadas como rastreáveis" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "O item de estoque selecionado não coincide com linha da BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" -msgstr "" +msgstr "A quantidade alocada deve ser maior que zero" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Quantidade deve ser 1 para estoque serializado" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Quantidade alocada ({q}) não deve exceder a quantidade disponível em estoque ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" -msgstr "O item do estoque está sobre-alocado" +msgstr "O item de estoque está superalocado" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" -msgstr "Item de Estoque" +msgstr "Item de estoque" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Origem do item em estoque" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Quantidade do estoque para alocar à produção" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Instalar em" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" -msgstr "Destino do Item do Estoque" +msgstr "Destino do item do estoque" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Nível de produção" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" -msgstr "Nome da Peça" +msgstr "Nome da peça" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" -msgstr "Saída da Produção" +msgstr "Saída da produção" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" -msgstr "Saída de produção não coincide com a produção progenitora" +msgstr "Saída de produção não coincide com a produção principal" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" -msgstr "Peça de saída não coincide com a peça da ordem de produção" +msgstr "Peça de saída não coincide com a peça do pedido de produção" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Esta saída de produção já foi concluída" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Esta saída de produção não está totalmente alocada" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Insira a quantidade para construir a saída de produção" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Quantidade inteira necessária para peças rastreáveis" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Quantidade inteira necessária, pois a lista de materiais contém peças rastreáveis" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" -msgstr "Números de Série" +msgstr "Números de série" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Digite os números de série para saídas de produção" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Local de estoque para saídas de produção" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" -msgstr "Alocar Números de Série Automaticamente" +msgstr "Alocar números de série automaticamente" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Alocar automaticamente os itens necessários com os números de série correspondentes" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Os seguintes números de série já existem ou são inválidos" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Uma lista de saídas de produção deve ser fornecida" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Local de estoque para saídas eliminadas" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Descartar alocações" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Descartar quaisquer alocações de estoque para saídas eliminadas" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Motivo para eliminar saída(s) de produção" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Local para saídas de produção concluídas" -#: build/serializers.py:572 -msgid "Accept Incomplete Allocation" -msgstr "Aceitar Alocação Incompleta" +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "Locais estruturais não podem receber itens de estoque" -#: build/serializers.py:573 +#: build/serializers.py:587 order/serializers.py:2561 +msgid "Accept Incomplete Allocation" +msgstr "Aceitar alocação incompleta" + +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Concluir saídas se o estoque não tiver sido totalmente alocado" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" -msgstr "Consumir Estoque Alocado" +msgstr "Consumir estoque alocado" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Consumir qualquer estoque que já tenha sido alocado para esta produção" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" -msgstr "Remover Saídas Incompletas" +msgstr "Remover saídas incompletas" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Excluir quaisquer saídas de produção que não tenham sido completadas" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Não permitido" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" -msgstr "Aceitar conforme consumido por esta ordem de produção" +msgstr "Aceitar conforme consumido por este pedido de produção" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" -msgstr "Desatribua antes de completar esta ordem de produção" +msgstr "Desatribua antes de completar este pedido de produção" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" -msgstr "" +msgstr "Estoque superalocado" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Como deseja manejar itens de estoque extras atribuídos ao pedido de produção" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Alguns itens de estoque foram sobrecarregados" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Aceitar não alocados" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Aceitar que os itens de estoque não foram totalmente alocados para esta encomenda" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Estoque obrigatório não foi totalmente alocado" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" -msgstr "Aceitar Incompleto" +msgstr "Aceitar incompleto" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Aceitar que o número requerido de saídas de produção não foi concluído" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Quantidade de produção requerida não foi concluída" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" -msgstr "A ordem de produção tem ordens de produção secundárias abertas" +msgstr "A pedido de produção tem pedidos de produção secundárias abertas" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" -msgstr "Ordem de produção deve estar no estado de produção" +msgstr "Pedido de produção deve estar no estado de produção" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" -msgstr "Ordem de produção tem saídas incompletas" +msgstr "Pedido de produção tem saídas incompletas" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" -msgstr "Linha de Produção" +msgstr "Linha de produção" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" -msgstr "Saída da Produção" +msgstr "Saída da produção" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Saída de produção deve indicar a mesma produção" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Item da linha de produção" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" -msgstr "bom_item.part deve apontar para a mesma parte que a ordem de produção" +msgstr "Bom_item.part deve apontar para a mesma peça que a pedido de produção" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "O item deve estar em estoque" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Quantidade disponível ({q}) excedida" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Saída de produção deve ser definida para alocação de peças rastreadas" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Saída de produção não pode ser definida para alocação de peças não rastreadas" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Alocação de itens precisam ser fornecidos" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Localização do estoque onde as peças devem ser originadas (deixe em branco a partir de qualquer local)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" -msgstr "Excluir Local" +msgstr "Excluir local" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Excluir itens de estoque desta localização selecionada" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" -msgstr "Estoque Intercambiável" +msgstr "Estoque intercambiável" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Itens de estoque em múltiplos locais podem ser intercambiáveis" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" -msgstr "Estoque Substituto" +msgstr "Estoque substituto" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Permitir alocação de peças substitutas" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Itens opcionais" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" -msgstr "Alocar itens BOM opcionais para ordem de produção" +msgstr "Alocar itens BOM opcionais para pedido de produção" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" -msgstr "" +msgstr "Todos os itens" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" -msgstr "" +msgstr "Itens não rastreados" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" -msgstr "" +msgstr "Itens rastreados" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" -msgstr "" +msgstr "Tipo de item" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "Selecionar o tipo de item para alocar automaticamente" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "Prioridade de estoque" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "Ordem preferencial em que os itens de estoque correspondentes são consumidos" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "Linhas de produção" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "Limitar a alocação a estas linhas de produção (deixe em branco para alocar todas as linhas)" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Referência do BOM" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" -msgstr "ID da parte BOM" +msgstr "ID da peça BOM" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Nome da peça BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" -msgstr "" +msgstr "Instalar em" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Produção" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" -msgstr "Fornecedor da Peça" +msgstr "Fornecedor da peça" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" -msgstr "Quantidade Alocada" +msgstr "Quantidade alocada" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Referência da produção" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" -msgstr "Nome da Categoria" +msgstr "Nome da categoria" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Rastreável" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Herdado" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Permitir variantes" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Item BOM" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" -msgstr "Em Produção" +msgstr "Em produção" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Agendado para produção" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" -msgstr "Estoque Externo" +msgstr "Estoque externo" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" -msgstr "Estoque Disponível" +msgstr "Estoque disponível" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" -msgstr "Estoque Substituto Disponível" +msgstr "Estoque substituto disponível" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" -msgstr "Estoque de Variantes Disponível" +msgstr "Estoque de variantes disponível" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" -msgstr "" +msgstr "A quantidade consumida excede a quantidade alocada" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" -msgstr "" +msgstr "Notas opcionais para o consumo de estoque" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" -msgstr "" +msgstr "O item de produção deve apontar para o pedido de produção correto" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" -msgstr "" +msgstr "Alocação de item de produção duplicada" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" -msgstr "" +msgstr "A linha de produção deve apontar para o pedido de produção correto" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" -msgstr "" +msgstr "Alocação de linha de produção duplicada" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" -msgstr "" +msgstr "Pelo menos um item ou uma linha deve ser fornecido" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Pendentes" @@ -1470,58 +1555,75 @@ msgid "Production" msgstr "Produção" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" -msgstr "Em Espera" +msgstr "Em espera" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Cancelado" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Concluído" -#: build/tasks.py:218 -msgid "Stock required for build order" -msgstr "Estoque obrigatório para a ordem de produção" +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "O pedido de produção {build} foi concluído" -#: build/tasks.py:228 +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Um pedido de produção foi concluído" + +#: build/tasks.py:487 +msgid "Stock required for build order" +msgstr "Estoque obrigatório para a pedido de produção" + +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" -msgstr "Ordem de produção {build} requer estoque adicional" +msgstr "Pedido de produção {build} requer estoque adicional" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" -msgstr "Ordem de produção vencido" +msgstr "Pedido de produção vencido" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" -msgstr "Ordem de produção {bo} está atrasada" +msgstr "Pedido de produção {bo} está atrasada" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "Tem miniatura" + +#: common/api.py:773 msgid "Is Link" msgstr "É um link" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "É um arquivo" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" -msgstr "O usuário não tem permissão para deletar esses anexos" +msgstr "O usuário não tem permissão para excluir esses anexos" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "O usuário não tem permissão para editar este anexo" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" -msgstr "O usuário não tem permissão para deletar esse anexo" +msgstr "O usuário não tem permissão para excluir esse anexo" + +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Lista de seleção bloqueada" #: common/currency.py:135 msgid "Invalid currency code" @@ -1539,21 +1641,26 @@ msgstr "Nenhum código de moeda válido fornecido" msgid "No plugin" msgstr "Sem extensão" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "Marcadores" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Rótulo de código do projeto" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Atualizado" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Tempo da última atualização" #: common/models.py:146 msgid "Update By" -msgstr "Atualizado Por" +msgstr "Atualizado por" #: common/models.py:147 msgid "User who last updated this object" @@ -1567,796 +1674,846 @@ msgstr "Código único do projeto" msgid "Project description" msgstr "Descrição do projeto" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Usuário ou grupo responsável por este projeto" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Chave de configurações" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Valor da Configuração" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Valor escolhido não é uma opção válida" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Valor deve ser um valor booleano" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Valor deve ser um número inteiro" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "O valor deve ser um número válido" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "O valor não passa em verificações de validação" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "A frase senha deve ser diferenciada" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Usuário" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Quantidade de Parcelamentos" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Preço" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Preço unitário na quantidade especificada" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Ponto final" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Ponto final em qual o webhook foi recebido" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Nome para este webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Ativo" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "Este código de projeto está ativo?" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Usuário ou grupo responsável por este projeto" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Chave de configurações" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Valor da configuração" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Valor escolhido não é uma opção válida" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Valor deve ser um valor booleano" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Valor deve ser um número inteiro" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "O valor deve ser um número válido" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "O valor não passa em verificações de validação" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "A frase senha deve ser diferenciada" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Usuário" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Quantidade de parcelamentos" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Preço" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Preço unitário na quantidade especificada" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Ponto final" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Ponto final em qual o webhook foi recebido" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Nome para este webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Este webhook está ativo" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Ficha" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Ficha para acesso" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Secreto" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Segredo compartilhado para HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" -msgstr "ID da Mensagem" +msgstr "ID da mensagem" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Identificador exclusivo desta mensagem" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Servidor" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Servidor do qual esta mensagem foi recebida" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Cabeçalho" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Cabeçalho da mensagem" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Corpo" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Corpo da mensagem" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Ponto do qual esta mensagem foi recebida" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Trabalhado em" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "O trabalho desta mensagem foi concluído?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "URL explícita opcional associada a esta notificação" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Título" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publicado" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Resumo" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Lida" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" -msgstr "Esta notícia do item foi lida?" +msgstr "Este item de notícia foi lido?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Arquivo de imagem" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Tipo modelo de destino para esta imagem" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "ID do modelo de destino para esta imagem" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" -msgstr "Unidade Personalizada" +msgstr "Unidade personalizada" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "O símbolo da unidade deve ser único" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Nome da unidade deve ser um identificador válido" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Nome da unidade" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Símbolo" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Símbolo de unidade opcional" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definição" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definição de unidade" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Anexo" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Arquivo ausente" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Link externo não encontrado" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" -msgstr "" +msgstr "Nenhum arquivo anexado para renomear" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" -msgstr "" +msgstr "O nome do arquivo não pode estar vazio" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" -msgstr "" +msgstr "Nome de arquivo inválido" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" -msgstr "" +msgstr "Não é possível alterar a extensão do arquivo" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" -msgstr "" +msgstr "Já existe um arquivo com este nome" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" -msgstr "" +msgstr "Falha ao salvar o arquivo renomeado" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" -msgstr "Categoria de Modelo" +msgstr "Categoria de modelo" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Tipo modelo de destino para esta imagem" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Selecione arquivo para anexar" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "Miniatura" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "Imagem em miniatura para este anexo" + +#: common/models.py:2155 msgid "Comment" msgstr "Comentário" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Comentário de anexo" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Data de envio" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Data em que o arquivo foi enviado" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "É imagem" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "Verdadeiro se este anexo for um arquivo de imagem válido" + +#: common/models.py:2183 msgid "File size" msgstr "Tamanho do arquivo" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Tamanho do arquivo em bytes" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Categoria de modelo especificado inválido para anexo" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Estado personalizado" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Estados personalizados" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" -msgstr "Status Referência Definido" +msgstr "Status referência definido" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" -msgstr "Conjunto de status estendido com este estado personalizado" +msgstr "Conjunto de status estendido com este status personalizado" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Chave lógica" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Chave lógica de estado que é igual a este estado personalizado na lógica de negócios" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Valor" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Valor numérico que será salvo no banco de dados dos modelos" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Nome do estado" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etiqueta" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Etiqueta que será exibida no frontend" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Cor" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Cor que será exibida no frontend" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Modelo" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Modelo que este estado está associado a" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Modelo deve ser selecionado" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "A chave deve ser selecionada" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Chave lógica deve ser selecionada" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "A chave deve diferir da chave lógica" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Uma classe de estado de referência válida deve ser fornecida" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "A chave deve diferir das chaves lógicas do estado de referência" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "A chave lógica deve estar nas chaves lógicas do estado de referência" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "O nome deve diferir dos nomes do estado de referência" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" -msgstr "Lista de Seleção" +msgstr "Lista de seleção" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" -msgstr "Listas de Seleção" +msgstr "Listas de seleção" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Nome da lista de seleção" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Descrição da lista de seleção" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Bloqueado" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Esta lista de seleção está bloqueada?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Esta lista de seleção pode ser usada?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Extensão de origem" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Extensão que fornece a lista de seleção" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" -msgstr "Série de Origem" +msgstr "Série de origem" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Série opcional identificando a fonte usada para esta lista" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" -msgstr "Entrada Padrão" +msgstr "Entrada padrão" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Entrada padrão para esta lista de seleção" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Criado em" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" -msgstr "Data e hora em que a lista de seleção foi criada" +msgstr "Data/hora em que a lista de seleção foi criada" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" -msgstr "Última Atualização" +msgstr "Última atualização" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" -msgstr "Data e hora da última atualização da lista de seleção" +msgstr "Data/hora da última atualização da lista de seleção" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Entrada na lista de seleção" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" -msgstr "Entradas na Lista de Seleção" +msgstr "Entradas na lista de seleção" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Lista de seleção à qual esta entrada pertence" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Valor da entrada da lista de seleção" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Rótulo para a entrada da lista de seleção" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Descrição da entrada da lista de seleção" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Esta entrada da lista de seleção está ativa?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" -msgstr "" +msgstr "Modelo de parâmetro" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" -msgstr "" +msgstr "Modelos de parâmetro" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "Nenhuma unicidade exigida" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "Único para o tipo de modelo" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "Único globalmente" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" -msgstr "" +msgstr "Parâmetros de caixa de seleção não podem ter unidades" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" -msgstr "" +msgstr "Parâmetros de caixa de seleção não podem ter opções" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" -msgstr "" +msgstr "As opções devem ser únicas" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" -msgstr "" +msgstr "O nome do modelo de parâmetro deve ser único" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" -msgstr "" +msgstr "Tipo de modelo de destino para este modelo de parâmetro" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" -msgstr "Nome do Parâmetro" +msgstr "Nome do parâmetro" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Unidades" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" -msgstr "" +msgstr "Unidades físicas para este parâmetro" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" -msgstr "" +msgstr "Descrição do parâmetro" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Caixa de seleção" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" -msgstr "" +msgstr "Este parâmetro é uma caixa de seleção?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" -msgstr "" +msgstr "Opções" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" -msgstr "" +msgstr "Opções válidas para este parâmetro (separadas por vírgula)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" -msgstr "" +msgstr "Lista de seleção para este parâmetro" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Habilitado" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" -msgstr "" +msgstr "Este modelo de parâmetro está habilitado?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "Unicidade" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "Impor unicidade dos valores de parâmetro vinculados a este template" + +#: common/models.py:2858 msgid "Parameter" -msgstr "" +msgstr "Parâmetro" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" -msgstr "" +msgstr "Parâmetros" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" -msgstr "" +msgstr "Opção inválida para o valor do parâmetro" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "O valor do parâmetro deve ser único" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" -msgstr "" +msgstr "Tipo de modelo inválido especificado para o parâmetro" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" -msgstr "" +msgstr "ID do modelo" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" -msgstr "" +msgstr "ID do modelo de destino para este parâmetro" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Modelo" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" -msgstr "" +msgstr "Modelo de parâmetro" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Dados" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" -msgstr "" +msgstr "Valor do parâmetro" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Anotação" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Campo opcional de notas" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" -msgstr "Escaneamento de Código de Barras" +msgstr "Leitura de código de barras" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Dados de código de barras" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" -msgstr "Usuário que escaneou o código de barras" +msgstr "Usuário que leu o código de barras" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Marcador de hora" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" -msgstr "Data e hora da verificação do código de barras" +msgstr "Data/hora da verificação do código de barras" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "O endpoint da URL que processou o código de barras" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Contexto" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" -msgstr "Dados de contexto para escanear código de barras" +msgstr "Dados de contexto para ler código de barras" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Resposta" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Dados de resposta da verificação de código de barras" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Resultado" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" -msgstr "O código de barras foi digitalizado com sucesso?" +msgstr "O código de barras foi lido com sucesso?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Ocorreu um erro" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." -msgstr "INVE-E8: exclusão de registro de e-mail está protegida. Defina INVENTREE_PROTECT_EMAIL_LOG para Falso para permitir a exclusão." +msgstr "INVE-E8: exclusão de registro de e-mail está protegida. Defina INVENTREE_PROTECT_EMAIL_LOG para falso para permitir a exclusão." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "Mensagem de e-mail" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" -msgstr "Mensagens de Email" +msgstr "Mensagens de e-mail" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Anunciado" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Enviado" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Falhou" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Entregue" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Confirmado" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Entrada" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Saída" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Não responder" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" -msgstr "Rastrear Entrega" +msgstr "Rastrear entrega" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Monitorado" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Clique no caminho" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" -msgstr "ID Global" +msgstr "ID global" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Identificador para esta mensagem (pode ser fornecido por sistema externo)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" -msgstr "ID do Tópico" +msgstr "ID do tópico" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Identificador deste tópico de mensagem (pode ser fornecido por sistema externo)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Tópico" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Tópico vinculado para esta mensagem" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" -msgstr "" +msgstr "Prioridade" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "Tópico do e-mail" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "Tópicos de e-mail" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Chave" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Chave única para este tópico (usada para identificar o tópico)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Identificador exclusivo deste tópico" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Iniciado interno" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Este tópico foi iniciado internamente?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" -msgstr "Data e hora em que o tópico foi criado" +msgstr "Data/hora em que o tópico foi criado" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" -msgstr "Data e hora da última atualização do tópico" +msgstr "Data/hora da última atualização do tópico" #: common/notifications.py:57 #, python-brace-format @@ -2376,9 +2533,9 @@ msgstr "{verbose_name} cancelado" msgid "A order that is assigned to you was canceled" msgstr "Um pedido atribuído a você foi cancelado" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" -msgstr "Itens Recebidos" +msgstr "Itens recebidos" #: common/notifications.py:75 msgid "Items have been received against a purchase order" @@ -2388,107 +2545,103 @@ msgstr "Os itens de um pedido de compra foram recebidos" msgid "Items have been received against a return order" msgstr "Os itens de um pedido de devolução foram recebidos" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" -msgstr "" +msgstr "Indica se a alteração desta configuração requer confirmação" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." -msgstr "" +msgstr "Esta configuração requer confirmação antes de ser alterada. Confirme a alteração." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "É indicado se a configuração é substituída por uma variável de ambiente" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Substituir" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Está em execução" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" -msgstr "Tarefas Pendentes" +msgstr "Tarefas pendentes" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" -msgstr "Tarefas Agendadas" +msgstr "Tarefas agendadas" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" -msgstr "Tarefas com Falhas" +msgstr "Tarefas com falhas" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" -msgstr "ID da Tarefa" +msgstr "ID da tarefa" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" -msgstr "ID Único da Tarefa" +msgstr "ID único da tarefa" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Bloquear" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Congelar tempo" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Nome da tarefa" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Função" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nome da função" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumentos" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argumentos da tarefa" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" -msgstr "Argumentos de Palavra-chave" +msgstr "Argumentos de palavra-chave" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" -msgstr "Argumentos Palavra-chave da Tarefa" +msgstr "Argumentos palavra-chave da tarefa" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nome do arquivo" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" -msgstr "Categoria de Modelo" +msgstr "Categoria de modelo" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Usuário não tem permissão para criar ou editar anexos para este modelo" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" -msgstr "" - -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Lista de seleção bloqueada" +msgstr "O usuário não tem permissão para criar ou editar parâmetros para este modelo" #: common/setting/system.py:97 msgid "No group" -msgstr "Sem Grupo" +msgstr "Sem grupo" #: common/setting/system.py:170 msgid "Site URL is locked by configuration" @@ -2536,7 +2689,7 @@ msgstr "Anuncie a ID da instância do servidor na informação de estado do serv #: common/setting/system.py:221 msgid "Server Instance Name" -msgstr "Nome da Instância do Servidor" +msgstr "Nome da instância do servidor" #: common/setting/system.py:223 msgid "String descriptor for the server instance" @@ -2556,23 +2709,23 @@ msgstr "Restringir a exibição 'sobre'" #: common/setting/system.py:234 msgid "Show the `about` modal only to superusers" -msgstr "Mostrar 'sobre' modal apenas para superusuários" +msgstr "Exibir 'sobre' modal apenas para superusuários" #: common/setting/system.py:239 msgid "Show superuser banner" -msgstr "" +msgstr "Exibir faixa de superusuário" #: common/setting/system.py:240 msgid "Show a warning banner in the UI when logged in as superuser" -msgstr "" +msgstr "Exibir uma faixa de aviso na interface quando conectado como superusuário" #: common/setting/system.py:245 msgid "Show admin banner" -msgstr "" +msgstr "Exibir faixa de administrador" #: common/setting/system.py:246 msgid "Show a warning banner in the UI when logged in as admin" -msgstr "" +msgstr "Exibir uma faixa de aviso na interface quando conectado como administrador" #: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" @@ -2580,11 +2733,11 @@ msgstr "Nome da empresa" #: common/setting/system.py:252 msgid "Internal company name" -msgstr "Nome interno da Empresa" +msgstr "Nome interno da empresa" #: common/setting/system.py:256 msgid "Base URL" -msgstr "URL de Base" +msgstr "URL de base" #: common/setting/system.py:257 msgid "Base URL for server instance" @@ -2592,7 +2745,7 @@ msgstr "URL de base para instância do servidor" #: common/setting/system.py:263 msgid "Default Currency" -msgstr "Moeda Padrão" +msgstr "Moeda padrão" #: common/setting/system.py:264 msgid "Select base currency for pricing calculations" @@ -2600,7 +2753,7 @@ msgstr "Selecione a moeda base para cálculos de preços" #: common/setting/system.py:270 msgid "Supported Currencies" -msgstr "Moedas Suportadas" +msgstr "Moedas suportadas" #: common/setting/system.py:271 msgid "List of supported currency codes" @@ -2608,31 +2761,39 @@ msgstr "Lista de códigos de moeda suportados" #: common/setting/system.py:277 msgid "Currency Update Interval" -msgstr "Intervalo de Atualização da Moeda" +msgstr "Intervalo de atualização da moeda" #: common/setting/system.py:278 msgid "How often to update exchange rates (set to zero to disable)" msgstr "Com que frequência atualizar as taxas de câmbio (defina como zero para desativar)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" -msgstr "dias" +msgstr "Dias" #: common/setting/system.py:284 msgid "Currency Update Plugin" -msgstr "Extensão de Atualização de Moeda" +msgstr "Extensão de atualização de moeda" #: common/setting/system.py:285 msgid "Currency update plugin to use" -msgstr "Extensão de Atualização de Moeda a utilizar" +msgstr "Extensão de atualização de moeda a utilizar" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "Limite de tamanho de envio" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "Tamanho máximo de envio permitido para imagens e arquivos" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Validação rigorosa de URL" @@ -2642,7 +2803,7 @@ msgstr "Exigir especificação de esquema ao validar URLs" #: common/setting/system.py:296 msgid "Update Check Interval" -msgstr "Atualizar Intervalo de Verificação" +msgstr "Atualizar intervalo de verificação" #: common/setting/system.py:297 msgid "How often to check for updates (set to zero to disable)" @@ -2650,7 +2811,7 @@ msgstr "Frequência para verificar atualizações (defina como zero para desativ #: common/setting/system.py:303 msgid "Automatic Backup" -msgstr "Backup Automático" +msgstr "Backup automático" #: common/setting/system.py:304 msgid "Enable automatic backup of database and media files" @@ -2658,7 +2819,7 @@ msgstr "Ativar cópia de segurança automática do banco de dados e arquivos de #: common/setting/system.py:309 msgid "Auto Backup Interval" -msgstr "Intervalo de Backup Automático" +msgstr "Intervalo de backup automático" #: common/setting/system.py:310 msgid "Specify number of days between automated backup events" @@ -2666,7 +2827,7 @@ msgstr "Especificar o número de dia entre as cópias de segurança" #: common/setting/system.py:316 msgid "Task Deletion Interval" -msgstr "Intervalo para Excluir da Tarefa" +msgstr "Intervalo para excluir da tarefa" #: common/setting/system.py:318 msgid "Background task results will be deleted after specified number of days" @@ -2674,7 +2835,7 @@ msgstr "Os resultados da tarefa no plano de fundo serão excluídos após um nú #: common/setting/system.py:325 msgid "Error Log Deletion Interval" -msgstr "Intervalo para Excluir do Registro de Erro" +msgstr "Intervalo para excluir do registro de erro" #: common/setting/system.py:326 msgid "Error logs will be deleted after specified number of days" @@ -2682,7 +2843,7 @@ msgstr "Registros de erros serão excluídos após um número especificado de di #: common/setting/system.py:332 msgid "Notification Deletion Interval" -msgstr "Intervalo para Excluir de Notificação" +msgstr "Intervalo para excluir de notificação" #: common/setting/system.py:334 msgid "User notifications will be deleted after specified number of days" @@ -2690,7 +2851,7 @@ msgstr "Notificações de usuários será excluído após um número especificad #: common/setting/system.py:341 msgid "Email Deletion Interval" -msgstr "Intervalo de Exclusão de e-mail" +msgstr "Intervalo de exclusão de e-mail" #: common/setting/system.py:343 msgid "Email messages will be deleted after specified number of days" @@ -2698,7 +2859,7 @@ msgstr "Mensagens de e-mail serão excluídas após um determinado número de di #: common/setting/system.py:350 msgid "Protect Email Log" -msgstr "Proteger o Log de E-mail" +msgstr "Proteger o log de e-mail" #: common/setting/system.py:351 msgid "Prevent deletion of email log entries" @@ -2714,7 +2875,7 @@ msgstr "Ativar suporte a leitor de código de barras na interface web" #: common/setting/system.py:362 msgid "Store Barcode Results" -msgstr "Armazenar Resultados do Código de Barras" +msgstr "Armazenar resultados do código de barras" #: common/setting/system.py:363 msgid "Store barcode scan results in the database" @@ -2726,7 +2887,7 @@ msgstr "Contagem máxima de códigos de barras" #: common/setting/system.py:369 msgid "Maximum number of barcode scan results to store" -msgstr "Número máximo de resultados de digitalização de códigos de barras para armazenar" +msgstr "Número máximo de resultados de leitura de códigos de barras para armazenar" #: common/setting/system.py:374 msgid "Barcode Input Delay" @@ -2746,7 +2907,7 @@ msgstr "Permitir a verificação de códigos de barras via webcam no navegador" #: common/setting/system.py:387 msgid "Barcode Show Data" -msgstr "Código de barras Exibir Dados" +msgstr "Código de barras exibir dados" #: common/setting/system.py:388 msgid "Display barcode data in browser as text" @@ -2760,957 +2921,1027 @@ msgstr "Extensão de geração de códio de barras" msgid "Plugin to use for internal barcode data generation" msgstr "Extensão para usar para geração de dados de código de barras interno" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "Bloqueio de peças" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "Habilitar o bloqueio de peças para impedir modificações" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Revisões de peças" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" -msgstr "Ativar campo de revisão para a Peça" +msgstr "Ativar campo de revisão para a peça" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" -msgstr "Somente Revisão da Assembleia" +msgstr "Somente revisão da assembleia" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Permitir revisões apenas para peças de montagem" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" -msgstr "Permitir a exclusão da Assembleia" +msgstr "Permitir a exclusão da assembleia" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Permitir a exclusão de peças que são usadas em uma montagem" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Regex IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" -msgstr "Padrão de expressão regular para correspondência de Parte IPN" +msgstr "Padrão de expressão regular para correspondência de peça IPN" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" -msgstr "Permitir Duplicação IPN" +msgstr "Permitir duplicação IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Permitir que várias peças compartilhem o mesmo IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" -msgstr "Permitir Edição IPN" +msgstr "Permitir edição IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Permitir trocar o valor do IPN enquanto se edita a peça" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" -msgstr "Copiar dados da LDM da Peça" +msgstr "Copiar dados da lista de materiais da peça" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" -msgstr "Copiar dados da LDM por padrão quando duplicar a peça" +msgstr "Copiar dados da lista de materiais por padrão quando duplicar a peça" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" -msgstr "Copiar Dados de Parâmetro da Peça" +msgstr "Copiar dados de parâmetro da peça" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Copiar dados de parâmetros por padrão quando duplicar uma peça" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" -msgstr "Copiar Dados Teste da Peça" +msgstr "Copiar dados teste da peça" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Copiar dados de teste por padrão quando duplicar a peça" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" -msgstr "Copiar Parâmetros dos Modelos de Categoria" +msgstr "Copiar parâmetros dos modelos de categoria" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Copiar parâmetros do modelo de categoria quando criar uma peça" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Peças são modelos por padrão" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Peças podem ser montadas a partir de outros componentes por padrão" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Componente" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Peças podem ser usadas como sub-componentes por padrão" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Comprável" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Peças são compráveis por padrão" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Comercializável" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Peças vão vendíveis por padrão" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Peças vão rastreáveis por padrão" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtual" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Peças são virtuais por padrão" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" -msgstr "Mostrar peças relacionadas" +msgstr "Exibir peças relacionadas" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Exibir peças relacionadas com uma peça" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" -msgstr "Dados Iniciais de Estoque" +msgstr "Dados iniciais de estoque" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Permitir a criação do estoque inicial quando adicionar uma nova peça" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" -msgstr "Dados Iniciais de Fornecedor" +msgstr "Dados iniciais de fornecedor" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Permitir a criação de dados iniciais de fornecedor quando adicionar uma nova peça" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" -msgstr "Formato de Exibição do Nome da Peça" +msgstr "Formato de exibição do nome da peça" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formato para exibir o nome da peça" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" -msgstr "Ícone de Categoria de Peça Padrão" +msgstr "Ícone de categoria de peça padrão" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Ícone padrão de categoria de peça (vazio significa sem ícone)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" -msgstr "Mínimo de Casas Decimais do Preço" +msgstr "Mínimo de casas decimais do preço" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Mínimo número de casas decimais a exibir quando renderizar dados de preços" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" -msgstr "Máximo Casas Decimais de Preço" +msgstr "Máximo casas decimais de preço" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Número máximo de casas decimais a exibir quando renderizar dados de preços" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" -msgstr "Usar Preços do Fornecedor" +msgstr "Usar preços do fornecedor" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Incluir quebras de preço do fornecedor nos cálculos de preços globais" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" -msgstr "Substituir Histórico de Compras" +msgstr "Substituir histórico de compras" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Histórico do pedido de compra substitui os intervalos dos preços do fornecedor" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" -msgstr "Usar Preços do Item em Estoque" +msgstr "Usar preços do item em estoque" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Usar preço inserido manualmente no estoque para cálculos de valores" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" -msgstr "Idade do preço do Item em Estoque" +msgstr "Idade do preço do item em estoque" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Não incluir itens em estoque mais velhos que este número de dias no cálculo de preços" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" -msgstr "Usar Preço Variável" +msgstr "Usar preço variável" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Incluir preços variáveis nos cálculos de valores gerais" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" -msgstr "Apenas Ativar Variáveis" +msgstr "Apenas ativar variáveis" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Apenas usar peças variáveis ativas para calcular preço variáveis" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Atualização automática dos preços" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Atualizar automaticamente o preço da peça quando dados internos forem alterados" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" -msgstr "Intervalo de Reconstrução de Preços" +msgstr "Intervalo de reconstrução de preços" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Número de dias antes da atualização automática dos preços das peças" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" -msgstr "Preços Internos" +msgstr "Preços internos" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Habilitar preços internos para peças" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Substituição de preço interno" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Se disponível, os preços internos substituem os cálculos da faixa de preços" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" -msgstr "" +msgstr "Permitir quantidade zero na lista de materiais" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" -msgstr "" +msgstr "Aceitar quantidade zero para o item da lista de materiais da peça. Permite usar a quantidade de preparação para definir a quantidade necessária por produção, independentemente da quantidade de produção" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" -msgstr "Habilitar Impressão de Etiqueta" +msgstr "Habilitar impressão de etiqueta" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Ativar impressão de etiqueta pela interface da internet" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" -msgstr "DPI da Imagem na Etiqueta" +msgstr "DPI da imagem na etiqueta" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Resolução de DPI quando gerar arquivo de imagens para fornecer à extensão de impressão de etiquetas" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" -msgstr "Ativar Relatórios" +msgstr "Ativar relatórios" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Ativar geração de relatórios" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Modo de depuração" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Gerar relatórios em modo de depuração (saída HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "Busca de URLs em relatórios" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "Permitir a busca de URLs remotas ao gerar relatórios" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Registro de erros" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Registrar erros que ocorrem ao gerar relatórios" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Tamanho da página" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Tamanho padrão da página PDF para relatórios" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" -msgstr "Forçar Unidades de Parâmetro" +msgstr "Forçar unidades de parâmetro" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Se as unidades são fornecidas, os valores do parâmetro devem corresponder às unidades especificadas" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" -msgstr "Seriais Únicos Globais" +msgstr "Seriais únicos globais" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Números de série para itens de estoque devem ser globalmente únicos" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" -msgstr "Excluir Estoque Esgotado" +msgstr "Excluir estoque esgotado" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Determina o comportamento padrão, quando um item de estoque é esgotado" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" -msgstr "" +msgstr "Permitir edição de número de série" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" -msgstr "" +msgstr "Permitir a edição do número de série dos itens de estoque" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" -msgstr "" +msgstr "Excluir estoque serializado" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" -msgstr "" +msgstr "Permitir a exclusão de itens de estoque que têm número de série" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" -msgstr "Modelo de Código de Lote" +msgstr "Modelo de código de lote" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Modelo para gerar códigos de lote padrão para itens de estoque" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" -msgstr "Validade do Estoque" +msgstr "Validade do estoque" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Ativar função de validade de estoque" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Vender estoque expirado" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Permitir venda de estoque expirado" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" -msgstr "Tempo de Estoque Inativo" +msgstr "Tempo de estoque inativo" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Número de dias em que os itens em estoque são considerados obsoleto antes de vencer" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" -msgstr "Produzir Estoque Vencido" +msgstr "Produzir estoque vencido" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Permitir produção com estoque vencido" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Controle de propriedade do estoque" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Ativar controle de propriedade sobre locais e itens de estoque" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Ícone padrão do local de estoque" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Ícone padrão de local de estoque (vazio significa sem ícone)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" -msgstr "Mostrar Itens de Estoque Instalados" +msgstr "Exibir itens de estoque instalados" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Exibir itens de estoque instalados nas tabelas de estoque" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" -msgstr "Verificar LDM ao instalar itens" +msgstr "Verificar lista de materiais ao instalar itens" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" -msgstr "Itens do estoque instalado devem existir na LDM para a parte principal" +msgstr "Itens do estoque instalado devem existir na lista de materiais para a peça principal" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" -msgstr "Permitir Fora de Transferência" +msgstr "Permitir fora de transferência" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Permitir que os itens que não estão em estoque sejam transferidos entre locais de estoque" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "Mesclar estoque com estoque existente na transferência por padrão" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "Estado padrão para o comportamento de mesclagem de estoque na transferência. (Pode ser alterado por transferência, se desejado)" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" -msgstr "Modelo de Referência de Pedidos de Produção" +msgstr "Modelo de referência de pedidos de produção" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" -msgstr "Modelo necessário para gerar campo de referência do Pedido de Produção" +msgstr "Modelo necessário para gerar campo de referência do pedido de produção" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Exigir proprietário responsável" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Um proprietário responsável deve ser atribuído a cada pedido" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" -msgstr "Requer Parte Ativa" +msgstr "Requer peça ativa" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" -msgstr "Impedir a criação de ordem para partes inativas" +msgstr "Impedir a criação de ordem para peças inativas" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" -msgstr "Exigir parte bloqueada" +msgstr "Exigir peça bloqueada" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Impedir criação de pedidos para peças desbloqueadas" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Exigir validade, BOM" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" -msgstr "Impedir criação de pedido de compilação a menos que LDM tenha sido validada" +msgstr "Impedir criação de pedido de produção a menos que lista de materiais tenha sido validada" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Exigir pedidos secundários fechados" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Impedir o preenchimento do pedido de construção até que todos os pedidos secundários sejam fechados" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" -msgstr "Pedido de Produção Externo" +msgstr "Pedido de produção externo" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Ativar funcionalidade de pedido de construção externa" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" -msgstr "" +msgstr "Exigir pedidos de produção externos" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" -msgstr "" +msgstr "Exigir um pedido de produção externo ao solicitar peças montadas de um fornecedor externo" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" -msgstr "Bloquear Até Passagem de Testes" +msgstr "Bloquear até passagem de testes" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Impedir que as saídas da produção sejam concluídas até que todos os testes necessários passem" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" -msgstr "Ativar Pedidos de Devolução" +msgstr "Ativar pedidos de devolução" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Ativar funcionalidade de pedido de devolução na interface do usuário" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" -msgstr "Modelo de Referência de Pedidos de Devolução" +msgstr "Modelo de referência de pedidos de devolução" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" -msgstr "Modelo necessário para gerar campo de referência do Pedido de Devolução" +msgstr "Modelo necessário para gerar campo de referência do pedido de devolução" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" -msgstr "Editar os Pedidos de Devolução Concluídos" +msgstr "Editar os pedidos de devolução concluídos" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Permitir a edição de pedidos de devolução após serem enviados ou concluídos" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" -msgstr "Modelo de Referência de Pedidos de Venda" +msgstr "Modelo de referência de pedidos de venda" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" -msgstr "Modelo necessário para gerar campo de referência do Pedido de Venda" +msgstr "Modelo necessário para gerar campo de referência do pedido de venda" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" -msgstr "Envio Padrão de Pedidos de Venda" +msgstr "Envio padrão de pedidos de venda" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" -msgstr "Habilitar criação de envio padrão com Pedidos de Vendas" +msgstr "Habilitar criação de envio padrão com pedidos de vendas" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" -msgstr "Editar os Pedidos de Vendas concluídos" +msgstr "Editar os pedidos de vendas concluídos" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Permitir a edição de pedidos de vendas após serem enviados ou concluídos" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" -msgstr "" +msgstr "Remessa requer verificação" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" -msgstr "" +msgstr "Impedir a conclusão de remessas até que os itens sejam verificados" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Marcar pedidos enviados como concluídos" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Pedidos de vendas marcados como enviados automaticamente serão concluídos, ignorando o status \"enviado\"" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "Habilitar pedidos de transferência" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "Habilitar a funcionalidade de pedido de transferência na interface do usuário" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "Padrão de referência do pedido de transferência" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "Padrão obrigatório para gerar o campo de referência do pedido de transferência" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "Editar pedidos de transferência concluídos" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "Permitir a edição de pedidos de transferência depois de concluídos" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" -msgstr "" +msgstr "Bloquear testes de item incompletos" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" -msgstr "" +msgstr "Impedir a alocação de itens de estoque a pedidos de venda se os testes obrigatórios do item estiverem incompletos" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" -msgstr "Modelo de Referência de Pedidos de Compras" +msgstr "Modelo de referência de pedidos de compras" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" -msgstr "Modelo necessário para gerar campo de referência do Pedido de Compra" +msgstr "Modelo necessário para gerar campo de referência do pedido de compra" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" -msgstr "Editar Pedidos de Compra Concluídos" +msgstr "Editar pedidos de compra concluídos" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Permitir a edição de pedidos de compras após serem enviados ou concluídos" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" -msgstr "Converter Moeda" +msgstr "Converter moeda" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Converter valor de item para moeda base quando receber o estoque" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" -msgstr "Completar automaticamente os pedidos de Compra" +msgstr "Completar automaticamente os pedidos de compra" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Marcar automaticamente os pedidos de compra como concluídos quando todos os itens de linha forem recebidos" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "Mesclar itens de linha do pedido de compra" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "Mesclar novos itens de linha do pedido de compra com linhas existentes que compartilham a mesma peça, destino e data-alvo" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Ativar senha esquecida" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Ativar a função \"Esqueci minha senha\" nas páginas de acesso" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Ativar cadastro" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Ativar auto-registro para usuários na página de entrada" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "Ativar SSO" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Ativar SSO na página de acesso" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Ativar registro SSO" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Ativar auto-registro via SSO para usuários nas páginas de login" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Ativar sincronização de grupo SSO" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Ativar sincronização de grupos do InvenTree com grupos fornecidos pelo IdP" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "Chave de grupo SSO" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "O nome dos grupos reivindicam o atributo fornecido pelo IdP" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "Mapa do grupo SSO" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Um mapeamento de grupos de SSO para grupos locais de InvenTree. Se o grupo local não existir, será criado." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Remover grupos fora do SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" -msgstr "Se os grupos atribuídos ao usuário devem ser removidos somente se eles não são o backend pelo IdP. Pois, essa configuração desabilitada pode causar problemas de segurança" +msgstr "Se os grupos atribuídos ao usuário devem ser removidos somente se eles não são o backend pelo IdP. Pois essa configuração desabilitada pode causar problemas de segurança" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" -msgstr "Email obrigatório" +msgstr "E-mail obrigatório" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Exigir do usuário o e-mail no cadastro" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Auto-preencher usuários SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Preencher automaticamente os detalhes do usuário a partir de dados da conta SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" -msgstr "Enviar email duplo" +msgstr "Enviar e-mail duplo" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Ao se registrar, peça aos usuários duas vezes por seus e-mails" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Senha duas vezes" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "No registro pedir aos usuários duas vezes pela senha" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Domínios permitidos" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Restringir registros a certos domínios (separados por vírgula, começando com @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grupo no cadastro" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Grupo ao qual novos usuários serão atribuídos ao registro. Se a sincronização de grupo SSO estiver ativada, este grupo só estará definido se nenhum grupo puder ser atribuído a partir do IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Forçar AMF" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Os usuários devem usar uma segurança multifatorial." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." -msgstr "" +msgstr "Habilitar esta configuração exigirá que todos os usuários configurem a autenticação multifator. Todas as sessões serão desconectadas imediatamente." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Verificar extensões na inicialização" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Checar que todas as extensões instaladas no início — ativar em ambientes de contêineres" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Verificar por atualizações de extensão" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Ativar verificações periódicas de atualizações para a extensão instalados" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Ativar integração URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Ativar extensão para adicionar rotas URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Ativar integração de navegação" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Ativar extensões para integrar à navegação" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Ativar integração com aplicativo" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Ativar extensões para adicionar aplicativos" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Ativar integração com agendas" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Ativar extensões para executar tarefas agendadas" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Ativar integração de eventos" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Ativar extensões para responder a eventos internos" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Ativar integração de interface" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Ativar extensões para integrar na interface do usuário" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Ativar integração com o e-mail" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Ativar extensão para processar e-mails de saída/entrada" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Ativar códigos de projeto" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Ativar códigos de projeto para rastrear projetos" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" -msgstr "" +msgstr "Habilitar inventário" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Ativar funcionalidade para gravação de níveis e valor de estoque históricos" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" -msgstr "Excluir Locais Externos" +msgstr "Excluir locais externos" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" -msgstr "" +msgstr "Excluir dos cálculos de inventário os itens de estoque em locais externos" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Período de contagem automática" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" -msgstr "" +msgstr "Número de dias entre os registros automáticos de inventário" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" -msgstr "" +msgstr "Excluir registros de inventário antigos" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" -msgstr "" +msgstr "Excluir registros de inventário com mais dias do que o especificado" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" -msgstr "" +msgstr "Intervalo de exclusão de inventário" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" -msgstr "" +msgstr "Os registros de inventário serão excluídos após o número de dias especificado" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" -msgstr "" +msgstr "Excluir registros de rastreamento de estoque antigos" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" -msgstr "" +msgstr "Excluir registros de rastreamento de estoque com mais dias do que o especificado" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" -msgstr "" +msgstr "Intervalo de exclusão de rastreamento de estoque" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "" +msgstr "Os registros de rastreamento de estoque serão excluídos após o número de dias especificado" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Exibir nomes completos dos usuários" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Exibir nomes completos dos usuários em vez de nomes de usuários" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" -msgstr "Exibir Perfis de Usuário" +msgstr "Exibir perfis de usuário" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" -msgstr "Exibir Perfis de Usuários em sua página de perfil" +msgstr "Exibir perfis de usuários em sua página de perfil" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" -msgstr "" +msgstr "Semana começa em" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" -msgstr "" +msgstr "Dia inicial da semana, para exibição nas visualizações de calendário" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" -msgstr "" +msgstr "Domingo" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" -msgstr "" +msgstr "Segunda-feira" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" -msgstr "" +msgstr "Terça-feira" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" -msgstr "" +msgstr "Quarta-feira" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" -msgstr "" +msgstr "Quinta-feira" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" -msgstr "" +msgstr "Sexta-feira" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" -msgstr "" +msgstr "Sábado" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "Horizonte do calendário" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "Número de meses no futuro a exibir nas visualizações de calendário" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "meses" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" -msgstr "Ativar Dados da Estação de Teste" +msgstr "Ativar dados da estação de teste" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Ativar coleção de dados da estação de teste para resultados de teste" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" -msgstr "" +msgstr "Habilitar ping de máquina" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" -msgstr "" +msgstr "Habilitar a tarefa periódica de ping das máquinas registradas para verificar seu status" #: common/setting/user.py:23 msgid "Inline label display" -msgstr "Mostrar etiqueta em linha" +msgstr "Exibir etiqueta em linha" #: common/setting/user.py:25 msgid "Display PDF labels in the browser, instead of downloading as a file" -msgstr "Mostrar etiquetas em PDF no navegador, ao invés de baixar o arquivo" +msgstr "Exibir etiquetas em PDF no navegador, ao invés de baixar o arquivo" #: common/setting/user.py:31 msgid "Default label printer" @@ -3722,35 +3953,35 @@ msgstr "Configurar qual impressora de etiqueta deve ser selecionada por padrão" #: common/setting/user.py:37 msgid "Inline report display" -msgstr "Mostrar relatório em linha" +msgstr "Exibir relatório em linha" #: common/setting/user.py:39 msgid "Display PDF reports in the browser, instead of downloading as a file" -msgstr "Mostrar relatórios em PDF no navegador, ao invés de baixar o arquivo" +msgstr "Exibir relatórios em PDF no navegador, ao invés de baixar o arquivo" #: common/setting/user.py:45 msgid "Barcode Scanner in Form Fields" -msgstr "" +msgstr "Leitor de código de barras em campos de formulário" #: common/setting/user.py:46 msgid "Allow barcode scanner input in form fields" -msgstr "" +msgstr "Permitir entrada de leitor de código de barras em campos de formulário" #: common/setting/user.py:51 msgid "Search Parts" -msgstr "Procurar Peças" +msgstr "Buscar peças" #: common/setting/user.py:52 msgid "Display parts in search preview window" -msgstr "Mostrar peças na janela de visualização de pesquisa" +msgstr "Exibir peças na janela de visualização de pesquisa" #: common/setting/user.py:57 msgid "Search Supplier Parts" -msgstr "Buscar Peças do Fornecedor" +msgstr "Buscar peças do fornecedor" #: common/setting/user.py:58 msgid "Display supplier parts in search preview window" -msgstr "Mostrar fornecedor de peças na janela de visualização de pesquisa" +msgstr "Exibir fornecedor de peças na janela de visualização de pesquisa" #: common/setting/user.py:63 msgid "Search Manufacturer Parts" @@ -3758,7 +3989,7 @@ msgstr "Buscar peças do fabricante" #: common/setting/user.py:64 msgid "Display manufacturer parts in search preview window" -msgstr "Mostrar fabricante de peças na janela de visualização de pesquisa" +msgstr "Exibir fabricante de peças na janela de visualização de pesquisa" #: common/setting/user.py:69 msgid "Hide Inactive Parts" @@ -3770,19 +4001,19 @@ msgstr "Não incluir peças inativas na janela de visualização de pesquisa" #: common/setting/user.py:75 msgid "Search Categories" -msgstr "Pesquisar Categorias" +msgstr "Pesquisar categorias" #: common/setting/user.py:76 msgid "Display part categories in search preview window" -msgstr "Mostrar categoria das peças na janela de visualização de pesquisa" +msgstr "Exibir categoria das peças na janela de visualização de pesquisa" #: common/setting/user.py:81 msgid "Search Stock" -msgstr "Pesquisar Estoque" +msgstr "Pesquisar estoque" #: common/setting/user.py:82 msgid "Display stock items in search preview window" -msgstr "Mostrar itens do estoque na janela de visualização de pesquisa" +msgstr "Exibir itens do estoque na janela de visualização de pesquisa" #: common/setting/user.py:87 msgid "Hide Unavailable Stock Items" @@ -3794,11 +4025,11 @@ msgstr "Não incluir itens de estoque que não estão disponíveis na janela de #: common/setting/user.py:95 msgid "Search Locations" -msgstr "Procurar Locais" +msgstr "Buscar locais" #: common/setting/user.py:96 msgid "Display stock locations in search preview window" -msgstr "Mostrar locais de estoque na janela de visualização de pesquisa" +msgstr "Exibir locais de estoque na janela de visualização de pesquisa" #: common/setting/user.py:101 msgid "Search Companies" @@ -3806,27 +4037,27 @@ msgstr "Pesquisar empresas" #: common/setting/user.py:102 msgid "Display companies in search preview window" -msgstr "Mostrar empresas na janela de visualização de pesquisa" +msgstr "Exibir empresas na janela de visualização de pesquisa" #: common/setting/user.py:107 msgid "Search Build Orders" -msgstr "Pesquisar Pedidos de Produção" +msgstr "Pesquisar pedidos de produção" #: common/setting/user.py:108 msgid "Display build orders in search preview window" -msgstr "Mostrar pedidos de produção na janela de visualização de pesquisa" +msgstr "Exibir pedidos de produção na janela de visualização de pesquisa" #: common/setting/user.py:113 msgid "Search Purchase Orders" -msgstr "Pesquisar Pedido de Compras" +msgstr "Pesquisar pedido de compras" #: common/setting/user.py:114 msgid "Display purchase orders in search preview window" -msgstr "Mostrar pedidos de compra na janela de visualização de pesquisa" +msgstr "Exibir pedidos de compra na janela de visualização de pesquisa" #: common/setting/user.py:119 msgid "Exclude Inactive Purchase Orders" -msgstr "Não incluir Pedidos de Compras Inativos" +msgstr "Não incluir pedidos de compras inativos" #: common/setting/user.py:120 msgid "Exclude inactive purchase orders from search preview window" @@ -3834,7 +4065,7 @@ msgstr "Não incluir pedidos de compras inativos na janela de visualização de #: common/setting/user.py:125 msgid "Search Sales Orders" -msgstr "Pesquisar Pedidos de Vendas" +msgstr "Pesquisar pedidos de vendas" #: common/setting/user.py:126 msgid "Display sales orders in search preview window" @@ -3842,7 +4073,7 @@ msgstr "Exibir pedidos de vendas na janela de visualização de pesquisa" #: common/setting/user.py:131 msgid "Exclude Inactive Sales Orders" -msgstr "Não Incluir Pedidos de Compras Inativas" +msgstr "Não incluir pedidos de compras inativas" #: common/setting/user.py:132 msgid "Exclude inactive sales orders from search preview window" @@ -3850,7 +4081,7 @@ msgstr "Não incluir pedidos de vendas inativos na janela de visualização de p #: common/setting/user.py:137 msgid "Search Sales Order Shipments" -msgstr "Pesquisar envios do Pedido de Venda" +msgstr "Pesquisar envios do pedido de venda" #: common/setting/user.py:138 msgid "Display sales order shipments in search preview window" @@ -3858,7 +4089,7 @@ msgstr "Exibir envios do pedido de venda na janela de pré-visualização" #: common/setting/user.py:143 msgid "Search Return Orders" -msgstr "Procurar Pedidos de Devolução" +msgstr "Buscar pedidos de devolução" #: common/setting/user.py:144 msgid "Display return orders in search preview window" @@ -3866,7 +4097,7 @@ msgstr "Exibir pedidos de devolução na janela de pré-visualização de pesqui #: common/setting/user.py:149 msgid "Exclude Inactive Return Orders" -msgstr "Não Incluir Pedidos de Devolução Inativas" +msgstr "Não incluir pedidos de devolução inativas" #: common/setting/user.py:150 msgid "Exclude inactive return orders from search preview window" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Número de resultados mostrados em cada seção da janela de visualização de pesquisa" #: common/setting/user.py:163 -msgid "Regex Search" -msgstr "Pesquisa de Regex" +msgid "Search Results Preview Panel" +msgstr "Painel de pré-visualização de resultados de busca" -#: common/setting/user.py:164 +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "Abrir resultados de busca no painel de pré-visualização, em vez de navegar diretamente para o resultado" + +#: common/setting/user.py:171 +msgid "Regex Search" +msgstr "Pesquisa de regex" + +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Ativar expressões regulares nas consultas de pesquisa" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" -msgstr "Pesquisar Palavras Inteiras" +msgstr "Pesquisar palavras inteiras" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Consultas de pesquisa retornam resultados para partidas de palavra inteira" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" -msgstr "Pesquisar Notas" +msgstr "Pesquisar notas" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Resultados das consultas de pesquisa para correspondências das notas do item" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" -msgstr "Tecla Esc Fecha Formulários" +msgstr "Tecla esc fecha formulários" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" -msgstr "Usar a tecla Esc para fechar fomulários modais" +msgstr "Usar a tecla esc para fechar fomulários modais" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Barra de navegação fixa" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "A posição da barra de navegação está fixa no topo da tela" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" -msgstr "Cabeçalhos da Tabela Fixa" +msgstr "Cabeçalhos da tabela fixa" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Cabeçalhos de tabela são fixos no topo da tabela" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" -msgstr "" +msgstr "Exibir Spotlight" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" -msgstr "Ativar a navegação do Spotlight" +msgstr "Ativar a navegação do spotlight" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" -msgstr "Ícones de Navegação" +msgstr "Ícones de navegação" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Exibir ícones na barra de navegação" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Formato da data" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Formato preferido para exibir datas" -#: common/setting/user.py:227 -msgid "Show Stock History" -msgstr "Mostrar histórico de ações" +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "Painel de pré-visualização de tabela" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "Mostrar informações do histórico de estoque na página de detalhes do capítulo" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "Mostrar última navegação" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "Mostrar a página atual em breadcrumbs" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" -msgstr "Mostrar localização completa do estoque nas tabelas" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "Exibir um painel de pré-visualização ao selecionar itens em tabelas" #: common/setting/user.py:241 +msgid "Show Stock History" +msgstr "Exibir histórico de ações" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" +msgstr "Exibir informações do histórico de estoque na página de detalhes do capítulo" + +#: common/setting/user.py:247 +msgid "Show Last Breadcrumb" +msgstr "Exibir última navegação" + +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" +msgstr "Exibir a página atual em breadcrumbs" + +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "Exibir informações extras do modelo" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "Exibir informações extras nas listas suspensas de seleção de modelo" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" +msgstr "Exibir localização completa do estoque nas tabelas" + +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Desativado: O caminho completo da localização é exibido como uma dica do mouse. Ativado: O caminho completo da localização é exibido como texto sem formatação." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" -msgstr "Mostrar categorias completas do capítulo nas tabelas" +msgstr "Exibir categorias completas do capítulo nas tabelas" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Desativado: O caminho completo da categoria é exibido como uma dica do mouse. Habilitado: O caminho completo da categoria é exibido como texto sem formatação." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" -msgstr "" +msgstr "Exibir subconjuntos na tabela da lista de materiais" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" -msgstr "" +msgstr "Habilitar a exibição de subconjuntos na tabela da lista de materiais" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Receber relatório de erros" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Receber notificações para erros do sistema" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Últimas máquinas de impressão utilizadas" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Salvar as últimas máquinas de impressão usadas para um usuário" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" -msgstr "" +msgstr "Exibir itens no nível final" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" -msgstr "" +msgstr "Exibir automaticamente itens/peças em vez de subníveis para locais ou categorias sem filhos" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Todos os modelos" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Nenhum modelo de anexo fornecido" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Categoria de modelo de anexo inválido" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "O tamanho do arquivo excede o limite máximo de envio de {max_size} MB" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "Nome de arquivo inválido" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Os lugares mínimos não podem ser maiores que os máximos" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Os lugares maiores não podem ser menores que os máximos" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Um domínio vazio não é permitido." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Nome de domínio inválido: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Valor deve ser maiúsculo" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "O valor deve ser um identificador de variável válido" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "A peça está ativa" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Fabricante está ativo" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" -msgstr "A peça do Fornecedor está ativa" +msgstr "A peça do fornecedor está ativa" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" -msgstr "" +msgstr "Peça de fornecedor principal" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "A peça interna está ativa" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" -msgstr "O fornecedor está Ativo" +msgstr "O fornecedor está ativo" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Fabricante" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Empresa" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Tem estoque" @@ -4105,11 +4369,11 @@ msgstr "Descrição da empresa" #: company/models.py:160 msgid "Website" -msgstr "Página Web" +msgstr "Página web" #: company/models.py:161 msgid "Company website URL" -msgstr "URL do Site da empresa" +msgstr "URL do site da empresa" #: company/models.py:167 msgid "Phone number" @@ -4123,8 +4387,8 @@ msgstr "Número de telefone do contato" msgid "Contact email address" msgstr "Endereço de e-mail do contato" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Contato" @@ -4176,283 +4440,283 @@ msgstr "CNPJ" msgid "Company Tax ID" msgstr "CNPJ da empresa" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Endereço" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Endereços" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" -msgstr "Selecione a Empresa" +msgstr "Selecione a empresa" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Título do endereço" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Título descrevendo a entrada do endereço" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" -msgstr "Endereço Principal" +msgstr "Endereço principal" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Definir como endereço principal" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Linha 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Linha de endereço 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Linha 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Linha de endereço 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "CEP" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Cidade/Região" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Cidade CEP / região" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Estado/Provincia" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" -msgstr "Estado ou Província" +msgstr "Estado ou província" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "País" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "País do endereço" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Notas de envio por correio" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Notas para o envio da transportadora" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Notas de envio interno" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Notas de envio para uso interno" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Link para as informações do endereço (externo)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Fabricante da peça" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Peça base" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Selecionar peça" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Selecionar fabricante" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "NPF" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" -msgstr "Número de Peça do Fabricante" +msgstr "Número de peça do fabricante" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Descrição da peça do fabricante" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Unidades de pacote devem ser compatíveis com as unidades de peça base" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Unidades de pacote devem ser maior que zero" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" -msgstr "Parte do fabricante vinculado deve fazer referência à mesma peça base" +msgstr "Peça do fabricante vinculado deve fazer referência à mesma peça base" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Fornecedor" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Selecione o fornecedor" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Unidade de reserva de estoque fornecedor" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" -msgstr "Esta parte de fornecedor está ativa?" - -#: company/models.py:792 -msgid "Primary" -msgstr "" +msgstr "Esta peça de fornecedor está ativa?" #: company/models.py:793 -msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgid "Primary" +msgstr "Principal" -#: company/models.py:803 +#: company/models.py:794 +msgid "Is this the primary supplier part for the linked Part?" +msgstr "Esta é a peça de fornecedor principal para a peça vinculada?" + +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Selecionar peça do fabricante" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL do link externo da peça do fabricante" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Descrição da peça fornecedor" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" -msgstr "preço base" +msgstr "Preço base" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Taxa mínima (ex.: taxa de estoque)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Embalagem" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Embalagem de peças" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Quantidade de embalagens" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Quantidade total fornecida em um único pacote. Deixe em branco para itens individuais." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" -msgstr "múltiplo" +msgstr "Múltiplo" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Pedido múltiplo" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Quantidade disponível do fornecedor" -#: company/models.py:889 -msgid "Availability Updated" -msgstr "Disponibilidade Atualizada" - #: company/models.py:890 +msgid "Availability Updated" +msgstr "Disponibilidade atualizada" + +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Data da última atualização de dados disponíveis" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" -msgstr "Parcelamento de Preço do Fornecedor" +msgstr "Parcelamento de preço do fornecedor" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Moeda padrão utilizada para este fornecedor" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" -msgstr "Nome da Empresa" +msgstr "Nome da empresa" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" -msgstr "Em Estoque" - -#: company/serializers.py:408 -msgid "Price Breaks" -msgstr "" +msgstr "Em estoque" #: company/serializers.py:461 -msgid "Pretty Name" -msgstr "" +msgid "Price Breaks" +msgstr "Faixas de preço" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: company/serializers.py:514 +msgid "Pretty Name" +msgstr "Nome amigável" + +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Ocorreu um erro ao exportar os dados" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "A extensão de exportação de dados retornou dados incorretos" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" -msgstr "Formato de Exportação" +msgstr "Formato de exportação" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Selecionar formato do arquivo de exportação" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Exportar extensão" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Selecionar extensão de exportação" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Informação adicional de status para este item" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Tecla de status personalizada" @@ -4476,123 +4740,152 @@ msgstr "Localizado" msgid "Invalid status code" msgstr "Código de status inválido" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Arquivo de dados" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Arquivo de dados para importar" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Colunas" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Categoria de modelo de destino para esta sessão de importação" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Status de importação" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Campos padrões" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Substituições de campo" -#: importer/models.py:121 -msgid "Field Filters" -msgstr "Campo de Filtros" - #: importer/models.py:127 +msgid "Field Filters" +msgstr "Campo de filtros" + +#: importer/models.py:134 msgid "Update Existing Records" -msgstr "" +msgstr "Atualizar registros existentes" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" -msgstr "" +msgstr "Se habilitado, os registros existentes serão atualizados com os novos dados" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Alguns campos necessários não foram mapeados" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "Histórico de contagem de linhas concluídas" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "Histórico de contagem de linhas" + +#: importer/models.py:453 msgid "ID" -msgstr "" +msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" -msgstr "" +msgstr "Identificador existente do registro no banco de dados" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "A coluna já está mapeada a um campo de banco de dados" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "O campo já está mapeado para uma coluna de dados" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Mapeamento de coluna deve ser ligado a uma sessão de importação válida" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "A coluna não existe no arquivo de dados" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "O campo não existe no modelo de destino" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "O campo selecionado é somente leitura" -#: importer/models.py:494 importer/models.py:571 -msgid "Import Session" -msgstr "Importar Sessão" +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "O campo de busca só pode ser definido para campos relacionados (chave estrangeira)" -#: importer/models.py:498 +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "Campo de busca inválido. As opções válidas são: {options}" + +#: importer/models.py:583 importer/models.py:670 +msgid "Import Session" +msgstr "Importar sessão" + +#: importer/models.py:587 msgid "Field" msgstr "Campo" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Coluna" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "Campo de busca" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "Campo do banco de dados a ser usado para busca por chave estrangeira. Deixe em branco para busca automática." + +#: importer/models.py:674 msgid "Row Index" msgstr "Índice de fileira" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Dados da linha original" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Erros" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Válido" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "" +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "Múltiplas correspondências encontradas para o valor — garanta que o valor seja único, ou selecione um campo de busca específico" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" -msgstr "" +msgstr "Nenhum registro encontrado com o ID fornecido" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" -msgstr "" +msgstr "Formato de ID fornecido inválido" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "O ID é obrigatório para atualizar registros existentes." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Formato de arquivo de dados não suportado" @@ -4600,43 +4893,47 @@ msgstr "Formato de arquivo de dados não suportado" msgid "Failed to open data file" msgstr "Falha ao abrir o arquivo de dados" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "Não foi possível decodificar o arquivo de dados como texto" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Dimensões de arquivo de dados inválidas" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Padrão de campo inválido" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Substituição de campo inválida" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Filtros de campo inválidos" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Linhas" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Lista de ID das linhas para aceitar" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Nenhuma linha fornecida" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "A linha não pertence a esta sessão" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "A linha contém dados inválidos" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "A linha já foi concluída" @@ -4646,7 +4943,7 @@ msgstr "Inicialização" #: importer/status_codes.py:18 msgid "Mapping Columns" -msgstr "Mapeando Colunas" +msgstr "Mapeando colunas" #: importer/status_codes.py:21 msgid "Importing Data" @@ -4672,1043 +4969,1153 @@ msgstr "Arquivo de dados contém colunas em excesso" msgid "Data file contains too many rows" msgstr "Arquivo de dados contém linhas em excesso" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Valor deve ser um objeto de dicionário válido" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Cópias" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Número de cópias para cada rótulo" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Conectado" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Desconhecido" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Imprimindo" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" -msgstr "" +msgstr "Aviso" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Sem mídia" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Papel enroscado" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Desconectado" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" -msgstr "" +msgstr "Erro" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Impressora de etiqueta" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Imprima etiquetas diretamente para vários itens." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Local da impressora" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Escopo da impressora para um local específico" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Nome da máquina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Categoria de máquina" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Categoria de máquina" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Controlador" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Controlador utilizado para a máquina" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Máquinas podem ser desativadas" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Controlador disponível" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Nenhum erro" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Iniciado" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Estado da máquina" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Máquina" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" -msgstr "Configuração da Máquina" +msgstr "Configuração da máquina" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Categoria de configuração" #: machine/serializers.py:24 msgid "Key of the property" -msgstr "" +msgstr "Chave da propriedade" #: machine/serializers.py:27 msgid "Value of the property" -msgstr "" +msgstr "Valor da propriedade" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupo" #: machine/serializers.py:30 msgid "Grouping of the property" -msgstr "" +msgstr "Agrupamento da propriedade" #: machine/serializers.py:33 msgid "Type" -msgstr "" +msgstr "Tipo" #: machine/serializers.py:35 msgid "Type of the property" -msgstr "" +msgstr "Tipo da propriedade" #: machine/serializers.py:40 msgid "Max Progress" -msgstr "" +msgstr "Progresso máximo" #: machine/serializers.py:41 msgid "Maximum value for progress type, required if type=progress" -msgstr "" +msgstr "Valor máximo para o tipo progresso, obrigatório se type=progress" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" -msgstr "Referência do Pedido" +msgstr "Referência do pedido" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Pendente" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Tem código do projeto" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Criado por" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" -msgstr "Criado Antes" +msgstr "Criado antes" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" -msgstr "Criado Após" +msgstr "Criado após" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" -msgstr "Tem Data Inicial" +msgstr "Tem data inicial" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" -msgstr "Data Inicial Antes" +msgstr "Data inicial antes" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" -msgstr "Data Inicial Após" +msgstr "Data inicial após" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" -msgstr "Tem Data Prevista" +msgstr "Tem data prevista" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" -msgstr "Data Prevista Antes" +msgstr "Data prevista antes" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" -msgstr "Data Prevista Antes" +msgstr "Data prevista antes" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" -msgstr "" +msgstr "Atualizado antes de" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" -msgstr "" +msgstr "Atualizado após" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" -msgstr "Tem Preço" +msgstr "Tem preço" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" -msgstr "Concluído Antes" +msgstr "Concluído antes" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" -msgstr "Concluído Após" +msgstr "Concluído após" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" -msgstr "Pedido de Produção Vencido" +msgstr "Pedido de produção vencido" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Pedido" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" -msgstr "Pedido Completo" +msgstr "Pedido completo" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" -msgstr "Peça Interna" +msgstr "Peça interna" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Pedido pendente" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Concluído" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" -msgstr "Possui Envio" +msgstr "Possui envio" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" -msgstr "" +msgstr "Remessa não encontrada" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" -msgstr "Pedido de Compra" +msgstr "Pedido de compra" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 #: templates/email/overdue_sales_order.html:15 msgid "Sales Order" -msgstr "Pedido de Venda" +msgstr "Pedido de venda" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" -msgstr "Pedido de Devolução" +msgstr "Pedido de devolução" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "Pedido de transferência" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" -msgstr "Preço Total" +msgstr "Preço total" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Preço total deste pedido" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" -msgstr "Moeda do Pedido" +msgstr "Moeda do pedido" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Moeda para este pedido (deixe em branco para usar o padrão da empresa)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Este pedido está bloqueado e não pode ser modificado" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "O contato não corresponde à empresa selecionada" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "Data inicial deve ser anterior à data limite" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" -msgstr "" +msgstr "O endereço não corresponde à empresa selecionada" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Descrição do pedido (opcional)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Selecione o código do projeto para este pedido" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Link para página externa" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Data inicial" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Data de início programada para esta encomenda" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" -msgstr "Data Prevista" +msgstr "Data prevista" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." -msgstr "Data esperada para entrega do pedido. O Pedido estará atrasado após esta data." +msgstr "Data esperada para entrega do pedido. O pedido estará atrasado após esta data." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Data de emissão" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Dia que o pedido foi feito" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" -msgstr "" +msgstr "Atualizado em" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Usuário ou grupo responsável para este pedido" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Ponto de contato para este pedido" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Endereço da empresa para este pedido" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Referência do pedido" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" -msgstr "Situação" +msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Estado do pedido" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Empresa da qual os itens estão sendo encomendados" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" -msgstr "Referencia do fornecedor" +msgstr "Referência do fornecedor" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Código de referência do pedido fornecedor" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" -msgstr "recebido por" +msgstr "Recebido por" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Dia que o pedido foi concluído" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Destino" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Destino para os itens recebidos" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Fornecedor de peça deve corresponder a fornecedor da OC" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" -msgstr "" +msgstr "O item de linha não corresponde ao pedido de compra" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" -msgstr "" +msgstr "O item de linha está sem uma peça vinculada" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Quantidade deve ser um número positivo" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" -msgstr "" +msgstr "Números de série não podem ser atribuídos a peças virtuais" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "Permitir qualquer estoque (serializado ou não)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "Apenas estoque serializado" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "Apenas estoque não serializado" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Cliente" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Empresa para qual os itens foi vendidos" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" -msgstr "Situação do Pedido de Venda" +msgstr "Situação do pedido de venda" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " -msgstr "Referência do Cliente " +msgstr "Referência do cliente " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" -msgstr "Código de Referência do pedido do cliente" +msgstr "Código de referência do pedido do cliente" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Data de envio" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" -msgstr "enviado por" +msgstr "Enviado por" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "O item de linha não está associado a este pedido" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Nenhuma correspondência encontrada para os seguintes números de série" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Os seguintes números de série não estão disponíveis" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "O pedido já está completo" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "O pedido já está cancelado" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Apenas um pedido aberto pode ser marcado como completo" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Pedido não pode ser concluído, pois, há envios incompletos" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "O pedido não pode ser concluído, pois, há alocações incompletas" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "O pedido não pode ser concluído, pois, há itens de linha incompletos" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "O pedido está bloqueado e não pode ser modificado" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Quantidade do item" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "Desconto" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "Percentual de desconto aplicado a este item de linha (0-100)" + +#: order/models.py:2138 msgid "Line Number" -msgstr "" +msgstr "Número da linha" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" -msgstr "" +msgstr "Número da linha para este item (opcional)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" -msgstr "Referência do Item em Linha" +msgstr "Referência do item em linha" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" -msgstr "Observações do Item de Linha" +msgstr "Observações do item de linha" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Data limite para este item de linha (deixe em branco para usar a data limite do pedido)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Descrição do item de linha (opcional)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Contexto adicional para esta linha" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" -msgstr "Preço Unitário" +msgstr "Preço unitário" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Item de linha de pedido de compra" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "A peça do fornecedor deve corresponder ao fornecedor" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "Pedido de produção deve ser marcada como externa" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" -msgstr "Os pedidos de produção só podem ser vinculados a partes de montagem" +msgstr "Os pedidos de produção só podem ser vinculados a peças de montagem" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" -msgstr "Criar parte do pedido deve combinar a parte do item de linha" +msgstr "Criar peça do pedido deve combinar a peça do item de linha" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" -msgstr "" +msgstr "Um pedido de produção externo é necessário para peças de montagem" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" -msgstr "Fornecedor da Peça" +msgstr "Fornecedor da peça" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Recebido" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Número de itens recebidos" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" -msgstr "Preço de Compra" +msgstr "Preço de compra" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Preço unitário de compra" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Pedido de produção externa para ser preenchida por este item de linha" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" -msgstr "Linha Extra do Pedido de Compra" +msgstr "Linha extra do pedido de compra" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" -msgstr "Item de Linha de Pedido de Vendas" +msgstr "Item de linha de pedido de vendas" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Apenas peças vendáveis podem ser atribuídas a um pedido de venda" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" -msgstr "Preço de Venda" +msgstr "Preço de venda" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Preço de venda unitário" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Enviado" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Quantidade enviada" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" -msgstr "Envio do Pedido de Venda" +msgstr "Envio do pedido de venda" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" -msgstr "" +msgstr "O endereço da remessa deve corresponder ao cliente" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" -msgstr "" +msgstr "Endereço de entrega desta remessa" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Data do envio" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" -msgstr "Data de Entrega" +msgstr "Data de entrega" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Data da entrega do envio" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Verificado por" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Usuário que verificou este envio" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Envio" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" -msgstr "Número do Envio" +msgstr "Número do envio" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Número de rastreio" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Informação de rastreamento" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" -msgstr "" +msgstr "Número da nota fiscal" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" -msgstr "" +msgstr "Número de referência da nota fiscal associada" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" -msgstr "" +msgstr "A remessa já foi enviada" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" -msgstr "" +msgstr "A remessa não tem itens de estoque alocados" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" -msgstr "" +msgstr "A remessa deve ser verificada antes de ser concluída" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" -msgstr "" +msgstr "Linha extra do pedido de venda" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" -msgstr "" +msgstr "Alocação do pedido de venda" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" -msgstr "" +msgstr "O item de estoque não foi atribuído" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" -msgstr "" +msgstr "Não é possível alocar um item de estoque a uma linha com uma peça diferente" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" -msgstr "" +msgstr "Não é possível alocar estoque a uma linha sem peça" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" -msgstr "" +msgstr "A quantidade alocada não pode exceder a quantidade em estoque" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Quantidade alocada deve ser maior que zero" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" -msgstr "" +msgstr "A quantidade deve ser 1 para um item de estoque serializado" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" -msgstr "" +msgstr "O pedido de venda não corresponde à remessa" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" -msgstr "" +msgstr "A remessa não corresponde ao pedido de venda" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Linha" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" -msgstr "" +msgstr "Referência da remessa do pedido de venda" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Item" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" -msgstr "" +msgstr "Selecionar item de estoque a alocar" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" -msgstr "" +msgstr "Inserir a quantidade de alocação de estoque" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" -msgstr "" +msgstr "Referência do pedido de devolução" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" -msgstr "" +msgstr "Empresa da qual os itens estão sendo devolvidos" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" -msgstr "" +msgstr "Status do pedido de devolução" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" -msgstr "" +msgstr "Item de linha do pedido de devolução" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" -msgstr "" +msgstr "O item de estoque deve ser especificado" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" -msgstr "" +msgstr "A quantidade de devolução excede a quantidade em estoque" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" -msgstr "" +msgstr "A quantidade de devolução deve ser maior que zero" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" -msgstr "" +msgstr "Quantidade inválida para item de estoque serializado" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" -msgstr "" +msgstr "Selecionar item a devolver do cliente" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" -msgstr "" +msgstr "Data de recebimento" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" -msgstr "" +msgstr "A data em que este item de devolução foi recebido" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" -msgstr "" +msgstr "Resultado" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" -msgstr "" +msgstr "Resultado para este item de linha" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" -msgstr "" +msgstr "Custo associado à devolução ou reparo deste item de linha" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" -msgstr "" +msgstr "Linha extra do pedido de devolução" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "Referência do pedido de transferência" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "Status do pedido de transferência" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Copiar linhas" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "Origem dos itens transferidos" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "Destino dos itens transferidos" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "Consumir estoque" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "Em vez de transferir o estoque para o destino, \"consuma\" o estoque removendo a quantidade transferida do item de estoque alocado" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "O pedido não pode ser concluído até que um local de destino seja definido" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" -msgstr "" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "O pedido não pode ser concluído até estar totalmente alocado" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "Item de linha do pedido de transferência" + +#: order/models.py:4027 +msgid "transferred" +msgstr "transferido" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "quantidade transferida" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "Alocação do pedido de transferência" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "Falha ao consumir item de estoque no pedido de transferência" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "Falha ao transferir item de estoque no pedido de transferência" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" -msgstr "" +msgstr "Itens de linha" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" -msgstr "" +msgstr "Linhas concluídas" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Duplicar Pedido" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "Chave de status personalizada" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "Definir um valor de status personalizado dentro deste status lógico" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "ID do pedido inválido" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "A chave de estatuto" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "Chave de status personalizada inválida" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "Chave de status personalizada inválida para este status de pedido" + +#: order/serializers.py:462 msgid "Supplier Name" -msgstr "" +msgstr "Nome do fornecedor" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "O pedido não pode ser cancelado" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" -msgstr "" +msgstr "Permitir que o pedido seja fechado com itens de linha incompletos" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" -msgstr "" +msgstr "O pedido tem itens de linha incompletos" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" -msgstr "" +msgstr "O pedido não está aberto" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" -msgstr "" +msgstr "Precificação automática" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" -msgstr "" +msgstr "Calcular automaticamente o preço de compra com base nos dados da peça de fornecedor" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" -msgstr "" +msgstr "Moeda do preço de compra" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" -msgstr "Mesclar Itens" +msgstr "Mesclar itens" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" -msgstr "" +msgstr "Mesclar itens com a mesma peça, destino e data prevista em um único item de linha" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Código (SKU)" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" -msgstr "Número Interno da Peça" +msgstr "Número interno da peça" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" -msgstr "Nome Interno da Peça" +msgstr "Nome interno da peça" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" -msgstr "" +msgstr "A peça de fornecedor deve ser especificada" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" -msgstr "" +msgstr "O pedido de compra deve ser especificado" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" -msgstr "" +msgstr "O fornecedor deve corresponder ao pedido de compra" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" -msgstr "" +msgstr "O pedido de compra deve corresponder ao fornecedor" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" -msgstr "" +msgstr "Item de linha" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" -msgstr "" +msgstr "Selecionar local de destino para os itens recebidos" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" -msgstr "" +msgstr "Inserir código de lote para os itens de estoque recebidos" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" -msgstr "" +msgstr "Data de validade" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" -msgstr "" +msgstr "Inserir data de validade para os itens de estoque recebidos" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" -msgstr "" +msgstr "Inserir números de série para os itens de estoque recebidos" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" -msgstr "" +msgstr "Substituir as informações de embalagem dos itens de estoque recebidos" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" -msgstr "" +msgstr "Nota adicional para os itens de estoque recebidos" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Código de barras" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Código de barras lido" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Código de barras já está em uso" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" -msgstr "" +msgstr "Os itens de linha devem ser fornecidos" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" -msgstr "" +msgstr "O local de destino deve ser especificado" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" -msgstr "" +msgstr "Os valores de código de barras fornecidos devem ser únicos" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "Os números de série fornecidos devem ser únicos" + +#: order/serializers.py:1217 msgid "Shipments" -msgstr "" +msgstr "Remessas" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" -msgstr "" +msgstr "Remessas concluídas" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" -msgstr "" +msgstr "Linhas alocadas" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" -msgstr "" +msgstr "Moeda do preço de venda" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" -msgstr "Itens Alocados" +msgstr "Itens alocados" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" -msgstr "" +msgstr "Nenhum detalhe de remessa fornecido" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" -msgstr "" +msgstr "A quantidade deve ser positiva" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" -msgstr "" +msgstr "O item de estoque não passou em todos os testes obrigatórios" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" -msgstr "" +msgstr "Inserir números de série a alocar" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" -msgstr "" +msgstr "A remessa já foi enviada" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" -msgstr "" +msgstr "A remessa não está associada a este pedido" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "Local de estoque de onde os itens são obtidos (deixe em branco para usar qualquer local)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Os seguintes números de série não estão disponíveis" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "Excluir itens de estoque deste local" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "Atribuir alocações a esta remessa" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "Permitir que o estoque seja retirado de vários locais para atender a um único item de linha" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "Estoque serializado" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "Controlar se os itens de estoque serializados são incluídos na alocação automática" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "Limitar a alocação a estes itens de linha (deixe em branco para alocar todas as linhas)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "O item de linha não pertence a este pedido" + +#: order/serializers.py:2261 msgid "Return order line item" -msgstr "" +msgstr "Item de linha do pedido de devolução" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" -msgstr "" +msgstr "O item de linha não corresponde ao pedido de devolução" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" -msgstr "" +msgstr "O item de linha já foi recebido" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" -msgstr "" +msgstr "Os itens só podem ser recebidos em pedidos que estão em andamento" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" -msgstr "" +msgstr "Quantidade a devolver" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" -msgstr "" +msgstr "Moeda do preço da linha" + +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "Permitir que o pedido seja concluído com alocações incompletas" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "O pedido tem alocações incompletas" #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" @@ -5718,1286 +6125,1319 @@ msgstr "Perdido" msgid "Returned" msgstr "Devolvido" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Em andamento" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" -msgstr "" +msgstr "Devolução" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Consertar" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" -msgstr "" +msgstr "Substituição" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" -msgstr "" +msgstr "Reembolso" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Rejeitado" -#: order/tasks.py:48 -msgid "Overdue Purchase Order" -msgstr "" +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Emitido" -#: order/tasks.py:53 +#: order/tasks.py:49 +msgid "Overdue Purchase Order" +msgstr "Pedido de compra atrasado" + +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" -msgstr "" +msgstr "O pedido de compra {po} está atrasado" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" -msgstr "" +msgstr "Pedido de venda atrasado" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" -msgstr "" +msgstr "O pedido de venda {so} está atrasado" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" -msgstr "" +msgstr "Pedido de devolução atrasado" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" -msgstr "" - -#: part/api.py:88 -msgid "Starred" -msgstr "" +msgstr "O pedido de devolução {ro} está atrasado" #: part/api.py:90 +msgid "Starred" +msgstr "Favorito" + +#: part/api.py:92 msgid "Filter by starred categories" -msgstr "" +msgstr "Filtrar por categorias favoritas" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" -msgstr "" +msgstr "Profundidade" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" -msgstr "" +msgstr "Filtrar por profundidade da categoria" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" -msgstr "" +msgstr "Nível superior" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" -msgstr "" +msgstr "Filtrar por categorias de nível superior" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" -msgstr "" +msgstr "Cascata" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" -msgstr "" - -#: part/api.py:162 -msgid "Parent" -msgstr "" +msgstr "Incluir subcategorias nos resultados filtrados" #: part/api.py:164 +msgid "Parent" +msgstr "Pai" + +#: part/api.py:166 msgid "Filter by parent category" -msgstr "" +msgstr "Filtrar por categoria pai" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" -msgstr "" +msgstr "Excluir subcategorias da categoria especificada" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "Nível máximo" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "Limitar a profundidade da árvore de categorias" + +#: part/api.py:442 msgid "Has Results" -msgstr "" - -#: part/api.py:654 -msgid "Is Variant" -msgstr "" - -#: part/api.py:662 -msgid "Is Revision" -msgstr "" +msgstr "Tem resultados" #: part/api.py:672 +msgid "Is Variant" +msgstr "É variante" + +#: part/api.py:680 +msgid "Is Revision" +msgstr "É revisão" + +#: part/api.py:690 msgid "Has Revisions" -msgstr "" +msgstr "Tem revisões" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" -msgstr "" +msgstr "BOM válida" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" -msgstr "" +msgstr "Categorias em cascata" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" -msgstr "" +msgstr "Se verdadeiro, inclui itens nas categorias filhas da categoria informada" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" -msgstr "" +msgstr "Filtrar por ID numérico da categoria ou o literal 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" -msgstr "" +msgstr "A peça de montagem está ativa" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" -msgstr "" +msgstr "A peça de montagem é rastreável" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" -msgstr "" +msgstr "A peça de montagem é testável" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" -msgstr "" +msgstr "A peça de montagem está bloqueada" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" -msgstr "" +msgstr "A peça componente está ativa" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" -msgstr "" +msgstr "A peça componente é rastreável" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" -msgstr "" +msgstr "A peça componente é testável" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" -msgstr "" +msgstr "A peça componente é uma montagem" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" -msgstr "" +msgstr "A peça componente é virtual" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" -msgstr "" +msgstr "Tem estoque disponível" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" -msgstr "" +msgstr "Usos" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" -msgstr "Categoria da Peça" +msgstr "Categoria da peça" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" -msgstr "Categorias de Peça" +msgstr "Categorias de peça" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" -msgstr "Local Padrão" +msgstr "Local padrão" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Local padrão para peças desta categoria" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" -msgstr "" +msgstr "Estrutural" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." -msgstr "" +msgstr "As peças não podem ser atribuídas diretamente a uma categoria estrutural, mas podem ser atribuídas a categorias filhas." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" -msgstr "Palavras-chave Padrão" +msgstr "Palavras-chave padrão" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Palavras-chave padrão para peças nesta categoria" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ícone" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ícone (opcional)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" -msgstr "" +msgstr "Você não pode tornar esta categoria de peças estrutural porque algumas peças já estão atribuídas a ela!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" -msgstr "" +msgstr "Modelo de parâmetro da categoria de peças" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" -msgstr "Valor Padrão" +msgstr "Valor padrão" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" -msgstr "Valor Padrão do Parâmetro" +msgstr "Valor padrão do parâmetro" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Peças" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" -msgstr "" +msgstr "Não é possível excluir parâmetros de uma peça bloqueada" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" -msgstr "" +msgstr "Não é possível modificar parâmetros de uma peça bloqueada" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" -msgstr "" +msgstr "Não é possível excluir esta peça porque ela está bloqueada" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" -msgstr "" +msgstr "Não é possível excluir esta peça porque ela ainda está ativa" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" -msgstr "" +msgstr "Não é possível excluir esta peça porque ela é usada em uma montagem" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" -msgstr "" +msgstr "A peça '{self}' não pode ser usada na lista de materiais de '{parent}' (recursivo)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" -msgstr "" +msgstr "A peça '{parent}' é usada na lista de materiais de '{self}' (recursivo)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" -msgstr "" +msgstr "O IPN deve corresponder ao padrão regex {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" -msgstr "" +msgstr "A peça não pode ser uma revisão de si mesma" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" -msgstr "" +msgstr "O código de revisão deve ser especificado para uma peça marcada como revisão" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" -msgstr "" - -#: part/models.py:799 -msgid "Cannot make a revision of a template part" -msgstr "" +msgstr "Revisões só são permitidas para peças de montagem" #: part/models.py:805 +msgid "Cannot make a revision of a template part" +msgstr "Não é possível criar uma revisão de uma peça modelo" + +#: part/models.py:811 msgid "Parent part must point to the same template" -msgstr "" +msgstr "A peça pai deve apontar para o mesmo modelo" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" -msgstr "" +msgstr "Já existe um item de estoque com este número de série" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" -msgstr "" +msgstr "IPN duplicado não é permitido nas configurações de peças" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." -msgstr "" +msgstr "Já existe uma revisão de peça duplicada." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." -msgstr "" +msgstr "Já existe uma peça com este nome, IPN e revisão." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" -msgstr "" +msgstr "As peças não podem ser atribuídas a categorias de peças estruturais!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Nome da peça" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "É um modelo" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" -msgstr "" +msgstr "Esta peça é uma peça modelo?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" -msgstr "" +msgstr "Esta peça é uma variante de outra peça?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" -msgstr "" +msgstr "Variante de" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Descrição da peça (opcional)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Palavras-chaves" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" -msgstr "" +msgstr "Palavras-chave da peça para melhorar a visibilidade nos resultados de busca" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" -msgstr "Categoria da Peça" +msgstr "Categoria da peça" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" -msgstr "" +msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" -msgstr "" +msgstr "Revisão da peça ou número da versão" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" -msgstr "" - -#: part/models.py:1169 -msgid "Is this part a revision of another part?" -msgstr "" - -#: part/models.py:1170 -msgid "Revision Of" -msgstr "" +msgstr "Revisão" #: part/models.py:1186 +msgid "Is this part a revision of another part?" +msgstr "Esta peça é uma revisão de outra peça?" + +#: part/models.py:1187 +msgid "Revision Of" +msgstr "Revisão de" + +#: part/models.py:1203 msgid "Where is this item normally stored?" -msgstr "" +msgstr "Onde este item é normalmente armazenado?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" -msgstr "Validade Padrão" +msgstr "Validade padrão" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Validade (em dias) para itens do estoque desta peça" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" -msgstr "Estoque Mínimo" - -#: part/models.py:1233 -msgid "Minimum allowed stock level" -msgstr "" - -#: part/models.py:1241 part/serializers.py:902 -msgid "Maximum Stock" -msgstr "" - -#: part/models.py:1242 -msgid "Maximum allowed stock level" -msgstr "" +msgstr "Estoque mínimo" #: part/models.py:1251 +msgid "Minimum allowed stock level" +msgstr "Nível mínimo de estoque permitido" + +#: part/models.py:1259 part/serializers.py:888 +msgid "Maximum Stock" +msgstr "Estoque máximo" + +#: part/models.py:1260 +msgid "Maximum allowed stock level" +msgstr "Nível máximo de estoque permitido" + +#: part/models.py:1269 msgid "Units of measure for this part" -msgstr "" - -#: part/models.py:1258 -msgid "Can this part be built from other parts?" -msgstr "" - -#: part/models.py:1264 -msgid "Can this part be used to build other parts?" -msgstr "" - -#: part/models.py:1270 -msgid "Does this part have tracking for unique items?" -msgstr "" +msgstr "Unidades de medida desta peça" #: part/models.py:1276 -msgid "Can this part have test results recorded against it?" -msgstr "" +msgid "Can this part be built from other parts?" +msgstr "Esta peça pode ser produzida a partir de outras peças?" #: part/models.py:1282 -msgid "Can this part be purchased from external suppliers?" -msgstr "" +msgid "Can this part be used to build other parts?" +msgstr "Esta peça pode ser usada para produzir outras peças?" #: part/models.py:1288 +msgid "Does this part have tracking for unique items?" +msgstr "Esta peça tem rastreamento para itens únicos?" + +#: part/models.py:1294 +msgid "Can this part have test results recorded against it?" +msgstr "Esta peça pode ter resultados de teste registrados?" + +#: part/models.py:1300 +msgid "Can this part be purchased from external suppliers?" +msgstr "Esta peça pode ser comprada de fornecedores externos?" + +#: part/models.py:1306 msgid "Can this part be sold to customers?" -msgstr "" - -#: part/models.py:1292 -msgid "Is this part active?" -msgstr "" - -#: part/models.py:1298 -msgid "Locked parts cannot be edited" -msgstr "" - -#: part/models.py:1304 -msgid "Is this a virtual part, such as a software product or license?" -msgstr "" - -#: part/models.py:1309 -msgid "BOM Validated" -msgstr "" +msgstr "Esta peça pode ser vendida a clientes?" #: part/models.py:1310 -msgid "Is the BOM for this part valid?" -msgstr "" +msgid "Is this part active?" +msgstr "Esta peça está ativa?" #: part/models.py:1316 +msgid "Locked parts cannot be edited" +msgstr "Peças bloqueadas não podem ser editadas" + +#: part/models.py:1322 +msgid "Is this a virtual part, such as a software product or license?" +msgstr "Esta é uma peça virtual, como um produto de software ou licença?" + +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "Esta peça é consumível, como cola ou um fixador?" + +#: part/models.py:1333 +msgid "BOM Validated" +msgstr "Lista de materiais validada" + +#: part/models.py:1334 +msgid "Is the BOM for this part valid?" +msgstr "A lista de materiais desta peça é válida?" + +#: part/models.py:1340 msgid "BOM checksum" -msgstr "" +msgstr "Checksum da lista de materiais" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" -msgstr "" +msgstr "Checksum armazenado da lista de materiais" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" -msgstr "" +msgstr "Lista de materiais verificada por" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" -msgstr "" +msgstr "Data de verificação da lista de materiais" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" -msgstr "Criação de Usuário" +msgstr "Criação de usuário" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" -msgstr "" +msgstr "Proprietário responsável por esta peça" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" -msgstr "" +msgstr "Vender em múltiplos" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" -msgstr "" +msgstr "Moeda usada para armazenar os cálculos de preço" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" -msgstr "" +msgstr "Custo mínimo da lista de materiais" + +#: part/models.py:3233 +msgid "Minimum cost of component parts" +msgstr "Custo mínimo das peças componentes" + +#: part/models.py:3239 +msgid "Maximum BOM Cost" +msgstr "Custo máximo da lista de materiais" + +#: part/models.py:3240 +msgid "Maximum cost of component parts" +msgstr "Custo máximo das peças componentes" + +#: part/models.py:3246 +msgid "Minimum Purchase Cost" +msgstr "Custo mínimo de compra" + +#: part/models.py:3247 +msgid "Minimum historical purchase cost" +msgstr "Custo histórico mínimo de compra" + +#: part/models.py:3253 +msgid "Maximum Purchase Cost" +msgstr "Custo máximo de compra" + +#: part/models.py:3254 +msgid "Maximum historical purchase cost" +msgstr "Custo histórico máximo de compra" + +#: part/models.py:3260 +msgid "Minimum Internal Price" +msgstr "Preço interno mínimo" + +#: part/models.py:3261 +msgid "Minimum cost based on internal price breaks" +msgstr "Custo mínimo com base nas faixas de preço internas" + +#: part/models.py:3267 +msgid "Maximum Internal Price" +msgstr "Preço interno máximo" + +#: part/models.py:3268 +msgid "Maximum cost based on internal price breaks" +msgstr "Custo máximo com base nas faixas de preço internas" + +#: part/models.py:3274 +msgid "Minimum Supplier Price" +msgstr "Preço mínimo do fornecedor" + +#: part/models.py:3275 +msgid "Minimum price of part from external suppliers" +msgstr "Preço mínimo da peça de fornecedores externos" + +#: part/models.py:3281 +msgid "Maximum Supplier Price" +msgstr "Preço máximo do fornecedor" + +#: part/models.py:3282 +msgid "Maximum price of part from external suppliers" +msgstr "Preço máximo da peça de fornecedores externos" + +#: part/models.py:3288 +msgid "Minimum Variant Cost" +msgstr "Custo mínimo de variante" + +#: part/models.py:3289 +msgid "Calculated minimum cost of variant parts" +msgstr "Custo mínimo calculado das peças variantes" + +#: part/models.py:3295 +msgid "Maximum Variant Cost" +msgstr "Custo máximo de variante" + +#: part/models.py:3296 +msgid "Calculated maximum cost of variant parts" +msgstr "Custo máximo calculado das peças variantes" + +#: part/models.py:3302 part/models.py:3316 +msgid "Minimum Cost" +msgstr "Custo mínimo" + +#: part/models.py:3303 +msgid "Override minimum cost" +msgstr "Substituir custo mínimo" + +#: part/models.py:3309 part/models.py:3323 +msgid "Maximum Cost" +msgstr "Custo máximo" + +#: part/models.py:3310 +msgid "Override maximum cost" +msgstr "Substituir custo máximo" + +#: part/models.py:3317 +msgid "Calculated overall minimum cost" +msgstr "Custo mínimo geral calculado" + +#: part/models.py:3324 +msgid "Calculated overall maximum cost" +msgstr "Custo máximo geral calculado" + +#: part/models.py:3330 +msgid "Minimum Sale Price" +msgstr "Preço de venda mínimo" + +#: part/models.py:3331 +msgid "Minimum sale price based on price breaks" +msgstr "Preço de venda mínimo com base nas faixas de preço" + +#: part/models.py:3337 +msgid "Maximum Sale Price" +msgstr "Preço de venda máximo" + +#: part/models.py:3338 +msgid "Maximum sale price based on price breaks" +msgstr "Preço de venda máximo com base nas faixas de preço" #: part/models.py:3344 -msgid "Minimum cost of component parts" -msgstr "" +msgid "Minimum Sale Cost" +msgstr "Custo de venda mínimo" -#: part/models.py:3350 -msgid "Maximum BOM Cost" -msgstr "" +#: part/models.py:3345 +msgid "Minimum historical sale price" +msgstr "Preço de venda histórico mínimo" #: part/models.py:3351 -msgid "Maximum cost of component parts" -msgstr "" - -#: part/models.py:3357 -msgid "Minimum Purchase Cost" -msgstr "" - -#: part/models.py:3358 -msgid "Minimum historical purchase cost" -msgstr "" - -#: part/models.py:3364 -msgid "Maximum Purchase Cost" -msgstr "" - -#: part/models.py:3365 -msgid "Maximum historical purchase cost" -msgstr "" - -#: part/models.py:3371 -msgid "Minimum Internal Price" -msgstr "" - -#: part/models.py:3372 -msgid "Minimum cost based on internal price breaks" -msgstr "" - -#: part/models.py:3378 -msgid "Maximum Internal Price" -msgstr "" - -#: part/models.py:3379 -msgid "Maximum cost based on internal price breaks" -msgstr "" - -#: part/models.py:3385 -msgid "Minimum Supplier Price" -msgstr "" - -#: part/models.py:3386 -msgid "Minimum price of part from external suppliers" -msgstr "" - -#: part/models.py:3392 -msgid "Maximum Supplier Price" -msgstr "" - -#: part/models.py:3393 -msgid "Maximum price of part from external suppliers" -msgstr "" - -#: part/models.py:3399 -msgid "Minimum Variant Cost" -msgstr "" - -#: part/models.py:3400 -msgid "Calculated minimum cost of variant parts" -msgstr "" - -#: part/models.py:3406 -msgid "Maximum Variant Cost" -msgstr "" - -#: part/models.py:3407 -msgid "Calculated maximum cost of variant parts" -msgstr "" - -#: part/models.py:3413 part/models.py:3427 -msgid "Minimum Cost" -msgstr "" - -#: part/models.py:3414 -msgid "Override minimum cost" -msgstr "" - -#: part/models.py:3420 part/models.py:3434 -msgid "Maximum Cost" -msgstr "" - -#: part/models.py:3421 -msgid "Override maximum cost" -msgstr "" - -#: part/models.py:3428 -msgid "Calculated overall minimum cost" -msgstr "" - -#: part/models.py:3435 -msgid "Calculated overall maximum cost" -msgstr "" - -#: part/models.py:3441 -msgid "Minimum Sale Price" -msgstr "" - -#: part/models.py:3442 -msgid "Minimum sale price based on price breaks" -msgstr "" - -#: part/models.py:3448 -msgid "Maximum Sale Price" -msgstr "" - -#: part/models.py:3449 -msgid "Maximum sale price based on price breaks" -msgstr "" - -#: part/models.py:3455 -msgid "Minimum Sale Cost" -msgstr "" - -#: part/models.py:3456 -msgid "Minimum historical sale price" -msgstr "" - -#: part/models.py:3462 msgid "Maximum Sale Cost" -msgstr "" +msgstr "Custo de venda máximo" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" -msgstr "" +msgstr "Preço de venda histórico máximo" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" -msgstr "" +msgstr "Peça para inventário" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" -msgstr "" +msgstr "Contagem de itens" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" -msgstr "" +msgstr "Número de entradas de estoque individuais no momento do inventário" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" -msgstr "" +msgstr "Estoque total disponível no momento do inventário" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Data" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" -msgstr "" +msgstr "Data em que o inventário foi realizado" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" -msgstr "" +msgstr "Custo mínimo do estoque" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" -msgstr "" +msgstr "Custo mínimo estimado do estoque em mãos" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" -msgstr "" +msgstr "Custo máximo do estoque" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" -msgstr "" +msgstr "Custo máximo estimado do estoque em mãos" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" -msgstr "" +msgstr "Faixa de preço de venda da peça" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "Faixa de preço interno da peça" + +#: part/models.py:3529 msgid "Part Test Template" -msgstr "" +msgstr "Modelo de teste da peça" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" -msgstr "" +msgstr "Nome de modelo inválido - deve incluir pelo menos um caractere alfanumérico" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" -msgstr "Modelos de teste só podem ser criados para partes testáveis" +msgstr "Modelos de teste só podem ser criados para peças testáveis" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" -msgstr "" +msgstr "Já existe um modelo de teste com a mesma chave para a peça" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" -msgstr "" +msgstr "Nome do teste" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" -msgstr "" +msgstr "Insira um nome para o teste" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" -msgstr "" +msgstr "Chave do teste" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" -msgstr "" +msgstr "Chave simplificada para o teste" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" -msgstr "" +msgstr "Descrição do teste" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" -msgstr "" +msgstr "Insira a descrição deste teste" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" -msgstr "" +msgstr "Este teste está habilitado?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Obrigatório" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" -msgstr "" +msgstr "Este teste precisa ser aprovado?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" -msgstr "" +msgstr "Requer valor" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" -msgstr "" +msgstr "Este teste requer um valor ao adicionar um resultado de teste?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" -msgstr "" +msgstr "Requer anexo" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" -msgstr "" +msgstr "Este teste requer um anexo de arquivo ao adicionar um resultado de teste?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" -msgstr "" +msgstr "Opções válidas para este teste (separadas por vírgula)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" -msgstr "" +msgstr "Quantidade inválida - nenhuma unidade especificada para a peça" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" -msgstr "" +msgstr "A quantidade deve ser maior ou igual a zero" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" -msgstr "" +msgstr "O item da lista de materiais não pode ser modificado - a montagem está bloqueada" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" -msgstr "" +msgstr "O item da lista de materiais não pode ser modificado - a montagem da variante está bloqueada" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" -msgstr "" +msgstr "Selecionar peça pai" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Sub peça" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" -msgstr "" +msgstr "Selecionar peça a ser usada na lista de materiais" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" -msgstr "" +msgstr "Quantidade" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" -msgstr "" +msgstr "Quantidade de subpeça consumida para produzir uma peça" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" -msgstr "" +msgstr "Quantidade na lista de materiais para este item" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" -msgstr "" +msgstr "Este item da lista de materiais é opcional" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" -msgstr "" +msgstr "Este item da lista de materiais é consumível (não é rastreado em pedidos de produção)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" -msgstr "" +msgstr "Quantidade de preparação" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" -msgstr "" +msgstr "Quantidade extra necessária para uma produção, para compensar perdas de preparação" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" -msgstr "" +msgstr "Perda" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" -msgstr "" +msgstr "Perda estimada para uma produção, expressa em porcentagem (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" -msgstr "" +msgstr "Múltiplo de arredondamento" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" +msgstr "Arredondar para cima a quantidade de produção necessária para o múltiplo mais próximo deste valor" + +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" msgstr "" -#: part/models.py:4122 +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" -msgstr "" +msgstr "Referência do item da lista de materiais" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" -msgstr "" +msgstr "Notas do item da lista de materiais" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" -msgstr "" +msgstr "Checksum" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" -msgstr "" +msgstr "Checksum da linha da lista de materiais" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" -msgstr "" +msgstr "Validado" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" -msgstr "" +msgstr "Este item da lista de materiais foi validado" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" -msgstr "" +msgstr "É herdado" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" -msgstr "" +msgstr "Este item da lista de materiais é herdado pelas listas de materiais das peças variantes" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" -msgstr "" +msgstr "Itens de estoque de peças variantes podem ser usados para este item da lista de materiais" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" -msgstr "" +msgstr "A quantidade deve ser um valor inteiro para peças rastreáveis" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" -msgstr "" +msgstr "A subpeça deve ser especificada" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" -msgstr "" +msgstr "Substituto do item da lista de materiais" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" -msgstr "" +msgstr "A peça substituta não pode ser a mesma que a peça principal" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" -msgstr "" +msgstr "Item pai da lista de materiais" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" -msgstr "" +msgstr "Peça substituta" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" -msgstr "" +msgstr "Peça 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" -msgstr "" +msgstr "Peça 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" -msgstr "" +msgstr "Selecionar peça relacionada" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" -msgstr "" +msgstr "Nota para esta relação" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" -msgstr "" +msgstr "Não é possível criar uma relação de peça entre uma peça e ela mesma" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" -msgstr "" +msgstr "Já existe uma relação duplicada" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "Excluir subcategorias" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "Excluir todas as subcategorias contidas nesta categoria" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "Excluir peças" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "Excluir todas as peças contidas nesta categoria" + +#: part/serializers.py:130 msgid "Parent Category" -msgstr "" +msgstr "Categoria pai" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" -msgstr "" +msgstr "Categoria de peça pai" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" -msgstr "" +msgstr "Subcategorias" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" -msgstr "" +msgstr "Resultados" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" -msgstr "" +msgstr "Número de resultados registrados para este modelo" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" -msgstr "" +msgstr "Moeda de compra deste item de estoque" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" -msgstr "" +msgstr "O arquivo não é uma imagem" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" +#: part/serializers.py:426 +msgid "Initial Stock Quantity" +msgstr "Quantidade inicial de estoque" #: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 -msgid "Initial Stock Quantity" -msgstr "" - -#: part/serializers.py:449 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." -msgstr "" +msgstr "Especifique a quantidade inicial de estoque para esta peça. Se a quantidade for zero, nenhum estoque é adicionado." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" -msgstr "" +msgstr "Local inicial de estoque" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" -msgstr "" +msgstr "Especifique o local inicial de estoque para esta peça" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" -msgstr "" +msgstr "Selecionar fornecedor (ou deixar em branco para pular)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" -msgstr "" +msgstr "Selecionar fabricante (ou deixar em branco para pular)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" -msgstr "" +msgstr "Número de peça do fabricante" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" -msgstr "" +msgstr "A empresa selecionada não é um fornecedor válido" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" -msgstr "" +msgstr "A empresa selecionada não é um fabricante válido" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" -msgstr "" +msgstr "Já existe uma peça de fabricante com este MPN" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" -msgstr "" +msgstr "Já existe uma peça de fornecedor com este SKU" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" -msgstr "" +msgstr "Nome da categoria" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" -msgstr "" +msgstr "Em produção" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" -msgstr "" +msgstr "Quantidade desta peça atualmente em produção" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" -msgstr "" +msgstr "Quantidade pendente desta peça programada para produção" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" -msgstr "Itens de Estoque" +msgstr "Itens de estoque" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" -msgstr "" +msgstr "Revisões" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" -msgstr "Estoque Total" +msgstr "Estoque total" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" -msgstr "" +msgstr "Estoque não alocado" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" -msgstr "" +msgstr "Estoque de variante" + +#: part/serializers.py:956 +msgid "Duplicate Part" +msgstr "Duplicar peça" + +#: part/serializers.py:957 +msgid "Copy initial data from another Part" +msgstr "Copiar dados iniciais de outra peça" + +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Copiar imagem" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Copiar imagem da peça original" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Copiar lista de materiais" #: part/serializers.py:969 -msgid "Duplicate Part" -msgstr "" +msgid "Copy bill of materials from original part" +msgstr "Copiar lista de materiais da peça original" -#: part/serializers.py:970 -msgid "Copy initial data from another Part" -msgstr "" +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Copiar notas" -#: part/serializers.py:976 +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Copiar notas da peça original" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Copiar testes" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Copiar modelos de teste da peça original" + +#: part/serializers.py:988 msgid "Initial Stock" -msgstr "Estoque Inicial" +msgstr "Estoque inicial" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" -msgstr "" +msgstr "Criar peça com quantidade inicial de estoque" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" -msgstr "" +msgstr "Informações do fornecedor" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" -msgstr "" +msgstr "Adicionar informações iniciais de fornecedor para esta peça" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" -msgstr "" +msgstr "Copiar parâmetros da categoria" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" -msgstr "" +msgstr "Copiar modelos de parâmetro da categoria de peças selecionada" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" -msgstr "" +msgstr "Imagem existente" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" -msgstr "" +msgstr "Nome do arquivo de uma imagem de peça existente" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" -msgstr "" +msgstr "O arquivo de imagem não existe" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" -msgstr "" +msgstr "Validar toda a lista de materiais" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" -msgstr "" +msgstr "Pode produzir" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" -msgstr "" +msgstr "Necessário para pedidos de produção" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" -msgstr "" +msgstr "Alocado para pedidos de produção" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" -msgstr "" +msgstr "Necessário para pedidos de venda" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" -msgstr "" +msgstr "Alocado para pedidos de venda" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" -msgstr "" +msgstr "IPN da peça" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" -msgstr "" +msgstr "Descrição da peça" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" -msgstr "" +msgstr "Selecione uma peça para gerar informações de inventário para essa peça (e quaisquer peças variantes)" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" -msgstr "" +msgstr "Selecione uma categoria para incluir todas as peças dentro dela (e subcategorias)" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" -msgstr "" +msgstr "Selecione um local para incluir todas as peças com estoque nesse local (incluindo sublocais)" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" -msgstr "" +msgstr "Gerar registros de inventário" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" -msgstr "" +msgstr "Salvar registros de inventário para as peças selecionadas" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" -msgstr "" +msgstr "Gerar relatório" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" -msgstr "" - -#: part/serializers.py:1466 -msgid "Minimum Price" -msgstr "" - -#: part/serializers.py:1467 -msgid "Override calculated value for minimum price" -msgstr "" - -#: part/serializers.py:1474 -msgid "Minimum price currency" -msgstr "" +msgstr "Gerar um relatório de inventário para as peças selecionadas" #: part/serializers.py:1481 -msgid "Maximum Price" -msgstr "" +msgid "Minimum Price" +msgstr "Preço mínimo" #: part/serializers.py:1482 -msgid "Override calculated value for maximum price" -msgstr "" +msgid "Override calculated value for minimum price" +msgstr "Substituir o valor calculado do preço mínimo" #: part/serializers.py:1489 -msgid "Maximum price currency" -msgstr "" +msgid "Minimum price currency" +msgstr "Moeda do preço mínimo" -#: part/serializers.py:1518 +#: part/serializers.py:1496 +msgid "Maximum Price" +msgstr "Preço máximo" + +#: part/serializers.py:1497 +msgid "Override calculated value for maximum price" +msgstr "Substituir o valor calculado do preço máximo" + +#: part/serializers.py:1504 +msgid "Maximum price currency" +msgstr "Moeda do preço máximo" + +#: part/serializers.py:1533 msgid "Update" msgstr "Atualizar" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" -msgstr "" +msgstr "Atualizar preços desta peça" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" -msgstr "" +msgstr "Não foi possível converter das moedas informadas para {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" -msgstr "" +msgstr "O preço mínimo não pode ser maior que o preço máximo" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" -msgstr "" +msgstr "O preço máximo não pode ser menor que o preço mínimo" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" -msgstr "" +msgstr "Quantidade necessária para este item (pode incluir unidades)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" -msgstr "" +msgstr "Selecionar a montagem pai" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" -msgstr "" +msgstr "Selecionar a peça componente" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" -msgstr "" +msgstr "Formato de quantidade inválido" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" -msgstr "" +msgstr "Selecionar peça da qual copiar a lista de materiais" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" -msgstr "" +msgstr "Remover dados existentes" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" -msgstr "" +msgstr "Remover itens existentes da lista de materiais antes de copiar" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" -msgstr "" +msgstr "Incluir herdados" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" -msgstr "" +msgstr "Incluir itens da lista de materiais herdados de peças modelo" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" -msgstr "Ignorar Linhas Inválidas" +msgstr "Ignorar linhas inválidas" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Habilite essa opção para ignorar linhas inválidas" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" -msgstr "" +msgstr "Copiar peças substitutas" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" -msgstr "" +msgstr "Copiar peças substitutas ao duplicar itens da lista de materiais" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" -msgstr "" +msgstr "Notificação de estoque baixo" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" -msgstr "" +msgstr "O estoque disponível de {part.name} caiu abaixo do nível mínimo configurado" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" -msgstr "" +msgstr "Notificação de estoque parado" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" -msgstr "" +msgstr "Você tem 1 item de estoque se aproximando da data de validade" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" -msgstr "" +msgstr "Você tem {item_count} itens de estoque se aproximando da data de validade" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" -msgstr "" +msgstr "Sem data de validade" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "Expirou {abs(days_diff)} dias atrás" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" -msgstr "" +msgstr "Vence hoje" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} dias" #: plugin/api.py:80 msgid "Builtin" -msgstr "" +msgstr "Integrado" #: plugin/api.py:94 msgid "Mandatory" @@ -7011,9 +7451,9 @@ msgstr "Exemplo" msgid "Installed" msgstr "Instalado" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" -msgstr "" +msgstr "O plugin não pode ser excluído porque está ativo no momento" #: plugin/base/action/api.py:56 msgid "No action specified" @@ -7021,269 +7461,285 @@ msgstr "Nenhuma ação especificada" #: plugin/base/action/api.py:70 msgid "No matching action found" -msgstr "" +msgstr "Nenhuma ação correspondente encontrada" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Nenhum resultado encontrado para os dados do código de barras" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Correspondência encontrada para dados de código de barras" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Modelo não suportado" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" -msgstr "" +msgstr "Instância do modelo não encontrada" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Código de barras corresponde ao item existente" #: plugin/base/barcodes/api.py:419 msgid "No matching part data found" -msgstr "" +msgstr "Nenhum dado de peça correspondente encontrado" #: plugin/base/barcodes/api.py:435 msgid "No matching supplier parts found" -msgstr "" +msgstr "Nenhuma peça de fornecedor correspondente encontrada" #: plugin/base/barcodes/api.py:438 msgid "Multiple matching supplier parts found" -msgstr "" +msgstr "Várias peças de fornecedor correspondentes encontradas" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "Você não possui as permissões necessárias para pedidos de compra" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" -msgstr "" +msgstr "Nenhum plugin correspondente encontrado para os dados do código de barras" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" -msgstr "" +msgstr "Peça de fornecedor correspondente" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" -msgstr "" +msgstr "O item já foi recebido" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "Pedido de compra encontrado\\rNenhuma peça de fornecedor correspondente" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "Peça de fornecedor encontrada\\rNenhum pedido de compra correspondente" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" -msgstr "" +msgstr "Nenhum plugin correspondente para o código de barras do fornecedor" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" -msgstr "" +msgstr "Vários itens de linha correspondentes encontrados" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" -msgstr "" +msgstr "Nenhum item de linha correspondente encontrado" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "Você não possui as permissões necessárias para pedidos de venda" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" -msgstr "" +msgstr "Nenhum pedido de venda fornecido" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" -msgstr "" +msgstr "O código de barras não corresponde a um item de estoque existente" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" -msgstr "" +msgstr "O item de estoque não corresponde ao item de linha" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" -msgstr "" +msgstr "Estoque disponível insuficiente" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" -msgstr "" +msgstr "Item de estoque alocado ao pedido de venda" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" -msgstr "" +msgstr "Informações insuficientes" #: plugin/base/barcodes/mixins.py:309 #: plugin/builtin/barcodes/inventree_barcode.py:101 msgid "Found matching item" -msgstr "" +msgstr "Item correspondente encontrado" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" -msgstr "" +msgstr "A peça de fornecedor não corresponde ao item de linha" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" -msgstr "" +msgstr "O item de linha já foi concluído" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" -msgstr "" +msgstr "Mais informações necessárias para receber o item de linha" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" -msgstr "" +msgstr "Item de linha do pedido de compra recebido" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" -msgstr "" +msgstr "Falha ao receber o item de linha" #: plugin/base/barcodes/serializers.py:53 msgid "Scanned barcode data" -msgstr "" +msgstr "Dados do código de barras lido" #: plugin/base/barcodes/serializers.py:62 msgid "Model name to generate barcode for" -msgstr "" +msgstr "Nome do modelo para o qual gerar o código de barras" #: plugin/base/barcodes/serializers.py:67 msgid "Primary key of model object to generate barcode for" -msgstr "" +msgstr "Chave primária do objeto do modelo para o qual gerar o código de barras" #: plugin/base/barcodes/serializers.py:137 msgid "Purchase Order to allocate items against" -msgstr "" +msgstr "Pedido de compra ao qual alocar itens" #: plugin/base/barcodes/serializers.py:143 msgid "Purchase order is not open" -msgstr "" +msgstr "O pedido de compra não está aberto" #: plugin/base/barcodes/serializers.py:161 msgid "Supplier to receive items from" -msgstr "" +msgstr "Fornecedor do qual receber itens" #: plugin/base/barcodes/serializers.py:168 msgid "PurchaseOrder to receive items against" -msgstr "" +msgstr "Pedido de compra ao qual receber itens" #: plugin/base/barcodes/serializers.py:174 msgid "Purchase order has not been placed" -msgstr "" +msgstr "O pedido de compra não foi feito" #: plugin/base/barcodes/serializers.py:182 msgid "Location to receive items into" -msgstr "" +msgstr "Local onde receber os itens" #: plugin/base/barcodes/serializers.py:188 msgid "Cannot select a structural location" -msgstr "" +msgstr "Não é possível selecionar um local estrutural" #: plugin/base/barcodes/serializers.py:196 msgid "Purchase order line item to receive items against" -msgstr "" +msgstr "Item de linha do pedido de compra ao qual receber itens" #: plugin/base/barcodes/serializers.py:202 msgid "Automatically allocate stock items to the purchase order" -msgstr "" +msgstr "Alocar automaticamente itens de estoque ao pedido de compra" #: plugin/base/barcodes/serializers.py:215 msgid "Sales Order to allocate items against" -msgstr "" +msgstr "Pedido de venda ao qual alocar itens" #: plugin/base/barcodes/serializers.py:221 msgid "Sales order is not open" -msgstr "" +msgstr "O pedido de venda não está aberto" #: plugin/base/barcodes/serializers.py:229 msgid "Sales order line item to allocate items against" -msgstr "" +msgstr "Item de linha do pedido de venda ao qual alocar itens" #: plugin/base/barcodes/serializers.py:236 msgid "Sales order shipment to allocate items against" -msgstr "" +msgstr "Remessa do pedido de venda à qual alocar itens" #: plugin/base/barcodes/serializers.py:242 msgid "Shipment has already been delivered" -msgstr "" +msgstr "A remessa já foi entregue" #: plugin/base/barcodes/serializers.py:247 msgid "Quantity to allocate" -msgstr "" +msgstr "Quantidade a alocar" #: plugin/base/label/label.py:41 msgid "Label printing failed" -msgstr "" +msgstr "Falha na impressão da etiqueta" #: plugin/base/label/mixins.py:56 msgid "Error rendering label to PDF" -msgstr "" +msgstr "Erro ao renderizar a etiqueta em PDF" #: plugin/base/label/mixins.py:73 msgid "Error rendering label to HTML" -msgstr "" +msgstr "Erro ao renderizar a etiqueta em HTML" #: plugin/base/label/mixins.py:156 msgid "No items provided to print" -msgstr "" +msgstr "Nenhum item fornecido para impressão" #: plugin/base/ui/serializers.py:30 msgid "Plugin Name" -msgstr "" +msgstr "Nome do plugin" #: plugin/base/ui/serializers.py:34 msgid "Feature Type" -msgstr "" +msgstr "Tipo de recurso" #: plugin/base/ui/serializers.py:39 msgid "Feature Label" -msgstr "" +msgstr "Rótulo do recurso" #: plugin/base/ui/serializers.py:44 msgid "Feature Title" -msgstr "" +msgstr "Título do recurso" #: plugin/base/ui/serializers.py:49 msgid "Feature Description" -msgstr "" +msgstr "Descrição do recurso" #: plugin/base/ui/serializers.py:54 msgid "Feature Icon" -msgstr "" +msgstr "Ícone do recurso" #: plugin/base/ui/serializers.py:58 msgid "Feature Options" -msgstr "" +msgstr "Opções do recurso" #: plugin/base/ui/serializers.py:61 msgid "Feature Context" -msgstr "" +msgstr "Contexto do recurso" #: plugin/base/ui/serializers.py:64 msgid "Feature Source (javascript)" -msgstr "" +msgstr "Fonte do recurso (javascript)" #: plugin/builtin/barcodes/inventree_barcode.py:27 msgid "InvenTree Barcodes" -msgstr "Códigos de Barras InvenTree" +msgstr "Códigos de barras InvenTree" #: plugin/builtin/barcodes/inventree_barcode.py:28 msgid "Provides native support for barcodes" -msgstr "" +msgstr "Fornece suporte nativo para códigos de barras" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" -msgstr "" +msgstr "Contribuidores do InvenTree" #: plugin/builtin/barcodes/inventree_barcode.py:34 msgid "Internal Barcode Format" -msgstr "Formato do Código de Barras Interno" +msgstr "Formato do código de barras interno" #: plugin/builtin/barcodes/inventree_barcode.py:35 msgid "Select an internal barcode format" @@ -7291,7 +7747,7 @@ msgstr "Selecione um formato de código de barras interno" #: plugin/builtin/barcodes/inventree_barcode.py:37 msgid "JSON barcodes (human readable)" -msgstr "" +msgstr "Códigos de barras JSON (legíveis por humanos)" #: plugin/builtin/barcodes/inventree_barcode.py:38 msgid "Short barcodes (space optimized)" @@ -7299,308 +7755,316 @@ msgstr "Códigos de barras curtos (otimização de espaço)" #: plugin/builtin/barcodes/inventree_barcode.py:43 msgid "Short Barcode Prefix" -msgstr "" +msgstr "Prefixo de código de barras curto" #: plugin/builtin/barcodes/inventree_barcode.py:45 msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" -msgstr "" +msgstr "Personalize o prefixo usado para códigos de barras curtos; pode ser útil em ambientes com várias instâncias do InvenTree" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" -msgstr "" +msgstr "Criar produções automaticamente" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" -msgstr "" +msgstr "Criar pedidos de produção automaticamente para montagens" #: plugin/builtin/events/auto_issue_orders.py:17 msgid "Auto Issue Orders" -msgstr "" +msgstr "Emitir pedidos automaticamente" #: plugin/builtin/events/auto_issue_orders.py:20 msgid "Automatically issue orders on the assigned target date" -msgstr "" +msgstr "Emitir pedidos automaticamente na data prevista atribuída" #: plugin/builtin/events/auto_issue_orders.py:30 msgid "Auto Issue Build Orders" -msgstr "" +msgstr "Emitir pedidos de produção automaticamente" #: plugin/builtin/events/auto_issue_orders.py:32 msgid "Automatically issue build orders on the assigned target date" -msgstr "" +msgstr "Emitir pedidos de produção automaticamente na data prevista atribuída" #: plugin/builtin/events/auto_issue_orders.py:38 msgid "Auto Issue Purchase Orders" -msgstr "" +msgstr "Emitir pedidos de compra automaticamente" #: plugin/builtin/events/auto_issue_orders.py:40 msgid "Automatically issue purchase orders on the assigned target date" -msgstr "" +msgstr "Emitir pedidos de compra automaticamente na data prevista atribuída" #: plugin/builtin/events/auto_issue_orders.py:46 msgid "Auto Issue Sales Orders" -msgstr "" +msgstr "Emitir pedidos de venda automaticamente" #: plugin/builtin/events/auto_issue_orders.py:48 msgid "Automatically issue sales orders on the assigned target date" -msgstr "" +msgstr "Emitir pedidos de venda automaticamente na data prevista atribuída" #: plugin/builtin/events/auto_issue_orders.py:54 msgid "Auto Issue Return Orders" -msgstr "" +msgstr "Emitir pedidos de devolução automaticamente" #: plugin/builtin/events/auto_issue_orders.py:56 msgid "Automatically issue return orders on the assigned target date" -msgstr "" +msgstr "Emitir pedidos de devolução automaticamente na data prevista atribuída" #: plugin/builtin/events/auto_issue_orders.py:62 msgid "Issue Backdated Orders" -msgstr "" +msgstr "Emitir pedidos retroativos" #: plugin/builtin/events/auto_issue_orders.py:63 msgid "Automatically issue orders that are backdated" -msgstr "" +msgstr "Emitir automaticamente pedidos com data retroativa" #: plugin/builtin/exporter/bom_exporter.py:22 msgid "Levels" -msgstr "" +msgstr "Níveis" #: plugin/builtin/exporter/bom_exporter.py:24 msgid "Number of levels to export - set to zero to export all BOM levels" -msgstr "" +msgstr "Número de níveis a exportar - defina como zero para exportar todos os níveis da lista de materiais" #: plugin/builtin/exporter/bom_exporter.py:31 #: plugin/builtin/exporter/bom_exporter.py:118 msgid "Total Quantity" -msgstr "" +msgstr "Quantidade total" #: plugin/builtin/exporter/bom_exporter.py:32 msgid "Include total quantity of each part in the BOM" -msgstr "" +msgstr "Incluir a quantidade total de cada peça na lista de materiais" #: plugin/builtin/exporter/bom_exporter.py:36 msgid "Stock Data" -msgstr "" +msgstr "Dados de estoque" #: plugin/builtin/exporter/bom_exporter.py:36 msgid "Include part stock data" -msgstr "" +msgstr "Incluir dados de estoque da peça" #: plugin/builtin/exporter/bom_exporter.py:40 #: plugin/builtin/exporter/stocktake_exporter.py:20 msgid "Pricing Data" -msgstr "" +msgstr "Dados de preço" #: plugin/builtin/exporter/bom_exporter.py:40 #: plugin/builtin/exporter/stocktake_exporter.py:20 msgid "Include part pricing data" -msgstr "" +msgstr "Incluir dados de preço da peça" #: plugin/builtin/exporter/bom_exporter.py:44 msgid "Supplier Data" -msgstr "" +msgstr "Dados do fornecedor" #: plugin/builtin/exporter/bom_exporter.py:44 msgid "Include supplier data" -msgstr "" +msgstr "Incluir dados do fornecedor" #: plugin/builtin/exporter/bom_exporter.py:49 msgid "Manufacturer Data" -msgstr "" +msgstr "Dados do fabricante" #: plugin/builtin/exporter/bom_exporter.py:50 msgid "Include manufacturer data" -msgstr "" +msgstr "Incluir dados do fabricante" #: plugin/builtin/exporter/bom_exporter.py:55 msgid "Substitute Data" -msgstr "" +msgstr "Dados de substitutos" #: plugin/builtin/exporter/bom_exporter.py:56 msgid "Include substitute part data" -msgstr "" +msgstr "Incluir dados das peças substitutas" #: plugin/builtin/exporter/bom_exporter.py:61 msgid "Parameter Data" -msgstr "" +msgstr "Dados de parâmetro" #: plugin/builtin/exporter/bom_exporter.py:62 msgid "Include part parameter data" -msgstr "" +msgstr "Incluir dados de parâmetro da peça" #: plugin/builtin/exporter/bom_exporter.py:71 msgid "Multi-Level BOM Exporter" -msgstr "" +msgstr "Exportador de lista de materiais multinível" #: plugin/builtin/exporter/bom_exporter.py:72 msgid "Provides support for exporting multi-level BOMs" -msgstr "" +msgstr "Fornece suporte para exportar listas de materiais multinível" #: plugin/builtin/exporter/bom_exporter.py:114 msgid "BOM Level" -msgstr "" +msgstr "Nível da lista de materiais" #: plugin/builtin/exporter/bom_exporter.py:124 #, python-brace-format msgid "Substitute {n}" -msgstr "" +msgstr "Substituto {n}" #: plugin/builtin/exporter/bom_exporter.py:130 #, python-brace-format msgid "Supplier {n}" -msgstr "" +msgstr "Fornecedor {n}" #: plugin/builtin/exporter/bom_exporter.py:131 #, python-brace-format msgid "Supplier {n} SKU" -msgstr "" +msgstr "SKU do fornecedor {n}" #: plugin/builtin/exporter/bom_exporter.py:132 #, python-brace-format msgid "Supplier {n} MPN" -msgstr "" +msgstr "MPN do fornecedor {n}" #: plugin/builtin/exporter/bom_exporter.py:138 #, python-brace-format msgid "Manufacturer {n}" -msgstr "" +msgstr "Fabricante {n}" #: plugin/builtin/exporter/bom_exporter.py:139 #, python-brace-format msgid "Manufacturer {n} MPN" -msgstr "" +msgstr "MPN do fabricante {n}" #: plugin/builtin/exporter/inventree_exporter.py:14 msgid "InvenTree Generic Exporter" -msgstr "" +msgstr "Exportador genérico do InvenTree" #: plugin/builtin/exporter/inventree_exporter.py:15 msgid "Provides support for exporting data from InvenTree" -msgstr "" +msgstr "Fornece suporte para exportar dados do InvenTree" #: plugin/builtin/exporter/parameter_exporter.py:16 msgid "Exclude Inactive" -msgstr "" +msgstr "Excluir inativos" #: plugin/builtin/exporter/parameter_exporter.py:17 msgid "Exclude parameters which are inactive" -msgstr "" +msgstr "Excluir parâmetros inativos" #: plugin/builtin/exporter/parameter_exporter.py:29 msgid "Parameter Exporter" -msgstr "" +msgstr "Exportador de parâmetros" #: plugin/builtin/exporter/parameter_exporter.py:30 msgid "Exporter for model parameter data" -msgstr "" +msgstr "Exportador de dados de parâmetro do modelo" #: plugin/builtin/exporter/stocktake_exporter.py:25 msgid "Include External Stock" -msgstr "" +msgstr "Incluir estoque externo" #: plugin/builtin/exporter/stocktake_exporter.py:26 msgid "Include external stock in the stocktake data" -msgstr "" +msgstr "Incluir estoque externo nos dados de inventário" #: plugin/builtin/exporter/stocktake_exporter.py:31 msgid "Include Variant Items" -msgstr "" +msgstr "Incluir itens de variante" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "" +msgid "Include part variant stock in stocktake data" +msgstr "Incluir estoque de variantes da peça nos dados de inventário" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "Excluir itens com estoque zero" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "Excluir peças com estoque zero do conjunto de dados exportado" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" -msgstr "" +msgstr "Exportador de inventário de peças" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" -msgstr "" +msgstr "Exportador de dados de inventário de peças" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" -msgstr "" +msgstr "Custo unitário mínimo" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" -msgstr "" +msgstr "Custo unitário máximo" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" -msgstr "" +msgstr "Custo total mínimo" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" -msgstr "" +msgstr "Custo total máximo" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" -msgstr "" +msgstr "Notificações da interface do InvenTree" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" -msgstr "" +msgstr "Métodos integrados de notificação da interface" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" -msgstr "" +msgstr "Notificações por e-mail do InvenTree" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" -msgstr "" +msgstr "Métodos integrados de notificação por e-mail" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" -msgstr "" +msgstr "Permitir notificações por e-mail" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" -msgstr "" +msgstr "Permitir o envio de notificações por e-mail para este usuário" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" -msgstr "" - -#: plugin/builtin/integration/core_notifications.py:126 -msgid "Integrated Slack notification methods" -msgstr "" - -#: plugin/builtin/integration/core_notifications.py:131 -msgid "Slack incoming webhook URL" -msgstr "" +msgstr "Notificações do Slack no InvenTree" #: plugin/builtin/integration/core_notifications.py:132 -msgid "URL that is used to send messages to a slack channel" -msgstr "" +msgid "Integrated Slack notification methods" +msgstr "Métodos integrados de notificação do Slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:137 +msgid "Slack incoming webhook URL" +msgstr "URL do webhook de entrada do Slack" + +#: plugin/builtin/integration/core_notifications.py:138 +msgid "URL that is used to send messages to a slack channel" +msgstr "URL usada para enviar mensagens a um canal do Slack" + +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Abrir link" #: plugin/builtin/integration/currency_exchange.py:22 msgid "InvenTree Currency Exchange" -msgstr "" +msgstr "Câmbio de moedas do InvenTree" #: plugin/builtin/integration/currency_exchange.py:23 msgid "Default currency exchange integration" -msgstr "" +msgstr "Integração padrão de câmbio de moedas" #: plugin/builtin/integration/machine_types.py:15 msgid "InvenTree Machines" -msgstr "" +msgstr "Máquinas do InvenTree" #: plugin/builtin/integration/machine_types.py:16 msgid "Built-in machine types for InvenTree" -msgstr "" +msgstr "Tipos de máquina integrados do InvenTree" #: plugin/builtin/integration/part_notifications.py:20 msgid "Part Notifications" -msgstr "" +msgstr "Notificações de peças" #: plugin/builtin/integration/part_notifications.py:22 msgid "Notify users about part changes" -msgstr "" +msgstr "Notificar usuários sobre alterações em peças" #: plugin/builtin/integration/part_notifications.py:27 msgid "Send notifications" @@ -7608,708 +8072,724 @@ msgstr "Enviar notificações" #: plugin/builtin/integration/part_notifications.py:28 msgid "Send notifications for part changes to subscribed users" -msgstr "" +msgstr "Enviar notificações de alterações em peças aos usuários inscritos" #: plugin/builtin/integration/part_notifications.py:45 msgid "Changed part notification" -msgstr "" +msgstr "Notificação de peça alterada" #: plugin/builtin/integration/part_notifications.py:55 #, python-brace-format msgid "The part `{part.name}` has been triggered with a `{part_action}` event" -msgstr "" +msgstr "A peça `{part.name}` foi acionada com um evento `{part_action}`" #: plugin/builtin/labels/inventree_label.py:24 msgid "InvenTree PDF label printer" -msgstr "" +msgstr "Impressora de etiquetas PDF do InvenTree" #: plugin/builtin/labels/inventree_label.py:25 msgid "Provides native support for printing PDF labels" -msgstr "" - -#: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 -msgid "Debug mode" -msgstr "" +msgstr "Fornece suporte nativo para impressão de etiquetas em PDF" #: plugin/builtin/labels/inventree_label.py:34 #: plugin/builtin/labels/label_sheet.py:79 +msgid "Debug mode" +msgstr "Modo de depuração" + +#: plugin/builtin/labels/inventree_label.py:34 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" -msgstr "" +msgstr "Habilitar o modo de depuração - retorna HTML bruto em vez de PDF" #: plugin/builtin/labels/inventree_machine.py:61 msgid "InvenTree machine label printer" -msgstr "" +msgstr "Impressora de etiquetas por máquina do InvenTree" #: plugin/builtin/labels/inventree_machine.py:62 msgid "Provides support for printing using a machine" -msgstr "" +msgstr "Fornece suporte para impressão usando uma máquina" #: plugin/builtin/labels/inventree_machine.py:164 msgid "last used" -msgstr "" +msgstr "usado por último" #: plugin/builtin/labels/inventree_machine.py:181 msgid "Options" msgstr "Opções" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" -msgstr "" - -#: plugin/builtin/labels/label_sheet.py:35 -msgid "Skip Labels" -msgstr "Pular Etiquetas" +msgstr "Tamanho da página para a folha de etiquetas" #: plugin/builtin/labels/label_sheet.py:36 -msgid "Skip this number of labels when printing label sheets" -msgstr "" +msgid "Skip Labels" +msgstr "Pular etiquetas" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:37 +msgid "Skip this number of labels when printing label sheets" +msgstr "Pular este número de etiquetas ao imprimir folhas de etiquetas" + +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Margem" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" -msgstr "" +msgstr "Imprimir uma borda ao redor de cada etiqueta" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Paisagem" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" -msgstr "" - -#: plugin/builtin/labels/label_sheet.py:55 -msgid "Page Margin" -msgstr "Margem da Página" +msgstr "Imprimir a folha de etiquetas no modo paisagem" #: plugin/builtin/labels/label_sheet.py:56 -msgid "Margin around the page in mm" -msgstr "" +msgid "Page Margin" +msgstr "Margem da página" -#: plugin/builtin/labels/label_sheet.py:69 -msgid "InvenTree Label Sheet Printer" -msgstr "" +#: plugin/builtin/labels/label_sheet.py:57 +msgid "Margin around the page in mm" +msgstr "Margem ao redor da página em mm" #: plugin/builtin/labels/label_sheet.py:70 +msgid "InvenTree Label Sheet Printer" +msgstr "Impressora de folhas de etiquetas do InvenTree" + +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" -msgstr "" +msgstr "Organiza várias etiquetas em uma única folha" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" -msgstr "" +msgstr "A etiqueta é grande demais para o tamanho da página" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" -msgstr "" +msgstr "Nenhuma etiqueta foi gerada" #: plugin/builtin/suppliers/digikey.py:17 msgid "Supplier Integration - DigiKey" -msgstr "" +msgstr "Integração de fornecedor - DigiKey" #: plugin/builtin/suppliers/digikey.py:18 msgid "Provides support for scanning DigiKey barcodes" -msgstr "" +msgstr "Fornece suporte para ler códigos de barras da DigiKey" #: plugin/builtin/suppliers/digikey.py:27 msgid "The Supplier which acts as 'DigiKey'" -msgstr "" +msgstr "O fornecedor que atua como 'DigiKey'" #: plugin/builtin/suppliers/lcsc.py:19 msgid "Supplier Integration - LCSC" -msgstr "" +msgstr "Integração de fornecedor - LCSC" #: plugin/builtin/suppliers/lcsc.py:20 msgid "Provides support for scanning LCSC barcodes" -msgstr "" +msgstr "Fornece suporte para ler códigos de barras da LCSC" #: plugin/builtin/suppliers/lcsc.py:28 msgid "The Supplier which acts as 'LCSC'" -msgstr "" +msgstr "O fornecedor que atua como 'LCSC'" #: plugin/builtin/suppliers/mouser.py:17 msgid "Supplier Integration - Mouser" -msgstr "" +msgstr "Integração de fornecedor - Mouser" #: plugin/builtin/suppliers/mouser.py:18 msgid "Provides support for scanning Mouser barcodes" -msgstr "" +msgstr "Fornece suporte para ler códigos de barras da Mouser" #: plugin/builtin/suppliers/mouser.py:26 msgid "The Supplier which acts as 'Mouser'" -msgstr "" +msgstr "O fornecedor que atua como 'Mouser'" #: plugin/builtin/suppliers/tme.py:19 msgid "Supplier Integration - TME" -msgstr "" +msgstr "Integração de fornecedor - TME" #: plugin/builtin/suppliers/tme.py:20 msgid "Provides support for scanning TME barcodes" -msgstr "" +msgstr "Fornece suporte para ler códigos de barras da TME" #: plugin/builtin/suppliers/tme.py:28 msgid "The Supplier which acts as 'TME'" -msgstr "" +msgstr "O fornecedor que atua como 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "O Pip não está instalado no ambiente atual" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" -msgstr "" +msgstr "Apenas contas de superusuário podem administrar plugins" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" -msgstr "" +msgstr "A instalação de plugins está desabilitada" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "URL inválida e nenhum nome de pacote fornecido" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" -msgstr "" +msgstr "Nenhum nome de pacote ou URL fornecido para instalação" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" -msgstr "" +msgstr "Caracteres inválidos no nome do pacote ou URL" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" -msgstr "" +msgstr "Plugin instalado com sucesso" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" -msgstr "" +msgstr "Plugin instalado em {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" -msgstr "" +msgstr "O plugin não foi encontrado no registro" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" -msgstr "" +msgstr "O plugin não é um plugin empacotado" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" -msgstr "" +msgstr "Nome do pacote do plugin não encontrado" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" -msgstr "" - -#: plugin/installer.py:347 -msgid "Plugin uninstalling is disabled" -msgstr "" +msgstr "Apenas usuários da equipe podem administrar plugins" #: plugin/installer.py:351 +msgid "Plugin uninstalling is disabled" +msgstr "A desinstalação de plugins está desabilitada" + +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" -msgstr "" +msgstr "O plugin não pode ser desinstalado porque está ativo no momento" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" -msgstr "" +msgstr "O plugin não pode ser desinstalado porque é obrigatório" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" -msgstr "" - -#: plugin/installer.py:367 -msgid "Plugin cannot be uninstalled as it is a built-in plugin" -msgstr "" +msgstr "O plugin não pode ser desinstalado porque é um plugin de exemplo" #: plugin/installer.py:371 +msgid "Plugin cannot be uninstalled as it is a built-in plugin" +msgstr "O plugin não pode ser desinstalado porque é um plugin integrado" + +#: plugin/installer.py:375 msgid "Plugin is not installed" -msgstr "" +msgstr "O plugin não está instalado" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" -msgstr "" +msgstr "Instalação do plugin não encontrada" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" -msgstr "" +msgstr "Plugin desinstalado com sucesso" #: plugin/models.py:39 msgid "Plugin Configuration" -msgstr "" +msgstr "Configuração do plugin" #: plugin/models.py:40 msgid "Plugin Configurations" -msgstr "" +msgstr "Configurações do plugin" #: plugin/models.py:47 msgid "Key of plugin" -msgstr "" +msgstr "Chave do plugin" #: plugin/models.py:55 msgid "Name of the plugin" -msgstr "" +msgstr "Nome do plugin" #: plugin/models.py:62 plugin/serializers.py:119 msgid "Package Name" -msgstr "" +msgstr "Nome do pacote" #: plugin/models.py:64 msgid "Name of the installed package, if the plugin was installed via PIP" -msgstr "" +msgstr "Nome do pacote instalado, se o plugin foi instalado via PIP" #: plugin/models.py:69 msgid "Is the plugin active" -msgstr "" +msgstr "O plugin está ativo" #: plugin/models.py:176 msgid "Sample plugin" -msgstr "" +msgstr "Plugin de exemplo" #: plugin/models.py:184 msgid "Builtin Plugin" -msgstr "" +msgstr "Plugin integrado" #: plugin/models.py:192 msgid "Mandatory Plugin" -msgstr "" +msgstr "Plugin obrigatório" #: plugin/models.py:210 msgid "Package Plugin" -msgstr "" +msgstr "Plugin empacotado" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" -msgstr "" +msgstr "Plugin" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" -msgstr "" +msgstr "Nenhum autor encontrado" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" -msgstr "" +msgstr "O plugin '{p}' não é compatível com a versão atual do InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" -msgstr "" +msgstr "O plugin requer pelo menos a versão {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" -msgstr "" +msgstr "O plugin requer no máximo a versão {v}" #: plugin/samples/integration/sample.py:52 msgid "User Setting 1" -msgstr "Configurações de Usuário 1" +msgstr "Configurações de usuário 1" #: plugin/samples/integration/sample.py:53 msgid "A user setting that can be changed by the user" -msgstr "" +msgstr "Uma configuração de usuário que pode ser alterada pelo usuário" #: plugin/samples/integration/sample.py:57 msgid "User Setting 2" -msgstr "Configurações de Usuário 2" +msgstr "Configurações de usuário 2" #: plugin/samples/integration/sample.py:58 msgid "Another user setting" -msgstr "" +msgstr "Outra configuração de usuário" #: plugin/samples/integration/sample.py:63 msgid "User Setting 3" -msgstr "Configurações de Usuário 3" +msgstr "Configurações de usuário 3" #: plugin/samples/integration/sample.py:64 msgid "A user setting with choices" -msgstr "" +msgstr "Uma configuração de usuário com opções" #: plugin/samples/integration/sample.py:72 msgid "Enable PO" -msgstr "" +msgstr "Habilitar pedido de compra" #: plugin/samples/integration/sample.py:73 msgid "Enable PO functionality in InvenTree interface" -msgstr "" +msgstr "Habilitar a funcionalidade de pedido de compra na interface do InvenTree" #: plugin/samples/integration/sample.py:78 msgid "API Key" -msgstr "" +msgstr "Chave de API" #: plugin/samples/integration/sample.py:79 msgid "Key required for accessing external API" -msgstr "" +msgstr "Chave necessária para acessar a API externa" #: plugin/samples/integration/sample.py:83 msgid "Numerical" -msgstr "" +msgstr "Numérico" #: plugin/samples/integration/sample.py:84 msgid "A numerical setting" -msgstr "" +msgstr "Uma configuração numérica" #: plugin/samples/integration/sample.py:90 msgid "Choice Setting" -msgstr "" +msgstr "Configuração de escolha" #: plugin/samples/integration/sample.py:91 msgid "A setting with multiple choices" -msgstr "" +msgstr "Uma configuração com várias opções" #: plugin/samples/integration/sample_currency_exchange.py:15 msgid "Sample currency exchange plugin" -msgstr "" +msgstr "Plugin de exemplo de câmbio de moedas" #: plugin/samples/integration/sample_currency_exchange.py:18 msgid "InvenTree Contributors" -msgstr "" +msgstr "Contribuidores do InvenTree" #: plugin/samples/integration/user_interface_sample.py:27 msgid "Enable Part Panels" -msgstr "" +msgstr "Habilitar painéis de peça" #: plugin/samples/integration/user_interface_sample.py:28 msgid "Enable custom panels for Part views" -msgstr "" +msgstr "Habilitar painéis personalizados para visualizações de peça" #: plugin/samples/integration/user_interface_sample.py:33 msgid "Enable Purchase Order Panels" -msgstr "" +msgstr "Habilitar painéis de pedido de compra" #: plugin/samples/integration/user_interface_sample.py:34 msgid "Enable custom panels for Purchase Order views" -msgstr "" +msgstr "Habilitar painéis personalizados para visualizações de pedido de compra" #: plugin/samples/integration/user_interface_sample.py:39 msgid "Enable Broken Panels" -msgstr "" +msgstr "Habilitar painéis quebrados" #: plugin/samples/integration/user_interface_sample.py:40 msgid "Enable broken panels for testing" -msgstr "" +msgstr "Habilitar painéis quebrados para teste" #: plugin/samples/integration/user_interface_sample.py:45 msgid "Enable Dynamic Panel" -msgstr "" +msgstr "Habilitar painel dinâmico" #: plugin/samples/integration/user_interface_sample.py:46 msgid "Enable dynamic panels for testing" -msgstr "" +msgstr "Habilitar painéis dinâmicos para teste" #: plugin/samples/integration/user_interface_sample.py:114 msgid "Part Panel" -msgstr "" +msgstr "Painel de peça" #: plugin/samples/integration/user_interface_sample.py:149 msgid "Broken Dashboard Item" -msgstr "" +msgstr "Item de painel quebrado" #: plugin/samples/integration/user_interface_sample.py:151 msgid "This is a broken dashboard item - it will not render!" -msgstr "" +msgstr "Este é um item de painel quebrado - ele não será renderizado!" #: plugin/samples/integration/user_interface_sample.py:157 msgid "Sample Dashboard Item" -msgstr "" +msgstr "Item de painel de exemplo" #: plugin/samples/integration/user_interface_sample.py:159 msgid "This is a sample dashboard item. It renders a simple string of HTML content." -msgstr "" +msgstr "Este é um item de painel de exemplo. Ele renderiza uma string simples de conteúdo HTML." #: plugin/samples/integration/user_interface_sample.py:165 msgid "Context Dashboard Item" -msgstr "" +msgstr "Item de painel de contexto" #: plugin/samples/integration/user_interface_sample.py:179 msgid "Admin Dashboard Item" -msgstr "" +msgstr "Item de painel de administrador" #: plugin/samples/integration/user_interface_sample.py:180 msgid "This is an admin-only dashboard item." -msgstr "" +msgstr "Este é um item de painel exclusivo para administradores." #: plugin/serializers.py:86 msgid "Source File" -msgstr "" +msgstr "Arquivo de origem" #: plugin/serializers.py:87 msgid "Path to the source file for admin integration" -msgstr "" +msgstr "Caminho para o arquivo de origem da integração de administração" #: plugin/serializers.py:94 msgid "Optional context data for the admin integration" -msgstr "" +msgstr "Dados de contexto opcionais para a integração de administração" #: plugin/serializers.py:110 msgid "Source URL" -msgstr "" +msgstr "URL de origem" #: plugin/serializers.py:112 msgid "Source for the package - this can be a custom registry or a VCS path" -msgstr "" +msgstr "Origem do pacote - pode ser um registro personalizado ou um caminho VCS" #: plugin/serializers.py:121 msgid "Name for the Plugin Package - can also contain a version indicator" -msgstr "" +msgstr "Nome do pacote do plugin - também pode conter um indicador de versão" #: plugin/serializers.py:128 msgid "Version" -msgstr "" +msgstr "Versão" #: plugin/serializers.py:130 msgid "Version specifier for the plugin. Leave blank for latest version." -msgstr "" +msgstr "Especificador de versão do plugin. Deixe em branco para a versão mais recente." #: plugin/serializers.py:135 msgid "Confirm plugin installation" -msgstr "" +msgstr "Confirmar instalação do plugin" #: plugin/serializers.py:137 msgid "This will install this plugin now into the current instance. The instance will go into maintenance." -msgstr "" +msgstr "Isso instalará este plugin agora na instância atual. A instância entrará em manutenção." #: plugin/serializers.py:150 msgid "Installation not confirmed" -msgstr "" +msgstr "Instalação não confirmada" #: plugin/serializers.py:152 msgid "Either packagename or URL must be provided" -msgstr "" +msgstr "É necessário fornecer o nome do pacote ou a URL" #: plugin/serializers.py:191 msgid "Full reload" -msgstr "" +msgstr "Recarga completa" #: plugin/serializers.py:192 msgid "Perform a full reload of the plugin registry" -msgstr "" +msgstr "Realizar uma recarga completa do registro de plugins" #: plugin/serializers.py:198 msgid "Force reload" -msgstr "" +msgstr "Forçar recarga" #: plugin/serializers.py:200 msgid "Force a reload of the plugin registry, even if it is already loaded" -msgstr "" +msgstr "Forçar uma recarga do registro de plugins, mesmo que já esteja carregado" #: plugin/serializers.py:207 msgid "Collect plugins" -msgstr "" +msgstr "Coletar plugins" #: plugin/serializers.py:208 msgid "Collect plugins and add them to the registry" -msgstr "" +msgstr "Coletar plugins e adicioná-los ao registro" #: plugin/serializers.py:236 msgid "Activate Plugin" -msgstr "" +msgstr "Ativar plugin" #: plugin/serializers.py:237 msgid "Activate this plugin" -msgstr "" +msgstr "Ativar este plugin" #: plugin/serializers.py:246 msgid "Mandatory plugin cannot be deactivated" -msgstr "" +msgstr "Um plugin obrigatório não pode ser desativado" #: plugin/serializers.py:264 msgid "Delete configuration" -msgstr "" +msgstr "Excluir configuração" #: plugin/serializers.py:265 msgid "Delete the plugin configuration from the database" -msgstr "" +msgstr "Excluir a configuração do plugin do banco de dados" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "Indica se a configuração é substituída pela configuração" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" -msgstr "" +msgstr "O usuário para o qual esta configuração se aplica" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" -msgstr "" +msgstr "Itens" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" -msgstr "" +msgstr "Plugin não encontrado" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" -msgstr "" +msgstr "O plugin não suporta impressão de etiquetas" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "Você não tem permissão para ver este tipo de modelo" + +#: report/api.py:174 msgid "Invalid label dimensions" -msgstr "" +msgstr "Dimensões de etiqueta inválidas" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" -msgstr "" - -#: report/helpers.py:43 -msgid "A4" -msgstr "" +msgstr "Nenhum item válido fornecido ao modelo" #: report/helpers.py:44 -msgid "A3" -msgstr "" +msgid "A4" +msgstr "A4" #: report/helpers.py:45 -msgid "Legal" -msgstr "" +msgid "A3" +msgstr "A3" #: report/helpers.py:46 +msgid "Legal" +msgstr "Ofício" + +#: report/helpers.py:47 msgid "Letter" -msgstr "" +msgstr "Carta" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" -msgstr "" +msgstr "Já existe um arquivo de modelo com este nome" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" -msgstr "" +msgstr "Nome do modelo" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" -msgstr "" +msgstr "Descrição do modelo" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" -msgstr "" +msgstr "Número da revisão (incrementa automaticamente)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" -msgstr "" +msgstr "Anexar ao modelo ao imprimir" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" -msgstr "" +msgstr "Salvar a saída do relatório como anexo na instância do modelo vinculado ao imprimir" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" -msgstr "" - -#: report/models.py:287 -msgid "Pattern for generating filenames" -msgstr "" +msgstr "Padrão de nome de arquivo" #: report/models.py:292 +msgid "Pattern for generating filenames" +msgstr "Padrão para gerar nomes de arquivo" + +#: report/models.py:297 msgid "Template is enabled" -msgstr "" +msgstr "O modelo está habilitado" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" -msgstr "" +msgstr "Tipo de modelo de destino para o modelo" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtros" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" -msgstr "" +msgstr "Filtros de consulta do modelo (lista separada por vírgula de pares chave=valor)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" -msgstr "Arquivo Modelo" +msgstr "Arquivo modelo" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" -msgstr "" - -#: report/models.py:393 -msgid "Render report in landscape orientation" -msgstr "" +msgstr "Tamanho da página para relatórios PDF" #: report/models.py:398 +msgid "Render report in landscape orientation" +msgstr "Renderizar o relatório na orientação paisagem" + +#: report/models.py:403 msgid "Merge" msgstr "Mesclar" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" -msgstr "" +msgstr "Renderizar um único relatório para os itens selecionados" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" -msgstr "" +msgstr "Relatório gerado a partir do modelo {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" -msgstr "" +msgstr "Erro de sintaxe no modelo" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" -msgstr "" +msgstr "Erro ao renderizar o relatório" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" -msgstr "" +msgstr "Erro ao gerar o relatório" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" -msgstr "" +msgstr "Erro ao mesclar as saídas do relatório" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Largura [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" -msgstr "Largura da Etiqueta, em mm" +msgstr "Largura da etiqueta, em mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Altura [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" -msgstr "Altura da Etiqueta, em mm" +msgstr "Altura da etiqueta, em mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" -msgstr "" +msgstr "Erro ao imprimir etiquetas" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" -msgstr "" +msgstr "Snippet" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" -msgstr "" - -#: report/models.py:855 -msgid "Snippet file description" -msgstr "" +msgstr "Arquivo de snippet do relatório" #: report/models.py:873 +msgid "Snippet file description" +msgstr "Descrição do arquivo de snippet" + +#: report/models.py:891 msgid "Asset" -msgstr "" +msgstr "Asset" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" -msgstr "" +msgstr "Arquivo de asset do relatório" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" -msgstr "" +msgstr "Descrição do arquivo de asset" #: report/serializers.py:37 msgid "User must be authenticated to save report templates" -msgstr "" +msgstr "O usuário deve estar autenticado para salvar modelos de relatório" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" -msgstr "" +msgstr "Selecionar modelo de relatório" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" -msgstr "" - -#: report/serializers.py:159 -msgid "Select label template" -msgstr "" +msgstr "Lista de chaves primárias dos itens a incluir no relatório" #: report/serializers.py:167 -msgid "Printing Plugin" -msgstr "" +msgid "Select label template" +msgstr "Selecionar modelo de etiqueta" -#: report/serializers.py:168 +#: report/serializers.py:175 +msgid "Printing Plugin" +msgstr "Plugin de impressão" + +#: report/serializers.py:176 msgid "Select plugin to use for label printing" -msgstr "" +msgstr "Selecionar o plugin a usar para impressão de etiquetas" #: report/templates/label/part_label.html:31 #: report/templates/label/stockitem_qr.html:21 @@ -8324,11 +8804,11 @@ msgstr "Código QR" #: report/templates/report/inventree_bill_of_materials_report.html:100 msgid "Bill of Materials" -msgstr "" +msgstr "Lista de materiais" #: report/templates/report/inventree_bill_of_materials_report.html:133 msgid "Materials needed" -msgstr "" +msgstr "Materiais necessários" #: report/templates/report/inventree_build_order_report.html:98 #: report/templates/report/inventree_purchase_order_report.html:47 @@ -8338,16 +8818,13 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" -msgstr "" - -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" +msgstr "Imagem da peça" #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" -msgstr "" +msgstr "Necessário para" #: report/templates/report/inventree_build_order_report.html:152 msgid "Issued By" @@ -8355,22 +8832,22 @@ msgstr "Emitido por" #: report/templates/report/inventree_purchase_order_report.html:15 msgid "Supplier was deleted" -msgstr "" +msgstr "O fornecedor foi excluído" #: report/templates/report/inventree_purchase_order_report.html:22 msgid "Order Details" -msgstr "" +msgstr "Detalhes do pedido" #: report/templates/report/inventree_purchase_order_report.html:37 #: report/templates/report/inventree_sales_order_report.html:30 msgid "Unit Price" -msgstr "" +msgstr "Preço unitário" #: report/templates/report/inventree_purchase_order_report.html:62 #: report/templates/report/inventree_return_order_report.html:48 #: report/templates/report/inventree_sales_order_report.html:55 msgid "Extra Line Items" -msgstr "" +msgstr "Itens de linha extras" #: report/templates/report/inventree_purchase_order_report.html:79 #: report/templates/report/inventree_sales_order_report.html:72 @@ -8380,39 +8857,39 @@ msgstr "Total" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" -msgstr "" +msgstr "Número de série" #: report/templates/report/inventree_sales_order_shipment_report.html:23 msgid "Allocations" -msgstr "" +msgstr "Alocações" #: report/templates/report/inventree_sales_order_shipment_report.html:47 #: templates/email/stale_stock_notification.html:20 msgid "Batch" -msgstr "" +msgstr "Lote" #: report/templates/report/inventree_stock_location_report.html:97 msgid "Stock location items" -msgstr "" +msgstr "Itens do local de estoque" #: report/templates/report/inventree_stock_report_merge.html:21 #: report/templates/report/inventree_test_report.html:21 msgid "Stock Item Test Report" -msgstr "" +msgstr "Relatório de teste do item de estoque" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" -msgstr "" +msgstr "Itens instalados" #: report/templates/report/inventree_stock_report_merge.html:111 #: report/templates/report/inventree_test_report.html:167 msgid "Serial" -msgstr "" +msgstr "Série" #: report/templates/report/inventree_test_report.html:97 msgid "Test Results" @@ -8432,818 +8909,930 @@ msgstr "Reprovado" #: report/templates/report/inventree_test_report.html:138 msgid "No result (required)" -msgstr "" +msgstr "Sem resultado (obrigatório)" #: report/templates/report/inventree_test_report.html:140 msgid "No result" -msgstr "" +msgstr "Sem resultado" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "Transferido" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" -msgstr "" +msgstr "Caminho de arquivo de mídia inválido" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" -msgstr "" +msgstr "Caminho de arquivo estático inválido" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" -msgstr "" +msgstr "Arquivo de asset não encontrado" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" -msgstr "" +msgstr "Arquivo de imagem não encontrado" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" -msgstr "" +msgstr "Nenhum arquivo de imagem especificado" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" -msgstr "" +msgstr "A tag part_image requer uma instância de Part" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" -msgstr "" +msgstr "A tag company_image requer uma instância de Company" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" -msgstr "" +msgstr "Filtrar por profundidade do local" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" -msgstr "" +msgstr "Filtrar por locais de nível superior" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" -msgstr "" +msgstr "Incluir sublocais nos resultados filtrados" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" -msgstr "" +msgstr "Local pai" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" -msgstr "" +msgstr "Filtrar por local pai" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" -msgstr "" +msgstr "Nome da peça (não diferencia maiúsculas)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" -msgstr "" +msgstr "Nome da peça contém (não diferencia maiúsculas)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" -msgstr "" +msgstr "Nome da peça (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" -msgstr "" +msgstr "IPN da peça (não diferencia maiúsculas)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" -msgstr "" +msgstr "IPN da peça contém (não diferencia maiúsculas)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" -msgstr "" +msgstr "IPN da peça (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Estoque mínimo" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Estoque máximo" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" -msgstr "" +msgstr "Código de status" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" -msgstr "" +msgstr "Local externo" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" -msgstr "" +msgstr "Consumido por pedido de produção" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" -msgstr "" +msgstr "Instalado em outro item de estoque" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" -msgstr "" +msgstr "Árvore de peças" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" -msgstr "" +msgstr "Atualizado antes de" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" -msgstr "" +msgstr "Atualizado após" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" -msgstr "" +msgstr "Inventário antes de" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" -msgstr "" +msgstr "Inventário após" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "Tem data de inventário" + +#: stock/api.py:1001 msgid "Expiry date before" -msgstr "" +msgstr "Data de validade antes de" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" -msgstr "" +msgstr "Data de validade após" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" -msgstr "" +msgstr "Parado" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" -msgstr "" +msgstr "Locais em cascata" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" -msgstr "" +msgstr "Se verdadeiro, inclui itens nos locais filhos do local informado" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" -msgstr "" +msgstr "Filtrar por ID numérico do local ou o literal 'null'" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" -msgstr "" +msgstr "A quantidade é obrigatória" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" -msgstr "" +msgstr "Uma peça válida deve ser fornecida" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" -msgstr "" +msgstr "A peça de fornecedor informada não existe" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" -msgstr "" +msgstr "A peça de fornecedor tem um tamanho de pacote definido, mas o flag use_pack_size não está ativado" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" -msgstr "" +msgstr "Números de série não podem ser fornecidos para uma peça não rastreável" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" -msgstr "" +msgstr "Incluir instalados" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" -msgstr "" +msgstr "Se verdadeiro, inclui resultados de teste dos itens instalados sob o item de estoque informado" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" -msgstr "" +msgstr "Filtrar por ID numérico do item de estoque" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" -msgstr "" +msgstr "O item de estoque com ID {id} não existe" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" -msgstr "" +msgstr "Incluir variantes da peça" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" -msgstr "" +msgstr "Data após" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" -msgstr "" +msgstr "Data antes de" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" -msgstr "" +msgstr "Tipo de local de estoque" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" -msgstr "" +msgstr "Tipos de local de estoque" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" -msgstr "" +msgstr "Ícone padrão para todos os locais que não têm ícone definido (opcional)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" -msgstr "" +msgstr "Local de estoque" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" -msgstr "" +msgstr "Locais de estoque" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Responsável" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" -msgstr "Selecionar Responsável" +msgstr "Selecionar responsável" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." -msgstr "" +msgstr "Os itens de estoque não podem ser alocados diretamente em locais de estoque estruturais, mas podem ser alocados em locais filhos." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" -msgstr "" +msgstr "Externo" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" -msgstr "" +msgstr "Este é um local de estoque externo" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" -msgstr "" +msgstr "Tipo de local" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" -msgstr "" +msgstr "Tipo de local de estoque deste local" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" -msgstr "" +msgstr "Você não pode tornar este local de estoque estrutural porque alguns itens de estoque já estão alocados nele!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "Estoque mais antigo primeiro (FIFO)" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "Estoque mais recente primeiro (LIFO)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "Menor quantidade primeiro" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "Maior quantidade primeiro" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "Data de validade mais próxima primeiro" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" -msgstr "" +msgstr "Itens de estoque serializados não podem ser excluídos" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" -msgstr "" +msgstr "{field} não existe" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" -msgstr "" +msgstr "A peça deve ser especificada" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" -msgstr "" +msgstr "Os itens de estoque não podem ser alocados em locais de estoque estruturais!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "A edição de números de série não é permitida - este item já recebeu um número de série" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" -msgstr "" +msgstr "Não é possível criar item de estoque para peças virtuais" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" -msgstr "" +msgstr "O tipo de peça ('{self.supplier_part.part}') deve ser {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" -msgstr "" +msgstr "A quantidade deve ser 1 para um item com número de série" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" -msgstr "" +msgstr "O número de série não pode ser definido se a quantidade for maior que 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" -msgstr "" +msgstr "O item não pode pertencer a si mesmo" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" -msgstr "" - -#: stock/models.py:1032 -msgid "Build reference does not point to the same part object" -msgstr "" - -#: stock/models.py:1046 -msgid "Parent Stock Item" -msgstr "" - -#: stock/models.py:1058 -msgid "Base part" -msgstr "" - -#: stock/models.py:1068 -msgid "Select a matching supplier part for this stock item" -msgstr "" - -#: stock/models.py:1080 -msgid "Where is this stock item located?" -msgstr "" - -#: stock/models.py:1088 stock/serializers.py:1682 -msgid "Packaging this stock item is stored in" -msgstr "" - -#: stock/models.py:1094 -msgid "Installed In" -msgstr "" - -#: stock/models.py:1099 -msgid "Is this item installed in another item?" -msgstr "" - -#: stock/models.py:1118 -msgid "Serial number for this item" -msgstr "" - -#: stock/models.py:1135 stock/serializers.py:1667 -msgid "Batch code for this stock item" -msgstr "" +msgstr "O item deve ter uma referência de produção se is_building=True" #: stock/models.py:1140 -msgid "Stock Quantity" -msgstr "" +msgid "Build reference does not point to the same part object" +msgstr "A referência de produção não aponta para o mesmo objeto de peça" -#: stock/models.py:1150 -msgid "Source Build" -msgstr "" +#: stock/models.py:1154 +msgid "Parent Stock Item" +msgstr "Item de estoque pai" -#: stock/models.py:1153 -msgid "Build for this stock item" -msgstr "" - -#: stock/models.py:1160 -msgid "Consumed By" -msgstr "" - -#: stock/models.py:1163 -msgid "Build order which consumed this stock item" -msgstr "" - -#: stock/models.py:1172 -msgid "Source Purchase Order" -msgstr "" +#: stock/models.py:1166 +msgid "Base part" +msgstr "Peça base" #: stock/models.py:1176 +msgid "Select a matching supplier part for this stock item" +msgstr "Selecione uma peça de fornecedor correspondente para este item de estoque" + +#: stock/models.py:1188 +msgid "Where is this stock item located?" +msgstr "Onde este item de estoque está localizado?" + +#: stock/models.py:1196 stock/serializers.py:1936 +msgid "Packaging this stock item is stored in" +msgstr "Embalagem em que este item de estoque é armazenado" + +#: stock/models.py:1202 +msgid "Installed In" +msgstr "Instalado em" + +#: stock/models.py:1207 +msgid "Is this item installed in another item?" +msgstr "Este item está instalado em outro item?" + +#: stock/models.py:1226 +msgid "Serial number for this item" +msgstr "Número de série deste item" + +#: stock/models.py:1243 stock/serializers.py:1921 +msgid "Batch code for this stock item" +msgstr "Código de lote deste item de estoque" + +#: stock/models.py:1248 +msgid "Stock Quantity" +msgstr "Quantidade em estoque" + +#: stock/models.py:1258 +msgid "Source Build" +msgstr "Produção de origem" + +#: stock/models.py:1261 +msgid "Build for this stock item" +msgstr "Produção deste item de estoque" + +#: stock/models.py:1268 +msgid "Consumed By" +msgstr "Consumido por" + +#: stock/models.py:1271 +msgid "Build order which consumed this stock item" +msgstr "Pedido de produção que consumiu este item de estoque" + +#: stock/models.py:1280 +msgid "Source Purchase Order" +msgstr "Pedido de compra de origem" + +#: stock/models.py:1284 msgid "Purchase order for this stock item" -msgstr "" +msgstr "Pedido de compra deste item de estoque" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" -msgstr "" +msgstr "Pedido de venda de destino" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" -msgstr "" +msgstr "Data de validade do item de estoque. O estoque será considerado vencido após esta data" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "Data em que este item de estoque foi criado" + +#: stock/models.py:1326 msgid "Delete on deplete" -msgstr "" +msgstr "Excluir ao esgotar" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" -msgstr "" +msgstr "Excluir este item de estoque quando o estoque se esgotar" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" -msgstr "" +msgstr "Preço de compra unitário no momento da compra" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" -msgstr "" +msgstr "Convertido em peça" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" -msgstr "" +msgstr "A quantidade excede o estoque disponível" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "Valor de quantidade inválido" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "Não é possível atribuir estoque a um local estrutural" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "A quantidade não deve exceder a quantidade de estoque disponível" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "Item de estoque serializado deve ser desmontado por completo" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "Nenhuma linha de BOM fornecida" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "Item de estoque com itens instalados deve ser desmontado por completo" + +#: stock/models.py:2431 msgid "Part is not set as trackable" -msgstr "" +msgstr "A peça não está definida como rastreável" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" -msgstr "" +msgstr "A quantidade deve ser um número inteiro" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" -msgstr "" +msgstr "A quantidade não pode exceder a quantidade de estoque disponível ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" -msgstr "" +msgstr "Os números de série devem ser fornecidos como uma lista" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" -msgstr "" +msgstr "A quantidade não corresponde aos números de série" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" -msgstr "" +msgstr "O modelo de teste não existe" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" -msgstr "" +msgstr "O item de estoque foi atribuído a um pedido de venda" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" -msgstr "" +msgstr "O item de estoque está instalado em outro item" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" -msgstr "" +msgstr "O item de estoque contém outros itens" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" -msgstr "" +msgstr "O item de estoque foi atribuído a um cliente" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" -msgstr "" +msgstr "O item de estoque está atualmente em produção" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" -msgstr "" +msgstr "Estoque serializado não pode ser mesclado" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" -msgstr "" +msgstr "Itens de estoque duplicados" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" -msgstr "" +msgstr "Os itens de estoque devem se referir à mesma peça" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" -msgstr "" +msgstr "Os itens de estoque devem se referir à mesma peça de fornecedor" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" -msgstr "" +msgstr "Os códigos de status do estoque devem coincidir" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" -msgstr "" +msgstr "O item de estoque não pode ser movido porque não está em estoque" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" -msgstr "" +msgstr "Rastreamento do item de estoque" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" -msgstr "" +msgstr "Notas do registro" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" -msgstr "" +msgstr "Resultado de teste do item de estoque" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" -msgstr "" +msgstr "Um valor deve ser fornecido para este teste" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" -msgstr "" +msgstr "Um anexo deve ser enviado para este teste" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" -msgstr "" +msgstr "Valor inválido para este teste" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" -msgstr "" +msgstr "Resultado do teste" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" -msgstr "" +msgstr "Valor de saída do teste" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" -msgstr "" +msgstr "Anexo do resultado do teste" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" -msgstr "" +msgstr "Notas do teste" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" -msgstr "" +msgstr "Estação de teste" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" -msgstr "" +msgstr "O identificador da estação de teste onde o teste foi realizado" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" -msgstr "" +msgstr "Iniciado" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" -msgstr "" +msgstr "A data/hora de início do teste" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" -msgstr "" +msgstr "Concluído" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" -msgstr "" +msgstr "A data/hora de término do teste" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" -msgstr "" +msgstr "Código de lote gerado" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" -msgstr "" +msgstr "Selecionar pedido de produção" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" -msgstr "" +msgstr "Selecionar item de estoque para o qual gerar o código de lote" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" -msgstr "" +msgstr "Selecionar local para o qual gerar o código de lote" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" -msgstr "" +msgstr "Selecionar peça para a qual gerar o código de lote" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" -msgstr "" +msgstr "Selecionar pedido de compra" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" -msgstr "" +msgstr "Inserir quantidade para o código de lote" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" -msgstr "" +msgstr "Número de série gerado" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" -msgstr "" +msgstr "Selecionar peça para a qual gerar o número de série" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" -msgstr "" +msgstr "Quantidade de números de série a gerar" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" -msgstr "" +msgstr "Modelo de teste para este resultado" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" -msgstr "" +msgstr "Nenhum teste correspondente encontrado para esta peça" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" -msgstr "" +msgstr "O ID do modelo ou o nome do teste deve ser fornecido" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" -msgstr "" +msgstr "A hora de término do teste não pode ser anterior à hora de início" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" -msgstr "" +msgstr "Item pai" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" -msgstr "" +msgstr "Item de estoque pai" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" -msgstr "" +msgstr "Usar o tamanho do pacote ao adicionar: a quantidade definida é o número de pacotes" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" -msgstr "" +msgstr "Usar tamanho do pacote" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" -msgstr "" +msgstr "Inserir números de série para os novos itens" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" -msgstr "" +msgstr "Número de peça do fornecedor" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" -msgstr "" +msgstr "Vencido" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" -msgstr "" +msgstr "Itens filhos" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" -msgstr "" +msgstr "Itens de rastreamento" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" -msgstr "" +msgstr "Preço de compra deste item de estoque, por unidade ou pacote" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" -msgstr "" +msgstr "Inserir o número de itens de estoque a serializar" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" -msgstr "" +msgstr "Nenhum item de estoque fornecido" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" -msgstr "" +msgstr "A quantidade não pode exceder a quantidade de estoque disponível ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" -msgstr "" +msgstr "Local de estoque de destino" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" -msgstr "" +msgstr "Números de série não podem ser atribuídos a esta peça" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" -msgstr "" +msgstr "Os números de série já existem" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" -msgstr "" +msgstr "Selecionar item de estoque a instalar" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" -msgstr "" - -#: stock/serializers.py:838 -msgid "Enter the quantity of items to install" -msgstr "" - -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 -msgid "Add transaction note (optional)" -msgstr "" +msgstr "Quantidade a instalar" #: stock/serializers.py:851 +msgid "Enter the quantity of items to install" +msgstr "Inserir a quantidade de itens a instalar" + +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 +msgid "Add transaction note (optional)" +msgstr "Adicionar nota da transação (opcional)" + +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" -msgstr "" +msgstr "A quantidade a instalar deve ser pelo menos 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" -msgstr "" - -#: stock/serializers.py:870 -msgid "Selected part is not in the Bill of Materials" -msgstr "" +msgstr "O item de estoque está indisponível" #: stock/serializers.py:883 +msgid "Selected part is not in the Bill of Materials" +msgstr "A peça selecionada não está na lista de materiais" + +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" -msgstr "" +msgstr "A quantidade a instalar não pode exceder a quantidade disponível" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" -msgstr "" +msgstr "Local de destino para o item desinstalado" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" -msgstr "" +msgstr "Código de status do item de estoque" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "Linha de BOM que define a peça componente a ser extraída" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "Quantidade da peça componente a ser criada" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "Local de destino para os itens componentes" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "Código de status para os itens componentes" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "Preço de compra unitário para os itens componentes (deixe em branco para alocação automática de custo)" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "Número de montagens a desmontar" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "Local de destino padrão para os itens componentes" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "O item de BOM não é válido para o item de estoque selecionado" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "Itens de BOM duplicados fornecidos" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Selecionar peça na qual converter o item de estoque" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "A peça selecionada não é uma opção válida para conversão" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Não é possível converter um item de estoque com peça de fornecedor atribuída" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" -msgstr "" +msgstr "Selecionar itens de estoque para alterar o status" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" -msgstr "" +msgstr "Nenhum item de estoque selecionado" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" -msgstr "" +msgstr "Sublocais" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "Excluir itens de estoque" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "Excluir todos os itens de estoque contidos neste local" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "Excluir sublocais" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "Excluir todos os sublocais contidos neste local" + +#: stock/serializers.py:1477 msgid "Parent stock location" -msgstr "" +msgstr "Local de estoque pai" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" -msgstr "" +msgstr "A peça deve ser vendável" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" -msgstr "" +msgstr "O item está alocado a um pedido de venda" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "O item está alocado a um pedido de transferência" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" -msgstr "" +msgstr "O item está alocado a um pedido de produção" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" -msgstr "" +msgstr "Cliente para atribuir os itens de estoque" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" -msgstr "" +msgstr "A empresa selecionada não é um cliente" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" -msgstr "" +msgstr "Notas da atribuição de estoque" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" -msgstr "" +msgstr "Uma lista de itens de estoque deve ser fornecida" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" -msgstr "" +msgstr "Notas da mesclagem de estoque" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" -msgstr "" +msgstr "Permitir fornecedores divergentes" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" -msgstr "" +msgstr "Permitir a mesclagem de itens de estoque com peças de fornecedor diferentes" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" -msgstr "" +msgstr "Permitir status divergente" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" -msgstr "" +msgstr "Permitir a mesclagem de itens de estoque com códigos de status diferentes" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" -msgstr "" +msgstr "Pelo menos dois itens de estoque devem ser fornecidos" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" -msgstr "" +msgstr "Sem alteração" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" -msgstr "" +msgstr "Valor da chave primária do StockItem" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" -msgstr "" +msgstr "O item de estoque não está em estoque" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" -msgstr "" +msgstr "O item de estoque já está em estoque" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" -msgstr "" +msgstr "A quantidade não pode ser negativa" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" -msgstr "" +msgstr "Mesclar com o estoque existente" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "Mesclar este item ao estoque existente no destino, se possível" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Notas da transação de estoque" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "Definir local de estoque para os itens contados (opcional)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" -msgstr "" +msgstr "Mesclar itens devolvidos com itens de estoque existentes, se possível" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" -msgstr "" +msgstr "Próximo número de série" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" -msgstr "" +msgstr "Número de série anterior" #: stock/status_codes.py:11 msgid "OK" @@ -9251,209 +9840,217 @@ msgstr "OK" #: stock/status_codes.py:12 msgid "Attention needed" -msgstr "" +msgstr "Atenção necessária" #: stock/status_codes.py:13 msgid "Damaged" -msgstr "" +msgstr "Danificado" #: stock/status_codes.py:14 msgid "Destroyed" -msgstr "" +msgstr "Destruído" #: stock/status_codes.py:15 msgid "Rejected" -msgstr "" +msgstr "Rejeitado" #: stock/status_codes.py:19 msgid "Quarantined" -msgstr "" +msgstr "Em quarentena" #: stock/status_codes.py:44 msgid "Legacy stock tracking entry" -msgstr "" +msgstr "Registro de rastreamento de estoque legado" #: stock/status_codes.py:46 msgid "Stock item created" -msgstr "" +msgstr "Item de estoque criado" #: stock/status_codes.py:49 msgid "Edited stock item" -msgstr "" +msgstr "Item de estoque editado" #: stock/status_codes.py:50 msgid "Assigned serial number" -msgstr "" +msgstr "Número de série atribuído" #: stock/status_codes.py:53 msgid "Stock counted" -msgstr "" +msgstr "Estoque contado" #: stock/status_codes.py:54 msgid "Stock manually added" -msgstr "" +msgstr "Estoque adicionado manualmente" #: stock/status_codes.py:55 msgid "Stock manually removed" -msgstr "" +msgstr "Estoque removido manualmente" #: stock/status_codes.py:56 msgid "Serialized stock items" -msgstr "" +msgstr "Itens de estoque serializados" #: stock/status_codes.py:58 msgid "Returned to stock" -msgstr "" +msgstr "Devolvido ao estoque" #: stock/status_codes.py:61 msgid "Location changed" -msgstr "" +msgstr "Local alterado" #: stock/status_codes.py:62 msgid "Stock updated" -msgstr "" +msgstr "Estoque atualizado" #: stock/status_codes.py:65 msgid "Installed into assembly" -msgstr "" +msgstr "Instalado na montagem" #: stock/status_codes.py:66 msgid "Removed from assembly" -msgstr "" +msgstr "Removido da montagem" #: stock/status_codes.py:68 msgid "Installed component item" -msgstr "" +msgstr "Item componente instalado" #: stock/status_codes.py:69 msgid "Removed component item" -msgstr "" +msgstr "Item componente removido" #: stock/status_codes.py:72 msgid "Split from parent item" -msgstr "" +msgstr "Separado do item pai" #: stock/status_codes.py:73 msgid "Split child item" -msgstr "" +msgstr "Item filho separado" #: stock/status_codes.py:76 msgid "Merged stock items" -msgstr "" +msgstr "Itens de estoque mesclados" #: stock/status_codes.py:79 -msgid "Converted to variant" -msgstr "" +msgid "Disassembled into components" +msgstr "Desmontado em componentes" -#: stock/status_codes.py:82 -msgid "Build order output created" -msgstr "" +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "Criado a partir da desmontagem" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "Convertido em variante" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "Saída do pedido de produção criada" + +#: stock/status_codes.py:87 msgid "Build order output completed" -msgstr "" - -#: stock/status_codes.py:84 -msgid "Build order output rejected" -msgstr "" - -#: stock/status_codes.py:85 -msgid "Consumed by build order" -msgstr "" +msgstr "Saída do pedido de produção concluída" #: stock/status_codes.py:88 +msgid "Build order output rejected" +msgstr "Saída do pedido de produção rejeitada" + +#: stock/status_codes.py:89 +msgid "Consumed by build order" +msgstr "Consumido por pedido de produção" + +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" -msgstr "" +msgstr "Enviado para pedido de venda" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" -msgstr "" - -#: stock/status_codes.py:94 -msgid "Returned against Return Order" -msgstr "" - -#: stock/status_codes.py:97 -msgid "Sent to customer" -msgstr "" +msgstr "Recebido para pedido de compra" #: stock/status_codes.py:98 +msgid "Returned against Return Order" +msgstr "Devolvido para pedido de devolução" + +#: stock/status_codes.py:101 +msgid "Sent to customer" +msgstr "Enviado ao cliente" + +#: stock/status_codes.py:102 msgid "Returned from customer" -msgstr "" +msgstr "Devolvido pelo cliente" #: templates/403.html:6 templates/403.html:10 templates/403_csrf.html:7 msgid "Permission Denied" -msgstr "Permissão Negada" +msgstr "Permissão negada" #: templates/403.html:11 msgid "You do not have permission to view this page." -msgstr "" +msgstr "Você não tem permissão para ver esta página." #: templates/403_csrf.html:11 msgid "Authentication Failure" -msgstr "" +msgstr "Falha de autenticação" #: templates/403_csrf.html:12 msgid "You have been logged out from InvenTree." -msgstr "" +msgstr "Você foi desconectado do InvenTree." #: templates/404.html:6 templates/404.html:10 msgid "Page Not Found" -msgstr "Página Não Encontrada" +msgstr "Página não encontrada" #: templates/404.html:11 msgid "The requested page does not exist" -msgstr "" +msgstr "A página solicitada não existe" #: templates/500.html:6 templates/500.html:10 msgid "Internal Server Error" -msgstr "Erro Interno do Servidor" +msgstr "Erro interno do servidor" #: templates/500.html:11 #, python-format msgid "The %(inventree_title)s server raised an internal error" -msgstr "" +msgstr "O servidor %(inventree_title)s gerou um erro interno" #: templates/500.html:12 msgid "Refer to the error log in the admin interface for further details" -msgstr "" +msgstr "Consulte o log de erros na interface de administração para mais detalhes" #: templates/503.html:11 templates/503.html:15 msgid "Site is in Maintenance" -msgstr "Site em Manutenção" +msgstr "Site em manutenção" #: templates/503.html:17 msgid "The site is currently in maintenance and should be up again soon!" -msgstr "" +msgstr "O site está em manutenção no momento e deve voltar a funcionar em breve!" #: templates/base.html:51 msgid "Server Restart Required" -msgstr "Reinicialização do Servidor é Necessária" +msgstr "Reinicialização do servidor é necessária" #: templates/base.html:54 msgid "A configuration option has been changed which requires a server restart" -msgstr "" +msgstr "Uma opção de configuração foi alterada e requer a reinicialização do servidor" #: templates/base.html:54 templates/base.html:64 msgid "Contact your system administrator for further information" -msgstr "" +msgstr "Entre em contato com o administrador do sistema para mais informações" #: templates/base.html:61 msgid "Pending Database Migrations" -msgstr "" +msgstr "Migrações de banco de dados pendentes" #: templates/base.html:64 msgid "There are pending database migrations which require attention" -msgstr "" +msgstr "Há migrações de banco de dados pendentes que requerem atenção" #: templates/config_error.html:6 templates/config_error.html:10 msgid "Configuration Error" -msgstr "" +msgstr "Erro de configuração" #: templates/config_error.html:11 #, python-format msgid "The %(inventree_title)s server raised a configuration error" -msgstr "" +msgstr "O servidor %(inventree_title)s gerou um erro de configuração" #: templates/email/build_order_completed.html:9 #: templates/email/canceled_order_assigned.html:9 @@ -9465,59 +10062,59 @@ msgstr "" #: templates/email/purchase_order_received.html:9 #: templates/email/return_order_received.html:9 msgid "Click on the following link to view this order" -msgstr "" +msgstr "Clique no link a seguir para ver este pedido" #: templates/email/build_order_required_stock.html:7 msgid "Stock is required for the following build order" -msgstr "" +msgstr "Estoque é necessário para o seguinte pedido de produção" #: templates/email/build_order_required_stock.html:8 #, python-format msgid "Build order %(build)s - building %(quantity)s x %(part)s" -msgstr "" +msgstr "Pedido de produção %(build)s - produzindo %(quantity)s x %(part)s" #: templates/email/build_order_required_stock.html:10 msgid "Click on the following link to view this build order" -msgstr "" +msgstr "Clique no link a seguir para ver este pedido de produção" #: templates/email/build_order_required_stock.html:14 msgid "The following parts are low on required stock" -msgstr "" +msgstr "As peças a seguir estão com estoque baixo" #: templates/email/build_order_required_stock.html:18 msgid "Required Quantity" -msgstr "" +msgstr "Quantidade necessária" #: templates/email/build_order_required_stock.html:38 #: templates/email/low_stock_notification.html:30 msgid "You are receiving this email because you are subscribed to notifications for this part " -msgstr "" +msgstr "Você está recebendo este e-mail porque está inscrito para receber notificações desta peça " #: templates/email/low_stock_notification.html:9 #: templates/email/part_event_notification.html:9 msgid "Click on the following link to view this part" -msgstr "" +msgstr "Clique no link a seguir para ver esta peça" #: templates/email/low_stock_notification.html:18 #: templates/email/part_event_notification.html:19 msgid "Minimum Quantity" -msgstr "" +msgstr "Quantidade mínima" #: templates/email/part_event_notification.html:32 msgid "You are receiving this email because you are subscribed to notifications for this part or a category that it is part of " -msgstr "" +msgstr "Você está recebendo este e-mail porque está inscrito para receber notificações desta peça ou de uma categoria à qual ela pertence " #: templates/email/stale_stock_notification.html:10 msgid "The following stock items are approaching their expiry dates:" -msgstr "" +msgstr "Os seguintes itens de estoque estão se aproximando da data de validade:" #: templates/email/stale_stock_notification.html:23 msgid "Days Until Expiry" -msgstr "Dias Até Vencimento" +msgstr "Dias até vencimento" #: templates/email/stale_stock_notification.html:57 msgid "You are receiving this email because you are subscribed to notifications for these parts" -msgstr "" +msgstr "Você está recebendo este e-mail porque está inscrito para receber notificações destas peças" #: users/admin.py:101 msgid "Users" @@ -9525,301 +10122,305 @@ msgstr "Usuários" #: users/admin.py:102 msgid "Select which users are assigned to this group" -msgstr "" +msgstr "Selecionar quais usuários estão atribuídos a este grupo" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Informações pessoais" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Permissões" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" -msgstr "" +msgstr "Datas importantes" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" -msgstr "" +msgstr "O token foi revogado" #: users/authentication.py:33 msgid "Token has expired" -msgstr "" +msgstr "O token expirou" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" -msgstr "" +msgstr "Token de API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" -msgstr "" +msgstr "Tokens de API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" -msgstr "" +msgstr "Nome do token" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" -msgstr "" +msgstr "Nome personalizado do token" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" -msgstr "" +msgstr "Data de validade do token" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" -msgstr "" +msgstr "Visto por último" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" -msgstr "" +msgstr "Última vez que o token foi usado" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" -msgstr "" +msgstr "Revogado" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" -msgstr "" +msgstr "Conjunto de permissões" -#: users/models.py:240 +#: users/models.py:238 msgid "View" -msgstr "" +msgstr "Visualizar" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Permissão para exibir itens" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Adicionar" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Permissão para adicionar itens" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Alterar" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Permissões para editar itens" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Excluir" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Permissão para excluir itens" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" -msgstr "" +msgstr "Bot" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Interno" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Convidado" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Idioma" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Idioma preferencial para o usuário" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Tema" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" -msgstr "" +msgstr "Configurações da interface web em JSON - não edite manualmente!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Widgets" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" -msgstr "" +msgstr "Configurações dos widgets do painel em JSON - não edite manualmente!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" -msgstr "Nome de Exibição" +msgstr "Nome de exibição" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Nome de exibição escolhido para o usuário" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Cargo" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" -msgstr "" +msgstr "Cargo ou posição principal" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Mensagem de status do usuário" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" -msgstr "" +msgstr "Informações de localização do usuário" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" -msgstr "" +msgstr "O usuário está usando o sistema ativamente" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" -msgstr "" +msgstr "Informações de contato preferenciais do usuário" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" -msgstr "Tipo de Usuário" +msgstr "Tipo de usuário" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" -msgstr "" +msgstr "Que tipo de usuário é este?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organização" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" -msgstr "" +msgstr "Organização/afiliação principal do usuário" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" -msgstr "" +msgstr "Grupo principal" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" -msgstr "" +msgstr "Grupo principal do usuário" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" -msgstr "" - -#: users/ruleset.py:34 -msgid "Purchase Orders" -msgstr "" +msgstr "Listas de materiais" #: users/ruleset.py:35 -msgid "Sales Orders" -msgstr "" +msgid "Purchase Orders" +msgstr "Pedidos de compra" #: users/ruleset.py:36 -msgid "Return Orders" -msgstr "" +msgid "Sales Orders" +msgstr "Pedidos de venda" -#: users/serializers.py:186 +#: users/ruleset.py:37 +msgid "Return Orders" +msgstr "Pedidos de devolução" + +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "Pedidos de transferência" + +#: users/serializers.py:196 msgid "Username" msgstr "Nome de usuário" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" -msgstr "Primeiro Nome" +msgstr "Primeiro nome" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Primeiro nome do usuário" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Sobrenome" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Sobrenome do usuário" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Endereço de e-mail do usuário" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" -msgstr "" +msgstr "O usuário deve estar autenticado" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" -msgstr "" +msgstr "Apenas um superusuário pode criar um token para outro usuário" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" -msgstr "" +msgstr "Administrador" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" -msgstr "" +msgstr "Este usuário tem permissões administrativas" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superusuário" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" -msgstr "" +msgstr "Este usuário é um superusuário" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" -msgstr "" +msgstr "Esta conta de usuário está ativa" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Somente um superusuário pode ajustar este campo" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Senha" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Senha do usuário" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" -msgstr "" +msgstr "Substituir aviso" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" -msgstr "" +msgstr "Substituir o aviso sobre as regras de senha" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" -msgstr "" +msgstr "Equipe" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" -msgstr "" +msgstr "Este usuário tem permissões de equipe" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Você não tem permissão para criar usuários" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Sua conta foi criada." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" -msgstr "" +msgstr "Use a função de redefinição de senha para entrar" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Bem-vindo(a) ao InvenTree" diff --git a/src/backend/InvenTree/locale/ro/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/ro/LC_MESSAGES/django.po index b3db2e6899..e4a3a4a5b3 100644 --- a/src/backend/InvenTree/locale/ro/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/ro/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Criteriul API final nu a fost găsit" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Articolele trebuie să fie furnizate ca o listă" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Listă de articole nevalidă furnizată" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Toate filtrele trebuie folosite doar cu adevărat" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Niciun articol nu corespunde criteriilor furnizate" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Nu sunt furnizate date" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Acest câmp trebuie să fie unic." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Utilizatorul nu are permisiunea de a vedea acest model" @@ -65,150 +69,155 @@ msgstr "Confirmare adresă e-mail" msgid "You must type the same email each time." msgstr "Trebuie să tastați același e-mail de fiecare dată." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Adresa de e-mail principală furnizată nu este validă." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Domeniul de e-mail furnizat nu este aprobat." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Unitate nevalidă furnizată ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nicio valoare furnizată" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Nu s-a putut converti {original} în {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Cantitate furnizata nevalida" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Detaliile de eroare pot fi găsite în panoul de administrare" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Enter Date" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Valoare zecimală nevalidă" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Notițe" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Valoarea '{name}' nu apare în formatul modelului" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Valoarea furnizată nu se potrivește cu modelul necesar: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Nu se pot serializa mai mult de 1000 de elemente odată" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Golire șir de numere de serie" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Număr de serie duplicat" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Grup nevalid: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Interval de grup {group} depășește cantitatea permisă ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Niciun număr de serie găsit" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Numărul unic de numere de serie ({n}) trebuie să corespundă cu cantitatea ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Elimină tag-urile HTML din această valoare" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Datele conţin conţinut de marcaje interzis" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Eroare de conexiune" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Serverul a răspuns cu un cod de stare invalid" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Excepție apărută" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Serverul a răspuns cu o valoare de Content-Length invalidă" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Dimensiunea imaginii este prea mare" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Descărcarea imaginii a depăşit dimensiunea maximă" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Serverul la distanță a returnat un răspuns gol" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "URL-ul furnizat nu este un fișier imagine valid" @@ -216,159 +225,203 @@ msgstr "URL-ul furnizat nu este un fișier imagine valid" msgid "Log in to the app" msgstr "Conectați-vă la aplicație" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-mail" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Trebuie să activați autentificarea cu doi factori înainte de a face orice altceva." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Eroare la rularea validării plugin-ului" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata trebuie să fie un obiect dict python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metadatele plugin" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Câmp de metadate JSON pentru utilizare de plugin-uri externe" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Model formatat incorect" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Format necunoscut cheie specificat" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Lipseste cheia de format" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Câmpul de referință nu poate fi gol" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referința trebuie să corespundă modelului necesar" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Numărul de referință este prea mare" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Alegere invalidă" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Nume" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Descriere" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Descriere (opțional)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Cale" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Duplicate nume nu poate exista sub acelaşi părinte" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Note Markdown (opțional)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Date Cod de Bare" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Date coduri de bare terțe" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Date Cod de Bare" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Hash unic al codului de bare" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Cod de bare existent găsit" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Eroare de server" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "A fost înregistrată o eroare de către server." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Imagine" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Trebuie sa fie un număr valid" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Monedă" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Selectați moneda din opțiunile disponibile" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Acest câmp nu poate fi null." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Valoare invalidă" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Format de tip de conținut nevalid" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Tipul de conținut nu a fost găsit" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "Tipul de conținut nu se potrivește cu mixin necesar clasei" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabic" @@ -521,46 +574,48 @@ msgstr "Chineză (simplificată)" msgid "Chinese (Traditional)" msgstr "Chineză (tradițională)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Actualizare disponibilă" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "O actualizare pentru InvenTree este disponibilă" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Unitate fizică nevalidă" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Nu este un cod valutar valid" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Starea comenzii" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Construcție părinte" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "İnclude variante" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "İnclude variante" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "İnclude variante" msgid "Part" msgstr "Piesă" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Categorie" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Ancestor Build" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Alocate mie" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Atribuit către" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Creat înainte de" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Creat după" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Are data de începere" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Data de început înainte de" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Data de incepere după" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Are dată țintă" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Data de început înainte de" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Data de incepere după" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Finalizat înainte de" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Finalizat după" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Dată min" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Dată maximă" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Exclude arbore" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Construcția trebuie anulată înainte de a putea fi ștearsă" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Consumabile" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opţional" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Asamblate" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Urmarit" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testabilă" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Comandă restantă" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Alocate" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Consumat" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Disponibil" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Pe comandă" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Comenzi de Producție" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Locatie" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Ieșire" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Filtrează după ID-ul elementelor de ieșire din stoc. Utilizați \"null\" pentru a găsi elemente de construcție dezinstalate." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Comenzi de Producție" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "BOM-ul nu a fost validată" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Comandă de producție nu poate fi creată pentru piesa inactiva" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Comandă de producție nu poate fi creată pentru piesa deblocată" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Comenzile de producție pot fi îndeplinite extern doar pentru piesele achiziționabile" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Utilizator sau grup responsabil trebuie specificat" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Piesa din comanda de producție nu poate fi schimbata" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Data țintă trebuie să fie după data de început" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Referință comandă producție" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referinţă" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Scurtă descriere a construcției (opțional)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Comanda de producție pentru care această construcție este alocată" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Selectează piesa pentru construit" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referință comandă de vânzare" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Comanda de vânzare pentru care această construcție este alocată" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Locație sursă" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Selectați locația de unde se va prelua stocul pentru această producție (lăsați câmpul necompletat pentru a prelua stocul din orice locație)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Construcție externă" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Această comandă de producție este îndeplinită extern" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Locul destinației" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Selectaţi locaţia unde vor fi stocate elementele complete" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Cantitatea construirii" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Numărul de articole de stoc pentru producție" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Articole finalizate" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Numărul de articole din stoc care au fost finalizate" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Stare producției" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Cod status producție" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Cod lot" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Cod de lot pentru această producție" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Data creării" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Data începerii construcției" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Data de început programată pentru această comandă de construcție" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Data finalizării țintă" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Data țintă pentru finalizarea construcției. Construcția va fi depășită după această dată." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Data completării" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "finalizat până la" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Emis de" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Utilizatorul care a emis această comandă de producție" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Responsabil" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Utilizatorul sau grupul responsabil pentru această comandă de producție" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Link extern" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link către URL-ul extern" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Prioritate de construire" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Prioritatea acestei comenzi de producție" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Cod proiect" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Cod de proiect pentru această comandă de construcție" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Nu se poate finaliza construcția comenzii cu versiuni deschise" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Nu se poate completa comanda de producție cu rezultate incomplete" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Nu s-a putut descărca sarcina pentru a finaliza alocarea construcției" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "A fost finalizată o comandă de producție {build}" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "A fost finalizată o comandă de producție" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Numerele de serie trebuie furnizate pentru piesele urmăribile" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nu este specificată nicio ieșire de producție" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Construcția este deja finalizată" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Construcția nu se potrivește cu Comanda de producție" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Cantitatea trebuie să fie mai mare decât zero" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Cantitatea nu poate fi mai mare decât cantitatea de ieşire" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "Construcția nu a trecut toate testele necesare" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Construcția {serial} nu a trecut toate testele necesare" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "Stocurile alocate sunt încă în producţie" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Nu se poate finaliza parțial o construcție cu elemente alocate" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Element linie comandă de producție" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Construiește obiectul" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Construiește obiectul" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Cantitate" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Cantitatea necesară pentru comanda de producție" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Cantitatea de stoc consumată" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Articolul contruit trebuie să specifice o ieșire de construcție, deoarece piesa principală este marcată ca urmăribilă." -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Articolul din stoc selectat nu se potrivește cu linia BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "Cantitatea alocată trebuie să fie mai mare decât zero" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Cantitatea trebuie sa fie 1 pentru stoc serializat" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Cantitate alocata ({q}) nu trebuie sa depaseasca cantitatea disponibila de stoc ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Articolul din stoc este supra alocat" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Articol Stoc" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Locație articol stoc" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Cantitatea de stoc alocată pentru construcție" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Instalează în" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Destinație articol in stoc" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Nivel de construcție" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Numele Piesei" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Rezultat de construcție" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Producția nu corespunde cu producția-mamă" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Componenta de ieșire nu corespunde componentei din comanda de producție" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Această producție este deja finalizată" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Această producție nu este alocată integral" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Introduceți cantitatea pentru producția de ieșire" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Număr de serie" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Nu este permisă" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Acceptați nealocat" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Acceptați Incomplet" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Linie de construcție" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Rezultatul construirii" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Locația stocului de unde vor fi procurate piesele (lăsați necompletat pentru a prelua piesele din orice locație)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Nume piesă BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Producție" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Nume Categorie Piesă" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "În Producţie" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Stoc extern" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Stoc disponibil" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Stoc de înlocuire disponibil" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "În așteptare" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Producție" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Suspendat" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Anulat" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Finalizat" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "A fost finalizată o comandă de producție {build}" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "A fost finalizată o comandă de producție" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Comandă de producție restantă" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Comanda de producție {bo} este în întârziere" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Etichetă Cod Proiect" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "Descrierea proiectului" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Utilizatorul sau grupul responsabil pentru acest proiect" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Valoarea nu trece verificările de validare" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Utilizator" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Preț" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Preț unitar la cantitatea specificată" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Punct final" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Punctul final la care acest webhook este primit" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Nume pentru acest webhook" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Activ" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Utilizatorul sau grupul responsabil pentru acest proiect" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Valoarea nu trece verificările de validare" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Utilizator" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Preț" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Preț unitar la cantitatea specificată" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Punct final" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Punctul final la care acest webhook este primit" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Nume pentru acest webhook" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Este acest webhook activ" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token-ul" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token pentru acces" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Secret" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Host" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Host de la care acest mesaj a fost primit" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id-ul" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Titlu" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Publicată" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Rezumat" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Citit" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "A fost citită această știre?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Fișier imagine" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Unitate personalizată" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Numele unității trebuie să fie un identificator valid" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Numele unității" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Comentariu" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Comentariu atașament" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Data încărcării" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Numele statului" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Descrierea listei de selecție" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Descrierea parametrului" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Numele acțiunii" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Nume funcție" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Nume fișier" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "Versiune Componente" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" -msgstr "" +msgid "Part Revisions" +msgstr "Versiune Componente" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 +msgid "Globally Unique Serials" +msgstr "" + +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" +msgstr "" + +#: common/setting/system.py:713 +msgid "Delete Depleted Stock" +msgstr "" + +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" +msgstr "" + +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" +msgstr "" + +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" +msgstr "" + +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" +msgstr "" + +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Șablon Cod lot" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Șablon pentru generarea codurilor de lot implicite pentru elementele de stoc" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Necesită Titularul Responsabil" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Titularul responsabil trebuie să fie atribuit fiecărei comenzi" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Comenzi externe de producție" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blochează până la trecerea testelor" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Previne ca ieșirile de construcție să fie finalizate până când toate testele necesare trec" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Comenzile de vânzare marcate ca expediate vor fi finalizate automat, ocolind starea \"expediate\"" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Activează parola uitată" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Activare parolă uitată funcție pe paginile de autentificare" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" -msgstr "" +msgid "Enable password forgot" +msgstr "Activează parola uitată" -#: common/setting/system.py:1021 -msgid "Mail twice" -msgstr "" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Activare parolă uitată funcție pe paginile de autentificare" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" -msgstr "Parola de două ori" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" -msgstr "La înscriere, cere de două ori parola lor" - -#: common/setting/system.py:1033 -msgid "Allowed domains" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" -msgstr "" +msgid "Password twice" +msgstr "Parola de două ori" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" -msgstr "" +msgid "On signup ask users twice for their password" +msgstr "La înscriere, cere de două ori parola lor" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" -msgstr "Afișează numele complet al utilizatorilor în loc de nume de utilizator" +msgid "Enable project codes for tracking projects" +msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "Afișează numele complet al utilizatorilor în loc de nume de utilizator" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Descrierea piesei de la producător" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Descrierea piesei furnizorului" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Id comandă" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Descrierea comenzii (opțional)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Utilizatorul sau grupul responsabil pentru această comandă de producție" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Descrierea elementului de rând (opțional)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Introduceți codul lotului pentru articolele din stoc primite" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5718,1279 +6125,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Este versiune" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Are Versiuni" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Descrierea piesei (opțional)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Versiunea" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Este aceasta parte o versiune a unei alte părți?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Versiune Din" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Responsabil pentru acest capitol" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Descriere test" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Introduceți descrierea pentru acest test" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Este necesar acest test pentru a trece?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Versiunea" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "Descrierea piesei" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Descrierea șablonului" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Număr versiune (creșteri automate)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Descrierea detaliată a fișierului" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Descriere fișier Asset" @@ -8291,23 +8771,23 @@ msgstr "Descriere fișier Asset" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Proprietar" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Codul lotului pentru acest element din stoc" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Cod lot generat" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Selectați articolul din stoc pentru a genera codul de lot" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Selectaţi locaţia pentru a genera codul de lot pentru" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Selectați articolul pentru a genera codul de lot pentru" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Introduceți cantitatea pentru codul de lot" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Nume utilizator" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Prenumele" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Prenumele utilizatorului" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Parolă" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Parolă pentru utilizator" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Suprascrie avertismentul cu privire la regulile parolei" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Vă rugăm să utilizați funcția de resetare a parolei pentru a vă autentifica" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/ru/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/ru/LC_MESSAGES/django.po index 34094be307..5021dbaf31 100644 --- a/src/backend/InvenTree/locale/ru/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/ru/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Конечная точка API не обнаружена" -#: InvenTree/api.py:438 -msgid "List of items must be provided for bulk operation" -msgstr "" - #: InvenTree/api.py:445 +msgid "List of items must be provided for bulk operation" +msgstr "Для массовой операции необходимо указать список позиций" + +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Элементы должны быть представлены в виде списка" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Предоставлен недопустимый список элементов" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Все фильтры будут использоваться с параметром True" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Нет элементов, соответствующих заданным критериям" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Данные не предоставлены" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Поле должно быть уникальным." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "У пользователя недостаточно прав для просмотра этой модели!" @@ -65,150 +69,155 @@ msgstr "Подтверждение адреса электронной почт msgid "You must type the same email each time." msgstr "Вы должны вводить один и тот же адрес электронной почты." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Указанный основной адрес электронной почты неверен." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Указанный домен электронной почты не утверждён." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Предоставлено недопустимое значение ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Значение не указано" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Невозможно преобразовать {original} в {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "недопустимое количество" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Подробности об ошибке можно найти в панели администратора" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Введите дату" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Не верное десятичное значение" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Заметки" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Значение '{name}' отсутствует в формате шаблона" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Предоставленное значение не соответствует требуемому формату: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Одновременно можно сериализовать только 1000 элементов" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Пустая строка серийного номера" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Повторяющийся серийный номер" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Недопустимая группа: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Диапазон группы {group} превышает допустимое количество ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Серийных номеров не найдено" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Количество уникальных серийных номеров ({n}) должно быть равно ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Удалить HTML теги из этого значения" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Данные содержат недопустимую разметку" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" -msgstr "" +msgstr "Недопустимый URL: имя хоста отсутствует" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" -msgstr "" +msgstr "Недопустимый URL: не удалось разрешить имя хоста" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" -msgstr "" +msgstr "URL указывает на частный или зарезервированный IP-адрес" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" -msgstr "" +msgstr "Слишком много перенаправлений" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Ошибка соединения" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Сервер ответил неверным кодом статуса" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Произошло исключение" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Сервер ответил неверным значением Контент-Длина" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Изображение слишком большое" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Загрузка изображения превышен максимальный размер" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Удаленный сервер вернул пустой ответ" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Предоставленный URL не является допустимым файлом изображения" @@ -216,159 +225,203 @@ msgstr "Предоставленный URL не является допусти msgid "Log in to the app" msgstr "Войти в приложение" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Электронная почта" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "Проверка CSRF не пройдена. Убедитесь, что INVENTREE_SITE_URL и INVENTREE_TRUSTED_ORIGINS настроены правильно." + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Вы должны включить двухфакторную аутентификацию, прежде чем делать что-нибудь еще." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Ошибка запуска проверки плагина" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Метаданные должны быть объектом python dict" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Метаданные плагина" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Поле метаданных JSON для использования внешними плагинами" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Неправильно отформатированный шаблон" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Указан неизвестный ключ формата" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Отсутствует требуемый ключ формата" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Ссылочный идентификатор не может быть пустым" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Ссылка должна соответствовать шаблону {pattern}" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Номер ссылки слишком большой" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Неверный выбор" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Название" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Описание" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Описание (необязательно)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Путь" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Повторяющиеся имена не могут существовать под одним и тем же родителем" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Записи о скидке (необязательно)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Данные штрихкода" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Данные стороннего штрих-кода" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Хэш штрих-кода" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Уникальный хэш данных штрих-кода" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Обнаружен существующий штрих-код" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Ошибка сервера" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Сервер зарегистрировал ошибку." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Изображение" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Должно быть действительным номером" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Валюта" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Выберите валюту из доступных вариантов" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Это поле не может быть пустым." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Неверное значение" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Неверный формат типа содержимого" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "Тип содержимого не найден" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "Тип содержимого не соответствует требуемому классу миксина" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Скопировать параметры" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "Копировать параметры из исходной позиции" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Копировать позиции" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Копировать позиции из исходного заказа" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Копировать дополнительные позиции" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Копировать дополнительные позиции из исходного заказа" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "Параметры дублирования" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "Укажите параметры дублирования этой позиции" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "Исходный" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "Выберите экземпляр для дублирования" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Арабский" @@ -521,46 +574,48 @@ msgstr "Китайский (Упрощенный)" msgid "Chinese (Traditional)" msgstr "Китайский (Традиционный)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Доступно обновление" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "Доступно обновление для InvenTree" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Неверная физическая единица" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Неверный код валюты" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Статус заказа" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Родительский заказ на производство" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Включая варианты" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Включая варианты" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Включая варианты" msgid "Part" msgstr "Деталь" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Категория" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Родительская сборка" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Назначено мне" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Назначено" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Создано до" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Создано после" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Есть дата начала" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Дата начала до" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Дата начала после" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Есть целевая дата" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Целевая дата до" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Целевая дата после" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Завершено до" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Завершено после" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "Минимальная дата" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Максимальная дата" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Исключить дерево" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Заказ на производство должен быть отменен перед удалением" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Расходник" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Необязательно" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Сборная деталь" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Отслеживается" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Тестируемая" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Невыполненные заказы" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Зарезервировано" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Потреблено" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Доступно" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "В заказе" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" -msgstr "" +msgstr "Сборка не найдена" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Заказ на производство" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Расположение" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Выход" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Фильтрация по идентификатору исходящей складской позиции. Используйте 'null', чтобы найти несмонтированные элементы сборки." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Заказы на производство" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Сборка BOM не подтверждена" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Порядок сборки не может быть создан для неактивной части" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Порядок сборки не может быть создан для разблокированной части" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Заказ на сборку может быть помечен сторонним только для покупных деталей" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Должен быть указан ответственный пользователь или группа" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Деталь заказа на производства не может быть изменена" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Целевая дата должна быть после даты начала" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Ссылка на заказ на производство" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Номер" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Краткое описание заказа на производство (необязательно)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Заказ на производство, которому принадлежит этот заказ на производство" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Выберите деталь для производства" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Ссылка на заказ" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Заказ на продажу, которому принадлежит этот заказ на производство" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Место хранения комплектующих" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Выберите место хранения для этого заказа на производство (оставьте пустым, чтобы взять с любого места на складе)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Сторонняя сборка" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Этот заказ на сборку выполнен сторонней компанией" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Место хранения результата" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Выберите место хранения завершенных элементов" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Количество производимых деталей" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Количество складских позиций для производства" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Произведенные детали" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Количество складских позиций, которые были произведены" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Статус заказа на производство" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Код статуса заказа на производство" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Код партии" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Код партии для продукции" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Дата создания" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Дата начала сборки" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Запланированная начальная дата этого заказа на сборку" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Целевая дата завершения" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Целевая дата для заказа на производства. Заказ будет просрочен после этой даты." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Дата завершения" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "выполнено" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Создано" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Пользователь, создавший этот заказ на производство" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ответственный" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Пользователь, ответственный за этот заказ на производство" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Внешняя ссылка" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Ссылка на внешний URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Приоритет производства" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Приоритет этого заказа на производство" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Код проекта" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Код проекта для этого заказа на производство" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Невозможно завершить заказ на сборку при наличии открытых дочерних сборок" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Невозможно завершить заказ на сборку при незавершенных выходах" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Не удалось выгрузить задачу для распределения на сборку" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Заказ на производство {build} был завершен" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Заказ на производство был завершен" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Для отслеживаемых деталей должны быть указаны серийные номера" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Продукция не указана" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Продукция уже произведена" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Продукция не совпадает с заказом на производство" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Количество должно быть больше нуля" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Количество не может быть больше количества продукции" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "Выход сборки не прошёл все необходимые тесты" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Сборка {serial} не прошла все необходимые тесты" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "Выделенные на складе товары все еще находятся в производстве" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Невозможно частично завершить выход сборки с распределёнными элементами" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Превышено доступное количество ({q})" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Номер позиции для производства" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Объект производства" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Объект производства" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Количество" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Требуемое количество для заказа на производство" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Количество израсходованного запаса" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Элемент производства должен указать продукцию, как главную деталь помеченную как отслеживаемая" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Выбранная складская позиция не соответствует позиции в BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "Резервируемое количество должно быть больше нуля" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Количество должно быть 1 для сериализованных запасов" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Резервируемое количество ({q}) не должно превышать доступное количество на складе ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Складская позиция перераспределена" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Складская позиция" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Исходная складская позиция" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Количество на складе для производства" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Установить в" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Целевая складская позиция" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Уровень сборки" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Наименование детали" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Выход Продукции" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Продукция не совпадает с родительским заказом на производство" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Продукция не соответствует детали заказа на производство" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Эта продукция уже помечена как завершенная" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Сырье для этой продукции не полностью зарезервировано" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Введите количество продукции" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Для отслеживаемых деталей должно быть указано целочисленное количество" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Требуется целое количество, так как материал содержит отслеживаемые детали" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Серийные номера" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Введите серийные номера для продукции" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Местоположение склада для результата сборки" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Автоматически выделить серийные номера" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Автоматически зарезервировать необходимые элементы с соответствующими серийными номерами" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Следующие серийные номера уже существуют или недействительны" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Необходимо представить список выхода деталей" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Место хранения для списанной продукции" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Отменить резервирование" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Отменить все резервы запасов для списанной продукции" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Причина списания продукции" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Место хранения для завершенной продукции" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "Складские позиции нельзя назначать структурным местам хранения" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Разрешить неполное резервирование" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Завершить продукцию, даже если остатки не были полностью зарезервированы" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Израсходовать зарезервированные остатки" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Израсходовать складские позиции, которые были зарезервированы для этой продукции" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Удалить незавершенную продукцию" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Удалить всю незавершенную продукцию" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Запрещено" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Принять как поглощенный этим заказом на производство" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Отменить резерв, до завершения заказа на производство" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Перераспределенные запасы" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Как вы хотите обработать дополнительные складские позиции, назначенные для заказа на производство" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Некоторые складские позиции были перераспределены" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Разрешить не полное резервирование" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Подтвердите, что складские позиции не были полностью зарезервированы для этого заказа на производство" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Необходимые запасы не были полностью зарезервированы" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Разрешить незавершенные производимые детали" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Допустить, что требуемое кол-во продукции не завершено" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Требуемое количество деталей не было произведено" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Производственный заказ имеет незавершённые дочерние заказы" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Заказ на производство должен быть в стадии выполнения" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Заказ на производство имеет незавершенную продукцию" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Позиция для производства" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Выход продукции" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Продукция должна указывать на тот же производство" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Позиция для производства" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part должна указывать на ту же часть, что и заказ на производство" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Элемент должен быть в наличии" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Превышено доступное количество ({q})" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Продукция должна быть указан для резервирования отслеживаемых частей" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Продукция не может быть указана для резервирования не отслеживаемых частей" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Необходимо указать резервируемые элементы" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Место хранения, где будут зарезервированы детали (оставьте пустым, чтобы забрать их из любого места)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Исключить место хранения" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Исключить складские позиции из этого выбранного места хранения" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Обменный остаток" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Складские позиции в нескольких местах могут использоваться на взаимозаменяемой основе" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Заменить остатки" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Разрешить резервирование замещающих деталей" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Необязательные элементы" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Зарезервировать необязательные позиции BOM для заказа на производство" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" -msgstr "" +msgstr "Все позиции" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" -msgstr "" +msgstr "Неотслеживаемые позиции" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" -msgstr "" +msgstr "Отслеживаемые позиции" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" -msgstr "" +msgstr "Тип позиции" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" -msgstr "" +msgstr "Выберите тип позиции для автоматического резервирования" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "Приоритет запасов" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "Предпочтительный порядок списания подходящих складских позиций" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "Строки сборки" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "Ограничить резервирование этими строками сборки (оставьте пустым, чтобы резервировать все строки)" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Ссылка на спецификацию (BOM)" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID детали в спецификации (BOM)" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Название детали в спецификации (BOM)" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "Установить в" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Сборка" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Деталь поставщика" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Зарезервированное количество" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Ссылка на сборку" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Название категории детали" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Отслеживание" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Унаследованные" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Есть варианты" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Позиция BOM" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "В производстве" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Запланировано к сборке" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Внешний склад" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Доступный запас" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Доступный запас заменителей" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Доступный запас вариантов" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "Потреблённое количество превышает выделенное количество" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Дополнительные примечания по расходу запаса" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "Элемент сборки должен ссылаться на правильный заказ на сборку" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Дублирование выделения элемента сборки" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "Строка сборки должна ссылаться на правильный заказ на сборку" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Дублирование выделения строки сборки" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "Должен быть указан хотя бы один элемент или строка" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "В обработке" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Продукция" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Отложен" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Отменён" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Завершён" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Заказ на производство {build} был завершен" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Заказ на производство был завершен" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Необходимый запас для заказа на производство" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Заказ на сборку {build} требует дополнительный запас" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Просроченный заказ сборки" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Заказ на производство {bo} просрочен" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "Есть миниатюра" + +#: common/api.py:773 msgid "Is Link" msgstr "Ссылка" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Файл" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "У пользователя нет прав для удаления этих вложений" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "У пользователя нет разрешёния на изменение этого вложения" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "У пользователя нет прав на удаление этого вложения" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Список выбора заблокирован" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Неверный код валюты" @@ -1539,15 +1641,20 @@ msgstr "Не указаны действительные коды валют" msgid "No plugin" msgstr "Нет плагина" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "Теги" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Название кода проекта" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Обновлено" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Временная метка последнего обновления" @@ -1567,794 +1674,844 @@ msgstr "Уникальный код проекта" msgid "Project description" msgstr "Описание проекта" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Пользователь или группа, ответственные за этот проект" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Ключ настроек" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Значения настроек" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Выбранное значение не является допустимым" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Значение должно быть булевым" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Значение должно быть целым числом" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Значение должно быть допустимым числом" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Значение не прошло проверку" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Строка ключа должна быть уникальной" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Пользователь" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Скидка распространяется на заданное количество" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Цена" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Цена за единицу для указанного количества" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Конечная точка" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Конечная точка, на которой принимается этот веб-хук" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Имя для этого веб-хука" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Активный" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "Этот код проекта активен?" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Пользователь или группа, ответственные за этот проект" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Ключ настроек" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Значения настроек" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Выбранное значение не является допустимым" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Значение должно быть булевым" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Значение должно быть целым числом" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Значение должно быть допустимым числом" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Значение не прошло проверку" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Строка ключа должна быть уникальной" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Пользователь" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Скидка распространяется на заданное количество" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Цена" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Цена за единицу для указанного количества" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Конечная точка" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Конечная точка, на которой принимается этот веб-хук" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Имя для этого веб-хука" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Этот веб-хук активен?" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Токен" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Токен для доступа" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Секрет" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Общий ключ для HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID Сообщения" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Уникальный идентификатор этого сообщения" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Хост" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Хост, с которого было получено это сообщение" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Заголовок" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Заголовок этого сообщения" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Тело" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Текст этого сообщения" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Конечная точка, на которую было получено это сообщение" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Работал над" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Работа над этим сообщением завершена?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Код" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Заголовок" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Ссылка" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Опубликовано" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Автор" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Итого" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Читать" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Эта новость была прочитана?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Файл изображения" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Тип целевой модели для этого изображения" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "ID целевой модели для этого изображения" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Пользовательская единица измерения" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Символ единицы должен быть уникальным" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Имя единицы должно быть действительным идентификатором" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Название единицы" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Символ" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Обозначение единицы измерения (необязательно)" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Определение" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Определение единицы измерения" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Вложения" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Файл не найден" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Отсутствует внешняя ссылка" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" -msgstr "" +msgstr "Нет прикреплённого файла для переименования" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" -msgstr "" +msgstr "Имя файла не может быть пустым" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" -msgstr "" +msgstr "Недопустимое имя файла" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" -msgstr "" +msgstr "Нельзя изменить расширение файла" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" -msgstr "" +msgstr "Файл с таким именем уже существует" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" -msgstr "" +msgstr "Не удалось сохранить переименованный файл" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Тип модели" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Тип целевой модели для изображения" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Выберите файл для вложения" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "Миниатюра" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "Миниатюра для этого вложения" + +#: common/models.py:2155 msgid "Comment" msgstr "Комментарий" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Описание вложения" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Дата загрузки" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Дата загрузки файла" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "Является изображением" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "Истинно, если это вложение является допустимым файлом изображения" + +#: common/models.py:2183 msgid "File size" msgstr "Размер файла" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Размер файла в байтах" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Указан недопустимый тип модели для вложения" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Пользовательское состояние" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Пользовательские состояния" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Группа статусов" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Группа статусов, которая будет дополнена пользовательским состоянием" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Логическое состояние" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Логическое состояние, соответствующее пользовательскому состоянию в бизнес-логике" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Значение" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Числовое значение, которое будет сохранено в базе данных" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Название состояния" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Метка" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Метка, которая будет отображаться на фронтенде" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Цвет" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Цвет отображения в интерфейсе" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Модель" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Модель, с которой связано это состояние" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Необходимо выбрать модель" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Необходимо выбрать ключ" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Логическое состояние должно быть выбрано" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "Ключ должен отличаться от логического ключа" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Должен быть указан корректный класс ссылочного статуса" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "Состояние должно отличаться от других логических состояний выбранного статуса" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "Логическое состояние должно быть из множества логических состояний выбранного статуса" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Имя должно отличаться от имен эталонного статуса" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Список выбора" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Списки выбора" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Название списка выбора" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Описание списка выбора" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Заблокирована" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Этот список выбора заблокирован?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Можно ли использовать этот список выбора?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Исходный плагин" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Плагин, который предоставляет список выбора" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Исходная строка" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Необязательная строка, определяющая источник, используемый для этого списка" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Запись по умолчанию" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Вариант по умолчанию для этого списка выбора" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Создано" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Дата и время создания списка выбора" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Последнее обновление" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Дата и время последнего обновления списка выбора" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Вариант списка выбора" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Варианты списка выбора" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Список выбора, к которому относится данный вариант" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Значение варианта списка выбора" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Метка для элемента списка выбора" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Описание варианта списка выбора" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Активен ли варианта списка выбора?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Шаблон параметра" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "Шаблоны параметров" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "У параметров-переключателей не может быть единицы измерения" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "У параметров-переключателей не может быть вариантов" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Варианты должны быть уникальными" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Имя шаблона параметров должно быть уникальным" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "Тип целевой модели для этого шаблона параметра" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Название параметра" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Единица измерения" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Физическая единица этого параметра" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Описание параметра" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Переключатель" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Этот параметр является переключателем?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Варианты" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Возможные варианты этого параметра (разделить запятой)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Список выбора для этого параметра" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Включено" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "Включен ли этот шаблон параметра?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "Параметр" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "Параметры" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Недопустимое значение параметра" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "Указан неверный тип модели для параметра" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "ID модели" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "ID целевой модели для этого параметра" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Шаблон" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "Шаблон параметра" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Данные" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Значение параметра" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Заметка" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Опциональное поле записей" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Сканирование штрихкодов" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Данные штрихкода" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Пользователь, который сканировал штрих-код" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Метка времени" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Дата и время сканирования штрих-кода" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "URL-адрес, обработавший штрихкод" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Контекст" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Контекстные данные для сканирования штрих-кода" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Ответ" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Данные ответа от сканирования штрихкода" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Результат" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Сканирование штрихкода было успешным?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Произошла ошибка" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8: Удаление журнала электронной почты защищено. Установите INVENTREE_PROTECT_EMAIL_LOG в False, чтобы разрешить удаление." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "Сообщение электронной почты" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "Сообщения электронной почты" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Объявлено" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Отправлено" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Неудача" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Доставлено" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Подтверждено" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Входящее" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Исходящее" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Без ответа" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Отслеживать доставку" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Отслеживать прочтение" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Отслеживать клики" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "Глобальный идентификатор" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Идентификатор этого сообщения (может быть предоставлен внешней системой)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "ID цепочки" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Идентификатор темы этого сообщения (может быть предоставлен внешней системой)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Цепочка" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Связанная цепочка для этого сообщения" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "Приоритет" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "Цепочка электронной почты" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "Цепочки электронной почты" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Ключ" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Уникальный ключ для этой цепочки (используется для идентификации цепочки)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Уникальный идентификатор этой цепочки" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Запущено внутренне" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Эта цепочка была начата внутри?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Дата и время создания цепочки" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Дата и время последнего обновления цепочки" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} отменен" msgid "A order that is assigned to you was canceled" msgstr "Заказ, назначенный вам, был отменён" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Полученные элементы" @@ -2388,104 +2545,100 @@ msgstr "Товары были получены по заказу на закуп msgid "Items have been received against a return order" msgstr "Товары были получены по заказу на возврат" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "Показывает, если изменение этой настройки требует подтверждения" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "Этот параметр требует подтверждения перед изменением. Пожалуйста, подтвердите изменения." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Указывает, переопределена ли настройка переменной окружения" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Переопределить" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Запущен" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Ожидающие задачи" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Запланированные задания" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Невыполненные Задачи" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Код задачи" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Уникальный ID задачи" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Заблокировать" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Время блокировки" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Название задачи" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Функция" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Имя функции" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Аргументы" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Аргументы задачи" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Именованные аргументы" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Именованные аргументы задачи" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Имя файла" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Тип модели" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Пользователь не имеет разрешения создавать или редактировать вложения для этой модели" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "У пользователя нет разрешения на создание или редактирование параметров для этой модели" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Список выбора заблокирован" - #: common/setting/system.py:97 msgid "No group" msgstr "Нет группы" @@ -2560,19 +2713,19 @@ msgstr "Показать `О...` только суперпользователя #: common/setting/system.py:239 msgid "Show superuser banner" -msgstr "" +msgstr "Показывать баннер суперпользователя" #: common/setting/system.py:240 msgid "Show a warning banner in the UI when logged in as superuser" -msgstr "" +msgstr "Показывать предупреждающий баннер в интерфейсе при входе как суперпользователь" #: common/setting/system.py:245 msgid "Show admin banner" -msgstr "" +msgstr "Показывать баннер администратора" #: common/setting/system.py:246 msgid "Show a warning banner in the UI when logged in as admin" -msgstr "" +msgstr "Показывать предупреждающий баннер в интерфейсе при входе как администратор" #: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" @@ -2614,13 +2767,13 @@ msgstr "Интервал обновления курса валют" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Как часто обновлять курс валют (установите \"ноль\", чтобы выключить)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "дней" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Модуль обновления валюты" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "Ограничение размера загрузки" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "Максимально допустимый размер загрузки изображений и файлов" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Строгая проверка URL-адреса" @@ -2760,947 +2921,1017 @@ msgstr "Плагин генерации штрих-кода" msgid "Plugin to use for internal barcode data generation" msgstr "Плагин для использования внутренней генерации данных штрих-кодов" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "Блокировка деталей" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "Включить блокировку деталей для предотвращения изменений" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Ревизия детали" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Включить поле ревизии для элемента" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Только ревизия сборки" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Разрешить ревизии только для сборочных деталей" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Разрешить удаление из заказа" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Разрешить удаление частей, которые используются в заказе" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Регулярное выражение IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Шаблон регулярного выражения для сопоставления IPN детали" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Разрешить повторяющиеся IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Разрешить нескольким элементам использовать один и тот же IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Разрешить редактирование IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Разрешить изменение значения IPN при редактировании детали" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Скопировать данные BOM детали" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Копировать данные BOM по умолчанию при дублировании детали" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Скопировать данные параметров детали" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Копировать данных параметров по умолчанию при дублировании детали" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Скопировать данные тестирования детали" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Копировать данные тестирования по умолчанию при дублировании детали" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Скопировать параметры по шаблону категории" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Копировать параметры по шаблону категории при создании детали" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "По умолчанию детали являются шаблонами" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "По умолчанию детали могут быть собраны из других компонентов" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Компонент" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "По умолчанию детали могут использоваться в качестве суб-компонентов" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Можно купить" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "По умолчанию детали являются отслеживаемыми" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Можно продавать" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Детали продаются по умолчанию" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "По умолчанию детали являются отслеживаемыми" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Виртуальная" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Детали являются виртуальными по умолчанию" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Показывать связанные детали" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Отображать связанные детали для элемента" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Начальные данные о запасах" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Разрешить создание начального запаса при добавлении новой детали" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Исходные данные о поставщике" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Разрешить создание исходных данных о поставщике при добавлении новой детали" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Формат отображения детали" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Формат для отображения имени детали" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Значок раздела по умолчанию" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Значок категории по умолчанию (пустой означает отсутствие значка)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Минимальные Цены Десятичные Значки" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Минимальное количество десятичных знаков при отображении данных о ценах" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Макс. Цены десятичные знаки" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Минимальное количество десятичных знаков при отображении данных о ценах" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Использовать цены поставщика" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Включить разницу цен поставщиков при расчетах цен" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Изменить историю покупки" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Ценообразование по историческим заказам на поставку отменяет различия в ценах поставщиков" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Использовать цены из складских позиций" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Использовать расценки из ручного ввода данных о запасах для расчета цен" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Возраст цен складских позиций" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Исключить складские позиции старше указанного количества дней с расчёта цен" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Использовать варианты цен" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Включить разницу цен поставщиков при расчетах цен" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Только Активные Варианты" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Использовать только активные запчасти для расчета стоимости варианта" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Автоматическое обновление цен" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Автоматически обновлять цены деталей при изменении внутренних данных" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Интервал пересчета цен" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Количество дней до автоматического обновления цены" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Внутренние цены" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Разрешить внутренние цены для частей" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Переопределение внутренней цены" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "При наличии внутренних цен переопределить ценовой диапазон" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" -msgstr "" +msgstr "Разрешить нулевое количество в спецификации" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" -msgstr "" +msgstr "Разрешить нулевое количество для позиции спецификации детали. Позволяет использовать подготовительное количество для задания количества на сборку независимо от количества сборки" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Включить печать этикеток" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Включить печать этикеток из веб-интерфейса" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Изображение меток DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Разрешение DPI при создании файлов изображений для печати этикеток плагинов" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Включить отчеты" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Включить генерацию отчетов" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Режим отладки" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Генерировать отчеты в режиме отладки (вывод HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "Загрузка URL для отчётов" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "Разрешить загрузку удалённых URL при формировании отчётов" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Журнал ошибок отчета" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Журнал ошибок, которые возникают при создании отчетов" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Размер страницы" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Размер страницы по умолчанию для PDF отчетов" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Принудительное применение единиц измерения параметров" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Если введены единицы, значения параметра должны соответствовать указанным единицам измерения" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Глобально уникальные серийные номера" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Серийные номера для складских позиций должны быть уникальными глобально" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Удалить исчерпанный запас" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Определяет поведение по умолчанию, когда складская позиция заканчивается" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" -msgstr "" +msgstr "Разрешить изменение серийного номера" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" -msgstr "" +msgstr "Разрешить изменение серийного номера складских позиций" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" -msgstr "" +msgstr "Удаление серийного запаса" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" -msgstr "" +msgstr "Разрешить удаление складских позиций с серийным номером" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Код партии Шаблона" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Шаблон для создания кодов партии по умолчанию для складских позиций" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Срок годности Запасов" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Включить функцию истечения срока годности" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Использовать просроченные остатки в производстве" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Разрешить продажу просроченных запасов" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Время Залежалости Запасов" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Количество дней перед тем как складская единица будет считаться просроченной" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Использовать просроченные остатки в производстве" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Разрешить использовать просроченные остатки в производстве" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Контроль за собственными запасами" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Разрешить владельцу контролировать расположение складов и номенклатуры" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Значок местоположения по умолчанию" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Значок местоположения склада по умолчанию (пустой означает отсутствие значка)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Показать установленные складские позиции" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Отображать установленные складские позиции в складских таблицах" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Проверять спецификацию при установке изделий" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Установленные единица хранения должны присутствовать в спецификации для родительской детали" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Разрешить передачу товара, отсутствующего на складе" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Разрешить перемещение товаров, которых нет на складе, между складами" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "По умолчанию объединять запас с существующим при перемещении" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "Состояние по умолчанию для объединения запаса при перемещении. При необходимости можно изменить для отдельного перемещения" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Паттерн ссылки заказа на производство" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Поле требуемого паттерна для создания ссылки заказа на производство" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Требуется ответственный владелец" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Ответственный владелец должен быть назначен для каждого заказа" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Требовать активную деталь" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Запрещать создание заказов на сборку для неактивных деталей" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Требовать заблокированную деталь" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Запрещать создание заказов на сборку для разблокированных деталей" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Требовать валидную спецификацию" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Запрещать создание заказов на сборку, пока спецификация не будет подтверждена" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Требовать закрытия дочерних заказов" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Запрещать завершение заказа на сборку, пока не закрыты все дочерние заказы" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Сторонний заказ на сборку" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Включить функциональность сторонних заказов на сборку" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" -msgstr "" +msgstr "Требовать внешние производственные заказы" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" -msgstr "" +msgstr "Требовать внешний производственный заказ при заказе сборочных деталей у внешнего поставщика" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Блокировать до прохождения тестов" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Запретить вывод сборки до тех пор, пока не пройдут все необходимые тесты" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Включить заказы на возврат" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Включите функцию заказа на возврат в пользовательском интерфейсе" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Шаблон заказа на возврат товара" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Необходимый шаблон для создания поля «Возврат заказа»" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Редактировать завершенные возвратные заказы" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Разрешить редактирование возвращенных заказов после их завершения" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Шаблон заказа на возврат товара" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Необходимый шаблон для создания поля «Возврат заказа»" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Отгрузка по умолчанию для заказа на продажу" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Включить создание отгрузки по умолчанию для заказов на продажу" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Редактирование завершённых заказов на продажу" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Разрешить редактирование заказов на продажу после их отправки или завершения" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "Отгрузка требует проверки" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Запрещать завершение отгрузок, пока товары не проверены" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Отмечать отправленные заказы как завершённые" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Заказы на продажу, помеченные как отгруженные, будут автоматически завершены, минуя статус 'отгружено'" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "Включить заказы на перемещение" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "Включить функциональность заказов на перемещение в интерфейсе" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "Шаблон номера заказа на перемещение" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "Обязательный шаблон для формирования поля номера заказа на перемещение" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" -msgstr "" +msgstr "Блокировать позиции с незавершёнными тестами" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" -msgstr "" +msgstr "Запретить резервирование складских позиций для заказов на продажу, если обязательные тесты позиции не завершены" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Шаблон ссылки заказа на закупку" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Требуемый шаблон для генерации поля ссылки заказа на закупку" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Редактировать завершённые заказы на закупку" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Разрешить редактирование заказов после их отправки или завершения" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Конвертировать валюту" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Преобразовывать стоимость товара в базовую валюту при поступлении на склад" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Автоматически выполнять заказы на закупку" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Автоматически отмечать заказы на закупку как завершённые при получении всех позиций" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Включить функцию восстановления пароля" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Включить функцию восстановления пароля на странице входа" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Разрешить регистрацию" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Включить самостоятельную регистрацию пользователей на странице входа" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "Включить SSO" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Включить SSO на странице входа" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Включить регистрацию через SSO" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Включить самостоятельную регистрацию пользователей через SSO на странице входа" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Включить синхронизацию групп через SSO" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Включить синхронизацию групп InvenTree с группами, предоставляемыми IdP" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "Ключ группы SSO" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Имя атрибута группы, предоставленного провайдером идентификации" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "Отображение групп SSO" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Отображение от групп SSO к локальным группам InvenTree. Если локальная группа не существует, она будет создана." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Удалять группы вне SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Удалять ли группы, назначенные пользователю, если они не поддерживаются провайдером идентификации. Отключение этой настройки может привести к проблемам безопасности" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "Необходимо указать EMail" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Требовать электронную почту при регистрации" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Автозаполнение пользователей SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Автоматически заполнять данные пользователя из аккаунта SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Написать дважды" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "При регистрации дважды спрашивать адрес электронной почты" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Пароль дважды" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "При регистрации запросить пароль у пользователей дважды" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Разрешенные домены" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Ограничить регистрацию определёнными доменами (через запятую, начиная с @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Группа при новой регистрации" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Группа, на которую назначаются новые пользователи при регистрации. Если включена синхронизация группы SSO, эта группа задается только в том случае, если ни одна группа не может быть назначена через IdP." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Принудительное MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Пользователи должны использовать многофакторную безопасность." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "Включение этой настройки потребует от всех пользователей настройки многофакторной аутентификации. Все сессии будут отключены немедленно." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Проверять плагины при запуске" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Проверять, что все плагины установлены при запуске — включать в контейнерных средах" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Проверка обновлений плагинов" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Включить периодическую проверку обновлений установленных плагинов" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Включить интеграцию URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Разрешить плагинам добавлять маршруты URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Включить интеграцию навигации" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Разрешить плагинам интегрироваться в навигацию" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Включить интеграцию приложений" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Разрешить плагинам добавлять приложения" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Включить интеграцию расписаний" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Разрешить плагинам запускать запланированные задачи" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Включить интеграцию событий" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Разрешить плагинам реагировать на внутренние события" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Включить интеграцию интерфейса" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Разрешить плагинам интегрироваться в пользовательский интерфейс" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Включить интеграцию почты" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Разрешить плагинам обрабатывать исходящую и входящую почту" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Включить коды проекта" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "Включить коды проекта для отслеживания проектов" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "Включить инвентаризацию" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Включить функцию записи истории уровней и стоимости запасов" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Исключить сторонний склад" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "Исключить из инвентаризации единицы хранения на внешних складах" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Автоматический период инвентаризации" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "Кол-во дней между автоматических записей инвентаризации" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "Удалять устаревшие записи инвентаризаций" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "Удалять записи инвентаризаций старше N дней" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "Частота удаления записей инвентаризаций" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "Записи инвентаризации будут удалены после N дней" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "Удалять старые записи истории запасов" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "Удалять записи истории запасов старше указанного количества дней" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "Интервал удаления истории запасов" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "Записи истории запасов будут удалены через указанное количество дней" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Показывать полные имена пользователей" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Отображать полные имена пользователей вместо логинов" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Отображать профили пользователей" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Отображать профили пользователей на их странице профиля" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" -msgstr "" +msgstr "Неделя начинается с" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" -msgstr "" +msgstr "День начала недели для отображения в календарях" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" -msgstr "" +msgstr "Воскресенье" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" -msgstr "" +msgstr "Понедельник" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" -msgstr "" +msgstr "Вторник" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" -msgstr "" +msgstr "Среда" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" -msgstr "" +msgstr "Четверг" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" -msgstr "" +msgstr "Пятница" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" -msgstr "" +msgstr "Суббота" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "Горизонт календаря" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "Количество месяцев вперёд для отображения в календарях" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "месяцы" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Добавлять данные об испытательном оборудовании" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Добавлять данные об испытательном оборудовании в результаты тестирования" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "Включить пинг машин" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Включить периодическую задачу пинга зарегистрированных машин для проверки их статуса" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Количество результатов для отображения в каждом разделе окна предварительного поиска" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Поиск по Regex" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Разрешить регулярные выражения в поисковых запросах" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Поиск по целым словам" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Поисковые запросы возвращают результаты по полным совпадениям слов" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Поиск по заметкам" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Поисковые запросы возвращают результаты, соответствующие заметкам элемента" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Закрытие форм по клавише Escape" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Модальные окна можно закрывать с помощью клавиши Escape" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Фиксированная панель навигации" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Положение панели навигации фиксируется в верхней части экрана" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "Фиксированные заголовки таблицы" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Заголовки таблицы закреплены в верхней части таблицы" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Показывать Spotlight" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Включить функциональность Spotlight" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Значки навигации" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Отображать значки в панели навигации" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Формат даты" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Предпочтительный формат для отображения дат" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Показывать историю запасов" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Отображать информацию об истории запасов на странице детали" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Показывать последний элемент хлебных крошек" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Показывать текущую страницу в хлебных крошках" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "Показывать дополнительную информацию о модели" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "Показывать дополнительную информацию в выпадающих списках выбора модели" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Показывать полный путь местоположения в таблицах" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Выключено: полный путь местоположения отображается во всплывающей подсказке. Включено: полный путь местоположения отображается как обычный текст." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Показывать полные категории деталей в таблицах" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Выключено: полный путь категории отображается во всплывающей подсказке. Включено: полный путь категории отображается как обычный текст." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" -msgstr "" +msgstr "Показывать подсборки в таблице спецификации" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" -msgstr "" +msgstr "Включить отображение подсборок в таблице спецификации" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Получать отчёты об ошибках" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Получать уведомления о системных ошибках" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Последние использованные печатающие машины" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Сохранять последние использованные печатающие машины для пользователя" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" -msgstr "" +msgstr "Показывать позиции на конечном уровне" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" -msgstr "" +msgstr "По умолчанию автоматически показывать позиции/детали вместо подуровней для мест хранения или категорий без дочерних элементов" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Все модели" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Не указан тип модели вложения" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Недопустимый тип модели вложения" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "Размер файла превышает максимальный предел загрузки {max_size} МБ" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "Недопустимое имя файла" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Минимальное количество знаков не может быть больше максимального" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Максимальное количество знаков не может быть меньше минимального" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Пустой домен не допускается." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Недопустимое доменное имя: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Значение должно быть в верхнем регистре" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Значение должно быть допустимым идентификатором переменной" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Деталь активна" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Производитель активен" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Поставляемая деталь активна" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" -msgstr "" +msgstr "Основная деталь поставщика" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Внутренняя деталь активна" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Поставщик активен" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Производитель" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Компания" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Есть запас" @@ -4123,8 +4387,8 @@ msgstr "Контактный телефон" msgid "Contact email address" msgstr "Электронная почта контакта" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Контакт" @@ -4176,283 +4440,283 @@ msgstr "Налоговый идентификатор" msgid "Company Tax ID" msgstr "Налоговый идентификатор компании" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Адрес" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Адреса" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Выберите компанию" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Заголовок адреса" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Заголовок, описывающий запись адреса" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Основной адрес" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Указать основным адресом" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Строка 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Адресная строка 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Строка 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Адресная строка 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Почтовый индекс" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Город/Регион" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Почтовый индекс, город/регион" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Регион/Область" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Штат или провинция" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Страна" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Страна адреса" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Записи отправления" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Записи для курьера" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Внутренние записи отправления" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Записи отправления для внутреннего пользования" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Ссылка на адресную информацию (внешняя)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Производитель детали" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Базовая деталь" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Выберите деталь" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Выберите производителя" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "Артикул производителя" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Артикул производителя" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "Ссылка на сайт производителя" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Описание детали производителя" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Единицы измерения упаковки должны быть совместимы с единицами базовой детали" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Единицы упаковки должны быть больше нуля" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Связанная деталь производителя должна ссылаться на ту же базовую деталь" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Поставщик" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Выберите поставщика" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Артикул поставщика" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Является ли эта поставляемая деталь активной?" -#: company/models.py:792 -msgid "Primary" -msgstr "" - #: company/models.py:793 -msgid "Is this the primary supplier part for the linked Part?" -msgstr "" +msgid "Primary" +msgstr "Основной" -#: company/models.py:803 +#: company/models.py:794 +msgid "Is this the primary supplier part for the linked Part?" +msgstr "Это основная деталь поставщика для связанной детали?" + +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Выберите производителя части" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "Ссылка на сайт поставщика" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Описание детали поставщика" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "базовая стоимость" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Минимальная плата (например, складская)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Упаковка" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Упаковка детали" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Количество в упаковке" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Общее количество, поставляемое в одной упаковке. Оставьте пустым для отдельных элементов." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "множественные" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Кратность заказа" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Количество, доступное у поставщика" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Доступность обновлена" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Дата последнего обновления данных о доступности" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Ценовой порог поставщика" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Валюта по умолчанию для этого поставщика" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Название компании" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "На складе" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Ценовые пороги" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" -msgstr "" +msgstr "Отображаемое имя" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Произошла ошибка при экспорте данных" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Плагин экспорта данных вернул неправильный формат данных" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Формат экспорта" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Выберите формат файла экспорта" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Плагин экспорта" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Выберите плагин экспорта" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Дополнительная информация о состоянии складской позиции" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Пользовательский ключ статуса" @@ -4476,123 +4740,152 @@ msgstr "Оформлен" msgid "Invalid status code" msgstr "Недопустимый код статуса" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Файл данных" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Файл с данными импорта" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Столбцы" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Целевой тип модели для этой сессии импорта" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Статус импорта" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Значения по умолчанию" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Переопределения полей" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Фильтры полей" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Обновлять существующие записи" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Если включено, существующие записи будут обновлены новыми данными" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Некоторые обязательные поля не были сопоставлены" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "История количества завершённых строк" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "История количества строк" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Существующий идентификатор записи в базе данных" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "Колонка уже сопоставлена с полем базы данных" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Поле уже сопоставлено с колонкой данных" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Сопоставление столбцов должно быть связано с корректным сеансом импорта" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Колонка не существует в файле данных" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Поле не существует в целевой модели" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Выбранное поле доступно только для чтения" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "Поле поиска можно задать только для связанных полей (внешних ключей)" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "Недопустимое поле поиска. Допустимые варианты: {options}" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Сессия импорта" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Поле" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Колонка" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "Поле поиска" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "Поле базы данных для поиска по внешнему ключу. Оставьте пустым для автоматического поиска." + +#: importer/models.py:674 msgid "Row Index" msgstr "Номер строки" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Исходные данные строки" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Ошибки" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Корректный" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "Для обновления существующих записей требуется ID." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "Найдено несколько совпадений для значения — убедитесь, что значение уникально, или выберите конкретное поле поиска" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Запись с указанным ID не найдена" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Указан недействительный формат ID" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "Для обновления существующих записей требуется ID." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Неподдерживаемый формат файла данных" @@ -4600,43 +4893,47 @@ msgstr "Неподдерживаемый формат файла данных" msgid "Failed to open data file" msgstr "Не удалось открыть файл данных" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Недопустимые размеры файла данных" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Недопустимые значения по умолчанию для полей" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Недопустимые переопределения полей" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Недопустимые фильтры полей" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Строки" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Список идентификаторов строк, которые нужно принять" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Строки не предоставлены" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "Строка не принадлежит этой сессии" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "Строка содержит недопустимые данные" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "Строка уже завершена" @@ -4672,115 +4969,115 @@ msgstr "Файл данных содержит слишком много кол msgid "Data file contains too many rows" msgstr "Файл данных содержит слишком много строк" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Значение должно быть допустимым объектом словаря" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Копии" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Количество копий для печати каждой этикетки" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Подключен" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Неизвестно" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Печать" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Предупреждение" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Нет носителя" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Замятие бумаги" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Отключено" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Ошибка" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Принтер этикеток" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Печать этикеток для различных элементов напрямую." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Расположение принтера" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Ограничить принтер конкретным местоположением" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Название оборудования" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Тип оборудования" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Тип оборудования" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Драйвер" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Драйвер для подключения оборудования" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Оборудование может быть отключено" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Драйвер доступен" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Ошибок нет" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Инициализировано" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Статус машины" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Машина" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Конфигурация машины" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Тип конфигурации" @@ -4792,7 +5089,7 @@ msgstr "Ключ свойства" msgid "Value of the property" msgstr "Значение свойства" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Группа" @@ -4816,117 +5113,118 @@ msgstr "Максимальный прогресс" msgid "Maximum value for progress type, required if type=progress" msgstr "Максимальное значение для типа прогресса, требуется, если тип=progress" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Ссылка на заказ" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Невыполненный" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Есть код проекта" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Создал" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Создано до" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Создано после" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Есть дата начала" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Дата начала до" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Дата начала после" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Есть целевая дата" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Целевая дата до" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Целевая дата после" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" -msgstr "" +msgstr "Обновлено до" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" -msgstr "" +msgstr "Обновлено после" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Имеет цену" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Завершено до" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Завершено после" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Сторонний заказ на сборку" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Заказ" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Заказ выполнен" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Внутренняя деталь" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Заказ в ожидании" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Завершённые" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Есть отгрузка" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" -msgstr "" +msgstr "Отгрузка не найдена" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Заказ на закупку" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Заказ на закупку" msgid "Sales Order" msgstr "Заказ на продажу" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Заказ на возврат" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "Заказ на перемещение" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Общая стоимость" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Общая стоимость этого заказа" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Валюта заказа" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Валюта заказа (оставьте пустым для использования валюты по умолчанию для компании)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Этот заказ заблокирован и не может быть изменён" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Контакт не соответствует выбранной компании" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "Дата начала должна быть до целевой даты" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "Адрес не соответствует выбранной компании" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Описание заказа (дополнительно)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Выберите код проекта для этого заказа" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Ссылка на внешнюю страницу" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Начальная дата" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Запланированная начальная дата этого заказа" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Целевая дата" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Ожидаемая дата доставки заказа. После этой даты заказ будет считаться просроченным." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Дата создания" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Дата выдачи заказа" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" -msgstr "" +msgstr "Обновлено" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Пользователь или группа, ответственная за этот заказ" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Контактное лицо по данному заказу" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Адрес компании по этому заказу" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Ссылка на заказ" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Статус" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Статус заказа на закупку" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Компания, в которой детали заказываются" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Номер у поставщика" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Номер заказа у поставщика" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "получил" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Дата завершения заказа" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Место хранения" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Место хранения для полученных позиций" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Поставщик детали должен совпадать с поставщиком заказа на закупку" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Позиция не соответствует заказу на закупку" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "В позиции отсутствует связанная деталь" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Количество должно быть положительным числом" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" -msgstr "" +msgstr "Серийные номера нельзя назначать виртуальным деталям" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "Разрешить любой запас (с серийными номерами или без них)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "Только запас с серийными номерами" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "Только запас без серийных номеров" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Покупатель" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Компания, которой детали продаются" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Статус заказа на продажу" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Ссылка клиента" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Код ссылки на заказ клиента" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Дата отгрузки" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "Отправлено" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Позиция не связана с этим заказом" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Совпадений для следующих серийных номеров не найдено" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Следующие серийные номера недоступны" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Заказ уже выполнен" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Заказ уже отменен" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Только открытый заказ может быть отмечен как завершённый" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Заказ не может быть завершён, так как есть незавершённые отгрузки" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Заказ не может быть завершён, так как есть незавершённые распределения" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Заказ не может быть завершён, так как есть незавершённые позиции" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "Заказ заблокирован и не может быть изменён" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Количество" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" -msgstr "" +msgstr "Номер строки" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" -msgstr "" +msgstr "Номер строки для этой позиции (необязательно)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Номер позиции" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Записи о позиции" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Целевая дата этой позиции (оставьте пустой, чтобы использовать целевую дату заказа)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Описание позиции (необязательно)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Дополнительный контекст для этой строки" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Цена за единицу" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Позиция заказа на закупку" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Поставляемая деталь должна соответствовать поставщику" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "Заказ на сборку должен быть отмечен как внешний" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Заказы на сборку могут быть связаны только со сборочными деталями" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "Деталь заказа на сборку должна соответствовать детали позиции" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" -msgstr "" +msgstr "Для сборочных деталей требуется внешний производственный заказ" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Деталь поставщика" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Получено" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Количество полученных предметов" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Закупочная цена" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Закупочная цена" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Внешний заказ на сборку, который будет выполнен этой позицией" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Дополнительная позиция заказа на закупку" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Позиция заказа на продажу" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Только продаваемые детали могут быть назначены заказу на продажу" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Цена продажи" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Цена последней продажи" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Доставлен" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Отгруженное кол-во" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Отгрузка заказа на продажу" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "Адрес отгрузки должен соответствовать клиенту" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Адрес доставки для этой отгрузки" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Дата отправления" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Дата доставки" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Дата доставки отгрузки" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Проверн" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Пользователь, проверивший эту отгрузку" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Отправление" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Номер отправления" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Номер отслеживания" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Информация об отслеживании доставки" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Номер счета" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Номер ссылки на связанную накладную" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Отгрузка уже отправлена" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Отправка не имеет зарезервированных складских позиций" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "Отгрузка должна быть проверена, прежде чем её можно завершить" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Дополнительная позиция заказа на продажу" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Распределение заказа на продажу" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Складская позиция не была назначена" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Невозможно зарезервировать складскую позицию в позицию другой детали" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Невозможно распределить запас к позиции без детали" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Количество распределения не может превышать количество на складе" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Резервируемое количество должно быть больше нуля" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Количество должно быть 1 для сериализированных складских позиций" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Заказ на продажу не соответствует отгрузке" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Отгрузка не соответствует заказу на продажу" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Строка" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Ссылка на отгрузку заказа на продажу" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Элемент" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Выберите складскую позицию для резервирования" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Укажите резервируемое количество" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Ссылка на заказ на возврат" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Компания, из которой возвращаются товары" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Статус заказа на возврат" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Позиция заказа на возврат" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Необходимо указать складской элемент" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Количество возврата превышает количество на складе" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "Количество возврата должно быть больше нуля" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Недопустимое количество для серийного складского элемента" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Выберите позицию, возвращаемую от клиента" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Дата получения" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "Дата возврата" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Результат" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Результат для этой позиции" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Стоимость, связанная с возвратом или ремонтом этой позиции" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Дополнительная позиция заказа на возврат" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID заказа" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "Номер заказа на перемещение" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID заказа для дублирования" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "Статус заказа на перемещение" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Копировать позиции" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "Источник перемещаемых позиций" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Копировать позиции из исходного заказа" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "Назначение перемещаемых позиций" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Копировать дополнительные позиции" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "Списать запас" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Копировать дополнительные позиции из исходного заказа" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "Вместо перемещения запаса в место назначения списать его, удалив перемещаемое количество из зарезервированной складской позиции" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Скопировать параметры" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "Заказ нельзя завершить, пока не указано место назначения" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "Заказ нельзя завершить, пока он не будет полностью зарезервирован" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "Позиция заказа на перемещение" + +#: order/models.py:4027 +msgid "transferred" +msgstr "Перемещено" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "перемещённое количество" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "Резервирование заказа на перемещение" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" msgstr "" -#: order/serializers.py:112 +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Позиции" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Завершённые позиции" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Дублировать заказ" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "Пользовательский ключ статуса" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Указать параметры для дублирования этого заказа" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "Обновить статус заказа до пользовательского значения для этого логического значения" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Недействительный ID заказа" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "Пользовательский ключ статуса должен быть целым числом" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "Недопустимый пользовательский ключ статуса" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "Недопустимый пользовательский ключ статуса для этого статуса заказа" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Имя поставщика" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Заказ не может быть отменён" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Разрешить закрывать заказ с незавершёнными позициями" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "В заказе есть незавершённые позиции" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Заказ не открыт" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Автоматическая цена" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Автоматически рассчитывать закупочную цену на основе данных детали поставщика" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Валюта заказа на закупку" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Объединять элементы" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Объединять в одну позицию элементы, у которых одинаковая деталь, место хранения и целевая дата" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Артикул" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Внутренний артикул детали" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Внутреннее название детали" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Необходимо указать поставляемую деталь" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Необходимо указать заказ на закупку" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Поставщик должен соответствовать заказу на закупку" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Заказ на закупку должен соответствовать поставщику" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Позиция" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Выберите место назначения для полученных элементов" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Введите код партии для поступающих складских позиций" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Истекает" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "Введите дату истечения срока годности для поступающих складских единиц" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Введите серийные номера для входящих складских позиций" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Переопределить информацию об упаковке для поступающих складских единиц" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Дополнительная заметка для поступающих складских единиц" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Штрих-код" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Сканированный штрих-код" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Штрихкод уже используется" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Необходимо предоставить позиции" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Необходимо указать место назначения" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Предоставленные значения штрихкодов должны быть уникальными" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Отгрузки" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Выполненные отгрузки" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "Зарезервированные позиции" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Валюта цены продажи" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Выделенные элементы" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Информация об отгрузке не предоставлена" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Позиция не связана с этим заказом" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Количество должно быть положительным" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" -msgstr "" +msgstr "Складская позиция не прошла все обязательные тесты" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Введите серийные номера для резервирования" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Отгрузка уже отправлена" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Отгрузка не связана с этим заказом" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Совпадений для следующих серийных номеров не найдено" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "Место хранения, откуда берутся позиции (оставьте пустым, чтобы использовать любое место)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Следующие серийные номера недоступны" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "Исключить складские позиции из этого места хранения" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "Назначить резервирования этой отгрузке" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "Разрешить брать запас из нескольких мест хранения для выполнения одной позиции заказа" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "Запас с серийными номерами" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "Управляет включением складских позиций с серийными номерами в автоматическое резервирование" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "Ограничить резервирование этими позициями заказа (оставьте пустым, чтобы резервировать все строки)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "Позиция заказа не относится к этому заказу" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Позиция заказа на возврат" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Позиция не соответствует заказу на возврат" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Позиция уже получена" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Предметы могут быть получены только по заказам, которые находятся в процессе выполнения" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Количество для возврата" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Валюта цены позиции" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "Разрешить завершение заказа с неполными резервированиями" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "В заказе есть неполные резервирования" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Потерян" @@ -5718,1279 +6125,1312 @@ msgstr "Потерян" msgid "Returned" msgstr "Возвращён" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Выполняется" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Возврат" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Починить" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Заменить" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Возврат" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Отклонён" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Оформлен" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Просроченные заказы на закупку" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Заказ на закупку {po} просрочен" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Просроченные заказы на продажу" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Заказ на продажу {so} просрочен" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Просроченный заказ на возврат" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "Заказ на возврат {ro} просрочен" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Помечено звёздочкой" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Фильтровать по отмеченным категориям" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Глубина" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Фильтровать по глубине категории" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Верхний уровень" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Фильтровать по категориям верхнего уровня" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Каскад" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Включать подкатегории в отфильтрованные результаты" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Родитель" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Фильтровать по родительской категории" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Исключить подкатегории указанной категории" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "Максимальный уровень" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "Ограничить глубину дерева категорий" + +#: part/api.py:442 msgid "Has Results" msgstr "Есть результаты" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Является вариантом" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Является ревизией" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Есть ревизии" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "Спецификация валидна" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Каскадные категории" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Если включено, включать элементы в дочерних категориях указанной категории" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Фильтровать по числовому идентификатору категории или литералу 'null'" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "Сборочная деталь активна" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "Отслеживаемая сборочная деталь" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Сборная деталь тестируется" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" -msgstr "" +msgstr "Сборочная деталь заблокирована" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "Деталь компонента активна" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "Отслеживаемая деталь компонента" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Компонент тестируется" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "Сборочная деталь компонента" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "Виртуальная деталь компонента" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "На складе" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Использования" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Категория детали" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Категория детали" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Место хранения по умолчанию" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Место хранения по умолчанию для деталей этой категории" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Структура" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Детали не могут быть непосредственно отнесены к структурной категории, но могут быть отнесены к дочерним категориям." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Ключевые слова по умолчанию" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Ключевые слова по умолчанию для деталей этой категории" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Значок" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Значок (необязательно)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Вы не можете сделать эту категорию деталей структурной, потому что некоторые детали уже назначены ей!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Шаблон параметров категории деталей" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Значение по умолчанию" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Значение параметра по умолчанию" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Детали" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "Нельзя удалить параметры заблокированной детали" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "Нельзя изменить параметры заблокированной детали" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Нельзя удалить эту деталь, так как она заблокирована" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Нельзя удалить эту деталь, так как она ещё активна" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Нельзя удалить эту деталь, так как она используется в сборке" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Деталь '{self}' не может быть использована в спецификации для '{parent}' (рекурсивно)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Деталь '{parent}' используется в спецификации для '{self}' (рекурсивно)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN должен соответствовать регулярному выражению {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Деталь не может быть ревизией самой себя" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" -msgstr "" +msgstr "Для детали, отмеченной как ревизия, необходимо указать код ревизии" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Ревизии разрешены только для сборочных деталей" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Нельзя сделать ревизию шаблонной детали" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "Родительская деталь должна указывать на тот же шаблон" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Складская позиция с этим серийным номером уже существует" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Дублирующий IPN не разрешён в настройках детали" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Дублирующая ревизия детали уже существует." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Деталь с таким именем, внутренним артикулом и ревизией уже существует." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Детали не могут быть назначены структурным категориям!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Наименование детали" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Шаблон" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Эта деталь является шаблоном?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Эта деталь является разновидностью другой детали?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Разновидность" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Описание детали (необязательно)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Ключевые слова" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Ключевые слова для улучшения видимости в результатах поиска" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Категория" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "Внутренний артикул" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Ревизия или серийный номер детали" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Ревизия" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Является ли эта деталь ревизией другой детали?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Ревизия от" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Где обычно хранится эта деталь?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Срок действия по умолчанию" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Срок годности (в днях) для складских позиций этой детали" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Минимальный запас" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Минимально допустимый складской запас" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" -msgstr "" +msgstr "Максимальный запас" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" -msgstr "" +msgstr "Максимально допустимый уровень запаса" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Единицы измерения этой детали" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Может ли эта деталь быть создана из других деталей?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Может ли эта деталь использоваться для создания других деталей?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Является ли каждый экземпляр этой детали уникальным, обладающим серийным номером?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Можно ли в этой детали записывать результаты тестов?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Может ли эта деталь быть закуплена у внешних поставщиков?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Может ли эта деталь быть продана покупателям?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Эта деталь активна?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Заблокированные детали нельзя редактировать" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Эта деталь виртуальная, как программный продукт или лицензия?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "Эта деталь является расходным материалом, например клеем или крепежом?" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "Спецификация подтверждена" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Валидна ли спецификация для этой детали?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Контрольная сумма BOM" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Сохранённая контрольная сумма спецификации" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOM проверил" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Дата проверки BOM" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Создатель" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Ответственный владелец этой детали" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Продать несколько" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Валюта, используемая для кэширования расчётов цен" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Минимальная Стоимость BOM" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Минимальная стоимость компонентных деталей" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Максимальная Стоимость BOM" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Максимальная стоимость компонентных деталей" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Минимальная стоимость закупки" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Минимальная историческая стоимость закупки" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Максимальная стоимость закупки" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Максимальная историческая стоимость закупки" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Минимальная внутренняя цена" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Минимальная стоимость на основе внутренних ценовых уровней" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Максимальная внутренняя цена" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Максимальная стоимость на основе внутренних ценовых уровней" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Минимальная цена поставщика" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Минимальная цена детали от внешних поставщиков" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Максимальная цена поставщика" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Максимальная цена детали от внешних поставщиков" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Минимальная стоимость варианта" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Расчётная минимальная стоимость вариантов деталей" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Максимальная стоимость варианта" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Расчётная максимальная стоимость вариантов деталей" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Минимальная Стоимость" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Переопределить минимальную стоимость" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Максимальная Стоимость" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Переопределить максимальную стоимость" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Расчётная общая минимальная стоимость" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Расчётная общая максимальная стоимость" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Минимальная цена продажи" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Минимальная цена продажи на основе ценовых уровней" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Максимальная цена продажи" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Максимальная цена продажи на основе ценовых уровней" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Минимальная стоимость продажи" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Минимальная историческая цена продажи" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Максимальная стоимость продажи" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Максимальная историческая цена продажи" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Деталь для инвентаризации" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Количество элементов" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Количество отдельных складских позиций на момент инвентаризации" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Общий доступный запас на момент инвентаризации" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Дата" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Дата проведения инвентаризации" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Минимальная стоимость запасов" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Оценочная минимальная стоимость имеющихся запасов" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Максимальная стоимость запасов" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Оценочная максимальная стоимость имеющихся запасов" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Цена продажи детали по порогу" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "Внутренний ценовой порог детали" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Шаблон теста детали" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Недопустимое имя шаблона — должно содержать хотя бы один буквенно-цифровой символ" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Шаблоны тестов можно создавать только для тестируемых деталей" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Шаблон теста с тем же ключом уже существует для детали" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Название теста" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Введите имя для теста" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Ключ теста" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Упрощённый ключ для теста" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Описание теста" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Введите описание для этого теста" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Активен ли данный тест?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Необходим" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Необходимо ли пройти этот тест?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Требуется значение" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Требуется ли значение для этого теста при добавлении результата?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Требуются вложения" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Требуется ли прикреплять вложение в виде файла при добавлении результатов теста?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Допустимые варианты данного теста(через запятую)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" -msgstr "" +msgstr "Недопустимое количество: для детали не указаны единицы измерения" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" -msgstr "" +msgstr "Количество должно быть больше или равно нулю" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "Пункт спецификации нельзя изменить — сборка заблокирована" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Пункт спецификации нельзя изменить — вариант сборки заблокирован" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Выберите родительскую деталь" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Суб-деталь" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Выбрать деталь для использования в BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" -msgstr "" +msgstr "Количество" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" -msgstr "" +msgstr "Количество вложенной детали, расходуемое для производства одной детали" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Количество элементов в спецификации" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Эта позиция спецификации необязательна" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Эта позиция - расходник (она не отслеживается в заказах на производство)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Количество для подготовки" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Дополнительное требуемое количество для сборки, учитывающее потери при подготовке" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Потери" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Оценочные потери для сборки, выраженные в процентах (0–100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Округление до кратности" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Округлять требуемое производственное количество до ближайшего кратного этого значения" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Ссылка на позицию спецификации" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Заметка о позиции в спецификации" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Контрольная сумма" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Контрольная сумма строки спецификации" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Проверен" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Этот пункт спецификации подтверждён" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Наследуется" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Позиция спецификации наследуется разновидностями детали" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Эту позицию можно заменять деталями, которые находятся на складе" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Для отслеживаемых деталей количество должно быть целым числом" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Необходимо указать поддеталь" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Замена пункта спецификации" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Деталь для замены не может быть такой же, как основная деталь" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Позиция BOM-родителя" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Замена детали" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Деталь 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Деталь 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Выберите связанную деталь" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Заметка для данной связи" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Нельзя создать отношение детали с самой собой" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Дублирующее отношение уже существует" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "Удалить подкатегории" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "Удалить все подкатегории внутри этой категории" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "Удалить детали" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "Удалить все детали внутри этой категории" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Родительская категория" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Родительская категория деталей" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Подкатегории" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Результаты" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Количество результатов, зарегистрированных по этому шаблону" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Валюта закупки складской позиции" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Файл не является изображением" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Оригинальная деталь" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Выберите исходную деталь для копирования" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Копировать Изображение" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Копировать изображение из исходной детали" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Скопировать BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Копировать спецификацию из исходной детали" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Копировать данные параметров из исходной детали" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Копировать Записи" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Скопировать записи из оригинальной детали" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Копировать тесты" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "Копировать шаблоны тестов из исходной детали" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Начальное количество на складе" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Задайте начальное количество этой детали на складе. Если количество равно 0, складская позиция не будет добавлена." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Начальное местоположение запаса" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Укажите начальное местоположение запаса для этой детали" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Выберите поставщика (или оставьте поле пустым, чтобы пропустить)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Выберите поставщика (или оставьте поле пустым, чтобы пропустить)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Артикул производителя" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Выбранная компания не является допустимым поставщиком" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Выбранная компания не является допустимым производителем" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Деталь производителя с данным артикулом уже существует" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Деталь поставщика с данным артикулом уже существует" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Название категории" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Производится" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Количество этой детали, находящееся в производстве" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Оставшееся количество этой детали, запланированное к сборке" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Складские позиции" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Ревизии" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Общий запас" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Нераспределённый запас" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Запас вариантов" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Дублировать деталь" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Копировать начальные данные из другой детали" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Копировать Изображение" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Копировать изображение из исходной детали" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Скопировать BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Копировать спецификацию из исходной детали" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Копировать Записи" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Скопировать записи из оригинальной детали" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Копировать тесты" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Копировать шаблоны тестов из исходной детали" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Начальный запас" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Создавать деталь с начальным количеством на складе" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Информация о поставщике" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Добавить начальную информацию о поставщике для этой детали" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Копировать параметры категории" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Копировать шаблоны параметров из выбранной категории деталей" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Существующее изображение" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Имя файла существующего изображения детали" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Файл изображения не существует" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Проверить всю спецификацию" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Можно произвести" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Требуется для заказов на сборку" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Выделено для заказов на сборку" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Требуется для заказов на продажу" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Выделено для заказов на продажу" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "Внутренний артикул детали" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "Описание детали" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "Выберите деталь (и любые её варианты) для которой сгенерировать информацию об инвентаризации" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "Выберите категорию (и любые её подкатегории) для которой сгенерировать информацию об инвентаризации" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "Выберите склад, чтобы включить все детали в наличии в указанном складе (включая подразделы)" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "Создать записи инвентаризации" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "Сохранить записи инвентаризации для выбранных деталей" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "Создать отчет" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "Создать отчёт инвентаризации для выбранных деталей" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Минимальная цена" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Переопределить рассчитанное значение минимальной цены" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Валюта минимальной цены" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Максимальная цена" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Переопределить рассчитанное значение максимальной цены" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Валюта максимальной цены" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Обновить" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Обновить цены для этой детали" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Не удалось конвертировать из предоставленных валют в {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Минимальная цена не должна превышать максимальную цену" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Максимальная цена не должна быть меньше минимальной" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" -msgstr "" +msgstr "Количество, необходимое для этой позиции (может включать единицы измерения)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Выберите родительскую сборку" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Выберите деталь, которая является компонентом" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" -msgstr "" +msgstr "Недопустимый формат количества" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Выберите деталь, из которой копировать спецификацию" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Удалить существующие данные" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Удалить существующие пункты спецификации перед копированием" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Включая наследуемые" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Включать пункты спецификации, унаследованные от шаблонных деталей" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Пропустить некорректные строки" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Включите эту опцию, чтобы пропускать недопустимые строки" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Копировать детали-заменители" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Копировать детали-заменители при дублировании пунктов спецификации" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Уведомление о низком уровне запаса" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Доступный запас для {part.name} упал ниже настроенного минимального уровня" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "Уведомление о просроченном запасе" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "У вас 1 складская единица приближается к дате истечения срока годности" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "У вас {item_count} складских единиц приближаются к дате истечения срока годности" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "Нет даты истечения" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "Истёк {abs(days_diff)} дней назад" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Истекает сегодня" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} дней" @@ -7011,7 +7451,7 @@ msgstr "Пример" msgid "Installed" msgstr "Установлено" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Плагин не может быть удалён, так как он активен" @@ -7023,23 +7463,23 @@ msgstr "Действие не указано" msgid "No matching action found" msgstr "Соответствующее действие не найдено" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Не найдено совпадений для данных штрих-кода" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Найдено совпадение по штрих-коду" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Модель не поддерживается" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Экземпляр модели не найден" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Штрихкод соответствует существующему элементу" @@ -7055,51 +7495,67 @@ msgstr "Не найдено соответствующих поставляем msgid "Multiple matching supplier parts found" msgstr "Найдено несколько соответствующих поставляемых деталей" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Плагин, соответствующий данным штрихкода, не найден" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Соответствующая поставляемая деталь" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Предмет уже был получен" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "Заказ на закупку найден\\rНет совпадения с деталью поставщика" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "Деталь поставщика найдена\\rНет совпадения с заказом на закупку" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Нет совпадения плагина для штрихкода поставщика" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Найдено несколько соответствующих позиций" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Не найдено соответствующей позиции" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Заказ на продажу не указан" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Штрих-код не соответствует существующим складским позициям" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Складская позиция не соответствует позиции" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Недостаточно запаса" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Складская позиция зарезервирована заказом на продажу" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Недостаточно информации" @@ -7108,23 +7564,23 @@ msgstr "Недостаточно информации" msgid "Found matching item" msgstr "Найден соответствующий элемент" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Поставляемая деталь не соответствует позиции" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Позиция уже завершена" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Для получения позиции требуется дополнительная информация" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Полученная позиция заказа на закупку" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Не удалось получить позицию" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Предоставляет встроенную поддержку штрихкодов" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Префикс короткого штрихкода" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Настройте префикс, используемый для коротких штрихкодов, что может быть полезно в средах с несколькими экземплярами InvenTree" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "Автоматически создавать сборки" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "Автоматически создавать заказы на сборку для сборочных изделий" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "Включать варианты" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "Включать запас вариантов детали в расчёты цен" +msgid "Include part variant stock in stocktake data" +msgstr "Включать запас вариантов детали в данные инвентаризации" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "Исключить записи с нулевым запасом" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "Исключить детали с нулевым запасом из экспортируемого набора данных" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "Экспортёр инвентаризации деталей" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "Экспортёр данных инвентаризации деталей" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "Минимальная стоимость за единицу" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "Максимальная стоимость за единицу" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "Минимальная общая стоимость" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "Максимальная общая стоимость" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "Уведомления интерфейса InvenTree" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "Интегрированные методы уведомлений в интерфейсе" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "Уведомления по электронной почте InvenTree" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "Интегрированные методы уведомлений по электронной почте" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "Разрешить уведомления по электронной почте" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "Разрешить отправку уведомлений по электронной почте этому пользователю" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "Уведомления Slack InvenTree" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "Интегрированные методы уведомлений Slack" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "Ссылка \"Slack incoming webhook\"" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL, используемый для отправки сообщений в канал Slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Открыть ссылку" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Предоставляет встроенную поддержку печати этикеток PDF" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Режим отладки" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Включить режим отладки — возвращает чистый HTML вместо PDF" @@ -7653,55 +8117,55 @@ msgstr "последнее использование" msgid "Options" msgstr "Параметры" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Размер страницы для листа этикеток" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Пропустить Этикетки" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Пропустить это количество этикеток при печати листов" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Граница" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Печатать рамку вокруг каждой этикетки" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Альбомная" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Печатать лист этикеток в альбомной ориентации" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Поле страницы" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Поле вокруг страницы в мм" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "Печать листов этикеток InvenTree" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Размещает несколько этикеток на одном листе" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Этикетка слишком большая для размера страницы" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Не было создано ни одной этикетки" @@ -7753,77 +8217,85 @@ msgstr "Предоставляет поддержку сканирования msgid "The Supplier which acts as 'TME'" msgstr "Поставщик, который представляет 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 -#: plugin/serializers.py:275 -msgid "Only superuser accounts can administer plugins" +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "Управлять плагинами могут только учётные записи суперпользователей" + +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Установка плагинов отключена" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" -msgstr "" +msgstr "Не указано имя пакета или URL для установки" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" -msgstr "" +msgstr "Недопустимые символы в имени пакета или URL" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Плагин успешно установлен" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Плагин установлен в {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Плагин не найден в реестре" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Плагин не является упакованным" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Имя пакета плагина не найдено" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Только пользователи с правами персонала могут управлять плагинами" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Удаление плагинов отключено" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Плагин нельзя удалить, так как он активен" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Плагин нельзя удалить, так как он обязательный" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Плагин нельзя удалить, так как он является образцом" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "Плагин нельзя удалить, так как он встроенный" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Плагин не установлен" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Установка плагина не найдена" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Плагин успешно удалён" @@ -7871,25 +8343,25 @@ msgstr "Обязательный плагин" msgid "Package Plugin" msgstr "Пакетный плагин" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Плагин" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Автор не найден" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Плагин '{p}' несовместим с текущей версией InvenTree {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Плагин требует как минимум версию {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Плагин требует не более версии {v}" @@ -8114,200 +8586,208 @@ msgstr "Удалить конфигурацию" msgid "Delete the plugin configuration from the database" msgstr "Удалить конфигурацию плагина из базы данных" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "Показывает, переопределена ли настройка конфигурацией" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "Пользователь, для которого применяется эта настройка" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Элементы" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Плагин не найден" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Плагин не поддерживает печать этикеток" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "У вас нет разрешёния на просмотр этого типа модели" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Недопустимые размеры этикетки" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Ни одного допустимого элемента не предоставлено для шаблона" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Правовая информация" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Письмо" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Файл шаблона с таким именем уже существует" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Название шаблона" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Описание шаблона" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Номер ревизии (автоматически)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Прикреплять к модели при печати" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Сохранять отчёт как вложение к связанному экземпляру модели при печати" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Шаблон имени файла" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Шаблон для создания имён файлов" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Шаблон включён" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Тип модели шаблона" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Фильтры" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Фильтры запроса шаблона (список ключ=значение через запятую)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Файл шаблона" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Размер страницы для PDF-отчётов" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Рендерить отчёт в альбомной ориентации" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "Объединить" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "Рендерить один отчёт по выбранным элементам" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "Отчёт, сгенерированный из шаблона {self.name}" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "Синтаксическая ошибка в шаблоне" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "Ошибка при рендеринге отчёта" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Ошибка при генерации отчёта" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "Ошибка при объединении выводов отчётов" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Ширина [мм]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Ширина этикетки, задаётся в миллиметрах" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Высота [мм]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Высота этикетки, задаётся в миллиметрах" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Ошибка при печати этикеток" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Сниппет" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Файл фрагмента отчёта" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Описание файла сниппета" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Объект" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Файл ресурса отчёта" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Описание медиафайла" #: report/serializers.py:37 msgid "User must be authenticated to save report templates" -msgstr "" +msgstr "Пользователь должен быть аутентифицирован, чтобы сохранять шаблоны отчётов" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Выберите шаблон отчёта" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Список первичных ключей элементов, включаемых в отчёт" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Выберите шаблон этикетки" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Плагин печати" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Выберите плагин для печати этикеток" @@ -8338,13 +8818,10 @@ msgstr "Необходимые материалы" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Изображение детали" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Оформлен" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Требуется для" @@ -8380,8 +8857,8 @@ msgstr "Всего" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Серийный номер" @@ -8405,7 +8882,7 @@ msgstr "Отчет тестирования складской позиции" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Установленные элементы" @@ -8438,810 +8915,922 @@ msgstr "Нет результата (обязательно)" msgid "No result" msgstr "Нет результата" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "Перемещено" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" -msgstr "" +msgstr "Недопустимый путь к медиафайлу" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" -msgstr "" +msgstr "Недопустимый путь к статическому файлу" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" -msgstr "" +msgstr "Файл ресурса не найден" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Файл изображения не найден" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" -msgstr "" +msgstr "Файл изображения не указан" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "Тег part_image требует экземпляр детали" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "Тег company_image требует экземпляр компании" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Фильтровать по глубине местоположения" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Фильтровать по местоположениям верхнего уровня" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Включать подместоположения в отфильтрованные результаты" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Основной склад" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Фильтровать по родительскому местоположению" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Название детали (без учёта регистра)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Название детали содержит (без учёта регистра)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Название детали (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "IPN детали (без учёта регистра)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "IPN детали содержит (без учёта регистра)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "IPN детали (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Минимальный запас" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Максимальный запас" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Код статуса" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Внешнее местоположение" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Израсходовано для заказов на сборку" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Установлено в другом складе" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Древо Деталей" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Обновлено до" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Обновлено после" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Инвентаризация до" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Инвентаризация после" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "Есть дата инвентаризации" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Дата истечения до" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Дата истечения после" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Залежалый" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "Укажите первичный ключ складского элемента, чтобы исключить этот элемент и всех его потомков" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "Каскад местоположений" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "Если включено, включать элементы в дочерних местоположениях данного местоположения" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Фильтровать по числовому идентификатору местоположения или литералу 'null'" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Необходимо указать количество" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Необходимо предоставить действительную деталь" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Указанная поставляемая деталь не существует" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "У поставляемой детали определён размер упаковки, но флаг use_pack_size не установлен" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Не нужно указывать серийные номера для неотслеживаемых деталей" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "Включать установленные" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Если включено, включать результаты тестов для предметов, установленных под данным складским элементом" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "Фильтровать по числовому идентификатору складского элемента" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Складской элемент с ID {id} не существует" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "Включая варианты деталей" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "После" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "До" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Тип местоположения склада" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Типы местоположения склада" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Значок по умолчанию для мест хранения с невыбранным значком (необязательно)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Место хранения" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Места хранения" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Владелец" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Выберите владельца" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Складские позиции не могут находиться в структурных местах хранения, но могут находиться в дочерних местах хранения." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Внешний" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Это сторонний склад" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Тип места хранения" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Тип места хранения данного склада" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Вы не можете сделать это место хранение структурным, потому, что некоторые складские позиции уже находятся в нем!" -#: stock/models.py:537 -msgid "Serialized stock items cannot be deleted" -msgstr "" +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "Сначала самый старый запас (FIFO)" -#: stock/models.py:674 +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "Сначала самый новый запас (LIFO)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "Сначала наименьшее количество" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "Сначала наибольшее количество" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "Сначала ближайшая дата истечения срока" + +#: stock/models.py:582 +msgid "Serialized stock items cannot be deleted" +msgstr "Складские позиции с серийными номерами нельзя удалить" + +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field} не существует" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Необходимо указать деталь" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Складские позиции не могут находиться в структурных местах хранения!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "Изменение серийных номеров запрещено: этой позиции уже назначен серийный номер" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Складская позиция не может быть создана для виртуальных деталей" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Тип детали ('{self.supplier_part.part}') должен быть {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Количество должно быть 1 для элемента с серийным номером" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Серийный номер нельзя задать, если количество больше 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Элемент не может принадлежать сам себе" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Элемент должен иметь ссылку на производство, если is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Ссылка на производство не указывает на тот же элемент" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Складская позиция" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Базовая деталь" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Выберите соответствующего поставщика детали для этой складской позиции" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Где находится эта складская позиция?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Упаковка этой складской позиции хранится в" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Установлено в" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Установлен ли этот элемент в другой элемент?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Серийный номер для этого элемента" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Код партии для этой складской позиции" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Количество на складе" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Исходное производство" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Производства для этой складской позиции" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Поглощен" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Заказ на производство, который поглотил эту складскую позицию" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Исходный заказ на закупку" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Заказ на закупку для этой складской позиции" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Целевой заказ на продажу" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Дата истечения срока годности для складской позиции. Остатки будут считаться просроченными после этой даты" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "Дата создания этой складской позиции" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Удалить при обнулении" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Удалить эту складскую позицию при обнулении складского запаса" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Цена за единицу на момент покупки" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Преобразовано в деталь" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "Количество превышает доступный запас" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "Нельзя назначить запас в структурное местоположение" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Деталь не является отслеживаемой" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Количество должно быть целым числом" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Количество не должно превышать доступный запас ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Серийные номера должны быть предоставлены в виде списка" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Количество не соответствует серийным номерам" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "Нельзя назначить запас в структурное местоположение" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Шаблон теста не существует" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Складская позиция была назначена заказу на продажу" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Складская позиция установлена в другую деталь" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Складская позиция содержит другие детали" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Складская позиция была назначена покупателю" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Складская позиция в производстве" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Серийные запасы нельзя объединить" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Дублирующие складские элементы" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Складские позиции должны ссылаться на одну и ту же деталь" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Складские позиции должны ссылаться на одну и ту же деталь поставщика" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Коды статуса запаса должны совпадать" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Складской элемент нельзя переместить, так как он отсутствует на складе" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Отслеживание складского элемента" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Заметки к записи" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Результат теста складского элемента" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Для этого теста должно быть указано значение" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Для этого теста требуется загрузить вложения" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "Недопустимое значение для этого теста" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Результат тестирования" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Результат выполнения теста" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Вложение с результатом теста" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Заметки о тестировании" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Испытательное оборудование" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "Идентификатор испытательного оборудования, на котором выполнялось тестирование" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Запущен" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Время начала тестирования" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Завершён" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Время окончания тестирования" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Сгенерированный код партии" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Выбрать заказ на сборку" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Выберите складской элемент для генерации кода партии" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Выберите место для генерации кода партии" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Выберите деталь для генерации кода партии" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Выберите заказ на закупку" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Введите количество для кода партии" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Сгенерированный серийный номер" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Выберите деталь для генерации серийного номера" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Количество серийных номеров для генерации" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Шаблон теста для этого результата" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "Для этой детали не найдено подходящего теста" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "Необходимо указать ID шаблона или имя теста" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "Время завершения теста не может быть раньше времени начала" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Родительский элемент" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Родительский складской элемент" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Использовать размер упаковки при добавлении: заданное количество — это количество упаковок" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "Использовать размер упаковки" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Введите серийные номера для новых элементов" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Номер детали поставщика" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Просрочен" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Дочерние элементы" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Отслеживание элементов" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Закупочная цена для этой складской позиции, за единицу или за упаковку" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Введите количество складских позиций для сериализации" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "Складской элемент не предоставлен" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Количество не должно превышать доступный запас ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Целевое место хранения" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Серийные номера не могут присваиваться данной детали" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Серийные номера уже существуют" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Выберите складскую позицию для установки" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Количество для установки" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Введите количество элементов для установки" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Добавить запись к транзакции (необязательно)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Количество для установки должно быть не менее 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Складская позиция недоступна" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Выбранная деталь отсутствует в спецификации" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Количество для установки не должно превышать доступное количество" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Место назначения для демонтированного элемента" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Выберите деталь в которую будет преобразована складская позиция" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Выбранная деталь не является допустимым вариантом для преобразования" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Невозможно преобразовать складскую позицию с назначенной деталью поставщика" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Статус складской позиции" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Выберите деталь в которую будет преобразована складская позиция" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Выбранная деталь не является допустимым вариантом для преобразования" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Невозможно преобразовать складскую позицию с назначенной деталью поставщика" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Выберите складские позиции для изменения статуса" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Не выбрано ни одной складской позиции" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Места хранения" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "Удалить складские позиции" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "Удалить все складские позиции в этом месте хранения" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "Удалить вложенные места хранения" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "Удалить все вложенные места хранения внутри этого места хранения" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Родительское местоположение запаса" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Деталь должна быть продаваемой" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Элемент распределён в заказ на продажу" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "Позиция зарезервирована для заказа на перемещение" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Элемент зарезервирован для заказа на производство" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Покупатель для назначения складских позиций" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Выбранная компания не является покупателем" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Записи о назначенных запасах" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Необходимо предоставить список складских позиций" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Заметки об объединении складских позиций" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Разрешить несоответствие поставщиков" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Разрешить объединение складских позиций с различными поставщиками" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Разрешить несоответствие статусов" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Разрешить объединение складских позиций с различными статусами" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Необходимо предоставить как минимум 2 складские позиции" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Нет изменений" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Первичный ключ складского элемента" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Складской элемент отсутствует на складе" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "Складской элемент уже на складе" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "Количество не должно быть отрицательным" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Заметки об изменении склада" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "Объединить с существующим запасом" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "По возможности объединить эту позицию с существующим запасом в месте назначения" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Заметки об изменении склада" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "Указать место хранения для подсчитанных позиций (необязательно)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "Объединять возвращённые элементы с существующими складскими элементами, если возможно" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Следующий серийный номер" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Предыдущий серийный номер" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Объединенные складские позиции" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Преобразовать в разновидность" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Создан выход продукции для этого заказа на производство" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Продукция заказа на производство завершена" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Продукция заказа на производство отклонена" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Поглощен заказом на производство" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Отгружено по заказу на продажу" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Получено по заказу на поставку" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Возвращено по заказу на возврат" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Отправлено клиенту" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Возвращено от клиента" @@ -9527,19 +10124,19 @@ msgstr "Пользователи" msgid "Select which users are assigned to this group" msgstr "Выберите пользователей, назначенных в эту группу" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Персональная информация" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Права доступа" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Важные даты" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Токен был отозван" @@ -9547,279 +10144,283 @@ msgstr "Токен был отозван" msgid "Token has expired" msgstr "Срок действия токена истёк" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API токен" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Токены API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Название токена" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Название пользовательского токена" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Дата истечения срока действия токена" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Последнее Посещение" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Последнее время использования токена" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Отозван" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Права доступа" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Вид" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Разрешение на просмотр элементов" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Добавить" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Разрешение на добавление элементов" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Изменить" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Разрешение на редактирование элементов" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Удалить" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Разрешение на удаление элементов" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "Бот" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "Внутренний" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Гость" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Язык" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "Предпочтительный язык пользователя" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Тема" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Настройки веб-интерфейса в формате JSON — не редактировать вручную!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "Виджеты" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "Настройки виджетов панели в формате JSON — не редактировать вручную!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Отображаемое имя" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Отображаемое имя пользователя" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Положение" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Основное место работы или должность" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Статусное сообщение пользователя" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Информация о местоположении пользователя" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "Пользователь активно использует систему" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Предпочтительная контактная информация пользователя" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Тип пользователя" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "Какого типа этот пользователь?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Организация" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Основная организация/принадлежность пользователя" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Основная группа" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Основная группа для пользователя" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Админ" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" -msgstr "" +msgstr "Спецификации" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Заказы на закупку" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Заказы на продажу" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Заказы на возврат" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "Заказы на перемещение" + +#: users/serializers.py:196 msgid "Username" msgstr "Логин" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Имя" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Имя пользователя" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Фамилия" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Фамилия пользователя" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Адрес электронной почты пользователя" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" -msgstr "" +msgstr "Пользователь должен быть аутентифицирован" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" -msgstr "" +msgstr "Только суперпользователь может создать токен для другого пользователя" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" -msgstr "" +msgstr "Администратор" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" -msgstr "" +msgstr "Есть ли у этого пользователя права администратора" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Суперпользователь" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Это пользователь является суперпользователем" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Активна эта учетная запись" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Только суперпользователь может изменить это поле" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Пароль" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "Пароль пользователя" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "Игнорировать предупреждение" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Игнорировать предупреждение о правилах пароля" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" -msgstr "" +msgstr "Персонал" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" -msgstr "" +msgstr "Есть ли у этого пользователя права сотрудника" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "У вас нет разрешения на создание пользователей" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Ваша учётная запись была успешно создана." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Пожалуйста, используйте функцию сброса пароля для входа" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Добро пожаловать в InvenTree" diff --git a/src/backend/InvenTree/locale/sk/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/sk/LC_MESSAGES/django.po index 83b0cd3b3c..8b5b5dc9b4 100644 --- a/src/backend/InvenTree/locale/sk/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/sk/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Slovak\n" "Language: sk_SK\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "" @@ -65,150 +69,155 @@ msgstr "" msgid "You must type the same email each time." msgstr "" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -216,159 +225,203 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5718,1279 +6125,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/sl/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/sl/LC_MESSAGES/django.po index e1349bc2fa..55d87dcb5f 100644 --- a/src/backend/InvenTree/locale/sl/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/sl/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Slovenian\n" "Language: sl_SI\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API vmesnik ni najden" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Uporabnik nima dovoljenja pogleda tega modela" @@ -65,150 +69,155 @@ msgstr "Potrdite e-pošto" msgid "You must type the same email each time." msgstr "E-pošti se morata ujemati" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Podana epošta ni veljavna." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Domena epošte ni podprta." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Vnesena napačna enota ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Vrednost ni vnesena" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Ni mogoče pretvoriti {original} v {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Podana napačna količina" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Podrobnosti napake so vidne v pogledu administratorja" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Vnesi datum" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Zapiski" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Vrednost '{name}' ni v predpisanem formatu" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Podana vrednost se ujema s predpisanim vzorcem: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Prazno polje serijske številke" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Dvojna serijska številka" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Doseg skupine {group} presega dovoljene količine ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Serijske številke niso najdene" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Odstranite oznako HTML iz te vrednosti" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Napaka povezave" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Odziv serverja: napravilni status kode" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Pojavila se je izjema" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Odziv serverja: napačna dolžina vrednosti" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Prevelika velikost slike" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Prenos slike presegel največjo velikost" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Oddaljeni server vrnil prazen odziv" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Podani URL ni veljavna slikovna datoteka" @@ -216,159 +225,203 @@ msgstr "Podani URL ni veljavna slikovna datoteka" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-pošta" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Napaka pri izvajanju preverjanja vtičnika" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metapodatki morajo biti objekt tipa python dict" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metapodatki vtičnika" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Polje metapodatkov JSON za uporabo pri zunanjih vtičnikih" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Nepravilno nastavljen vzorec" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Nastavljen neprepoznan ključ formata" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Manjka obvezen ključ formata" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Referenčno polje ne sme biti prazno" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referenca se mora ujemati s vzorcem" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referenčna številka prevelika" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Nedovoljena izbira" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Ime" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Opis" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Opis (opcijsko)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Pot" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Podvojena imena ne morejo obstajati pod istim nadrejenim elementom" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown opombe (neobvezno)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Podatki čtrne kode" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Podatki črtne kode tretje osebe" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Oznaka črtne kode" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Enolična oznaka podatkov črtne kode" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Črtna koda že obstaja" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Napaka strežnika" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Zaznana napaka na strežniku." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Mora biti veljavna številka" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Izberite valuto med razpoložljivimi možnostmi" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Neveljavna vrednost" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "Kitajščina (poenostavljena)" msgid "Chinese (Traditional)" msgstr "Kitajščina (tradicionalno)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Neveljavna fizična enota" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Neveljavna oznaka valute" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Nadrejena izgradnja" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Del" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Dodeljeno meni" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Dodeljeno" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Izgradnja mora biti najprej preklicana, nato je lahko izbrisana" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Neobvezno" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Montaža" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Sledi" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testno" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Dodeljeno" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Na voljo" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Nalog izgradnje" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Nalogi izgradnje" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Sestava BOM ni bila potrjena" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Naveden mora biti odgovorni uporabnik ali skupina" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Referenca naloga izgradnje" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referenca" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Izberite del za izgradnjo" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referenca dobavnica" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Lokacija vira" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Izberite lokacijo dela za to izgradnjo (v primeru da ni pomembno pusti prazno)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Ciljna lokacija" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Izberite lokacijo, kjer bodo končne postavke shranjene" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Količina izgradenj" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Število postavk za izgradnjo" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Končane postavke" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Število postavk zaloge, ki so bile končane" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Status izgradnje" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Koda statusa izgradnje" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Številka serije" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Številka serije za to izgradnjo" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Datum ustvarjenja" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Rok dokončanja" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Rok končanja izdelave. Izdelava po tem datumu bo v zamudi po tem datumu." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Datom končanja" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "dokončal" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Izdal" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Uporabnik, ki je izdal nalog za izgradnjo" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odgovoren" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Odgovorni uporabnik ali skupina za to naročilo" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Zunanja povezava" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Zunanja povezava" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Nalog izgradnje {build} je dokončan" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Nalog izgradnej dokončan" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Ni določena izgradnja" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Igradnja je že dokončana" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Izgradnja se ne ujema s nalogom izdelave" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Količina" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Izdelana postavka mora imeti izgradnjo, če je glavni del označen kot sledljiv" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Količina za zalogo s serijsko številko mora biti 1" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Prestavljena zaloga ({q}) ne sme presegati zaloge ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Preveč zaloge je prestavljene" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Postavka zaloge" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Izvorna postavka zaloge" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Količina zaloge za prestavljanje za izgradnjo" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Inštaliraj v" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Destinacija postavke zaloge" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Izgradnja" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Izgradnja se ne ujema z nadrejeno izgradnjo" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Izhodni del se ne ujema s naročilom sestava" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Ta sestava je že zaključena" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "V teku" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Proizvodnja" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Preklicano" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Končano" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Nalog izgradnje {build} je dokončan" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Nalog izgradnej dokončan" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Uporabnik" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktivno" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Uporabnik" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Povezava" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Priloga" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Manjka datoteka" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Manjka zunanja povezava" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Izberite prilogo" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Komentar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Ime datoteke" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Postavljeno" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Podatki datoteke" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Poslano" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Prestavljena količina mora biti večja od 0" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Izgubljeno" @@ -5718,1279 +6125,1312 @@ msgstr "Izgubljeno" msgid "Returned" msgstr "Vrnjeno" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "V teku" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Združena zaloga postavk" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Spremenjeno v varianto" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Nalog za izgradnjo ustvarjen" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Nalog za izgradnjo končan" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Nalog za izgradnjo zavrnjen" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Porabljeno v nalogu za izgradnjo" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Poslano preko prodajnega naročila" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Prejeto preko nabavnega naročila" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Vrnjeno preko naročila za vračilo" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Posalno stranki" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Vrnjeno od stranke" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Uporabniško ime" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Ime" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Ime uporabnika" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Priimek" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Priimek uporabnika" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Email uporabnika" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superuporabnik" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Ali je ta uporabnik superuporabnik" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Ali je ta račun aktiven" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Vaš račun je bil ustvarjen." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Za prijavo uporabite funkcijo ponastavitve gesla" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Dobrodošli v InvenTree" diff --git a/src/backend/InvenTree/locale/sr/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/sr/LC_MESSAGES/django.po index 71f9ccd0cc..322e88d3a3 100644 --- a/src/backend/InvenTree/locale/sr/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/sr/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Serbian (Latin)\n" "Language: sr_CS\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API krajnja tačka nije pronađena" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Lista nevalidiranih stavki" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Korisnik nema dozvolu za pregled ovog modela" @@ -65,150 +69,155 @@ msgstr "Potvrda adrese e-pošte" msgid "You must type the same email each time." msgstr "Svaki put morate upisati istu e-poštu." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Navedena primarna adresa e-pošte nije važeća." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Navedeni domen adrese e-pošte nije prihvaćen." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Data je nevažeća jedinica ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Nije navedena vrednost" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Nije moguće konvertovati {original} u {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Isporučena nevažeća količina" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Detalji o grešci se mogu naći u admin sekciji" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Unesite datum" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Neispravna decimalna vrednost" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Napomene" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Vrednost '{name}' se ne pojavljuje u formatu obrasca" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Navedena vrednost ne odgovara traženom obrascu: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Nije moguće dati više od 1000 serijskih brojeva stavkama odjednom" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Serijski broj nije popunjen" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Dupliciraj serijski broj" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Nevažeća grupa: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Raspon grupe {group} prelazi dozvoljenu količinu ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Nisu pronađeni serijski brojevi" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Uklonite HTML oznake iz ove vrednosti" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Podatak sadrži zabranjen jezički sadržaj" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Greška u povezivanju" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Server je odgovorio nevažećim statusnim kodom" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Došlo je do izuzetka" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Server je odgovorio nevažećom vrednošću dužina sadržaja" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Veličina slike je prevelika" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Preuzimanje slike premašilo je maksimalnu veličinu" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Udaljeni server vratio je prazan odgovor" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Navedeni URL nije važeća slikovna datoteka" @@ -216,159 +225,203 @@ msgstr "Navedeni URL nije važeća slikovna datoteka" msgid "Log in to the app" msgstr "Prijavljivanje na aplikaciju" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-Pošta" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Greška prilikom validacije ekstenzije" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metapodaci moraju biti \"python dict\" objekat" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metapodaci dodatka" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Polje metapodataka JSON, za korištenje eksternih dodataka" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Neispravno formatiran obrazac" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Naveden je ključ nepoznatog formata" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Nedostaje potreban ključ formata" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Polje za reference ne može biti prazno" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referenca mora odgovarati traženom obrascu" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Broj reference je predugačak" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Nevažeći izvor" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Ime" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Opis" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Opis (Opciono)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Putanja" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Dvostruka imena ne mogu postojati pod istom nadredjenom grupom" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Zabeleške (Opciono)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Podaci sa barkoda" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Podaci sa barkoda trećih lica" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Heš barkoda" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Jedinstveni hash barkoda" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Postojeći barkod pronađen" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Greška servera" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Server je zabležio grešku." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Slika" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Mora biti važeći broj" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Odaberite valutu među dostupnim opcijama" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Nevažeća vrednost" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Kopiraj parametre" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Kopiraj porudžbine" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Kopiraj stavke porudžbine sa originalnog naloga" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Kopiraj dodatne porudžbine" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Kopiraj dodatne stavke porudžbine sa originalnog naloga" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabski" @@ -521,46 +574,48 @@ msgstr "Kineski (Uprošćeni)" msgid "Chinese (Traditional)" msgstr "Kineski (Tradicionalni)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Nevažeća jedinica mere" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Nevažeći kod valute" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Status naloga" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Roditeljski proizvod" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Uključi varijante" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Uključi varijante" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Uključi varijante" msgid "Part" msgstr "Deo" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategorija" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Proizvod predaka" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Dodeljeno meni" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Dodeljeno" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Kreirano pre" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Kreirano nakon" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Ciljni datum pre" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Ciljni datum nakon" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Završeno pre" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Završeno nakon" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Ne uključuj stablo" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Proizvod mora biti poništen pre nego što se izbriše" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Potrošni materijal" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Opciono" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Sklapanje" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Praćeno" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Proverljivo" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Neizmirena narudžbina" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Alocirano" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Dostupno" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Po narudžbini" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Nalog za izradu" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Lokacija" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Nalozi za izradu" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "BOM za sastavljanje nije potvrđeno" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Nalog za izradu se ne može kreirati za neaktivan deo" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Nalog za izradu se ne može kreirati za zaključan deo" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Odgovorni korisnik ili grupa mora biti određena" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Deo u nalogu za izradu ne može se izmeniti" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Reference naloga za pravljenje" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referenca" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Kratak opis izrade (nije obavezno)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Izaberi deo za izgradnju" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Referenca naloga za prodaju" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Lokacija izvora" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Izaberi lokaciju zaliha za ovu izgradnju (ostaviti prazno ako hoćete bilo koju lokaciju zaliha" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Lokacija odredišta" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Izaberi lokaciju gde će se završene stavke skladištiti" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Količina izgradnje" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Broj stavki za izgradnju" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Kompletirane stavke" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Broj stavki u zalihama koje su kompletirane" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Status izgradnje" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Kod statusa izgradnje" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Kod serije" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Kod izgradnje za ovaj izlaz" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "datum kreiranja" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Datum ciljanog završetka" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Ciljani datum za završetak izgradnje. Izgradnja će biti u prekoračenju nakon ovog datuma" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Datum završetka" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "kompletirano od " -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "izdato od" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Korisnik koji je izdao nalog za izgradnju" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Odgovoran" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Korisnik ili grupa koja je odgovorna za ovaj nalog za izgradnju" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Spoljašnja konekcija" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Link za eksterni URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Prioritet izgradnje" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Prioritet ovog naloga za izgradnju" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Kod projekta" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Kod projekta za ovaj nalog za izgradnju" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Nije uspelo preuzimanje zadataka da bi se dovršila alokacija izgradnje" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Nalog za izgradnju {build} je kompletiran" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Nalog za izgradnju je kompletiran" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Za delove koji mogu da se prate moraju se dostaviri serijski brojevi" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Nije određen izlaz izgradnje" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Izlaz izgradnje je već kompletiran" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Izlaz izgradnje se ne slaže sa Nalogom za izgradnju" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Količina mora biti veća od nule" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Količina ne sme da bude veća od izlazne količine" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Izlaz izgradnje {serial} nije zadovoljio zahtevane testove" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Dostupna količina ({q}) premašena" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Stavka porudžbine naloga za izgradnju" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Objekat izgradnje" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Objekat izgradnje" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Količina" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Potrebna količina za nalog za izgradnju" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Stavka izgradnje mora imati izlaz izgradnje, jer je nadređeni deo markiran da može da se prati" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Izabrana stavka zaliha se ne slaže sa porudžbinom sa spiska materijala" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Količina mora da bude 1 za zalihe koje su serijalizovane" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Alocirana količina ({q}) ne sme da bude veća od količine dostupnih zaliha ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Stavka zaliha je prealocirana" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Stavka zaliha" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Izvor stavke zaliha" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Količina zaliha za alociranje za izgradnju" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Ugradi u" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Stavka zaliha odredišta" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Nivo izgradnje" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Ime dela" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Izlaz izgradnje" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Izlaz izgradnje se ne slaže sa nadređenom izgradnjom" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Izlazni deo se ne slaže sa delom Naloga za Izgradnju" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Ovaj izlaz izgradnje je već kompletiran" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Ovaj izlaz izgradnje nije u potpunosti alociran" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Unesi količinu za izlaz izgradnje" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Brojčana količina potrebna za delove koji mogu da se prate" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Potrebna je brojčana količina, jer opis materijala sadrži delove koji se mogu pratiti" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Serijski brojevi" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Unesi serijske brojeve za izlaz izgradnje" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Lokacija zaliha za izlaz izgradnje" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Automatski alociraj serijske brojeve" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Automatski alociraj tražene stavke sa odgovarajućim serijskim brojevima" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Sledeći serijski brojevi već postoje ili su neispravni" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Lista izlaza izgradnje se mora obezbediti" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Lokacija zaliha za otpisane izlaze" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Odbaci alokacije" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Odbaci bilo kojiu alokaciju zaliha za otpisane izlaze" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Razlog za otpisane izlaz(e) izgradnje" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Lokacija za završene izlaze izgradnje" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Prihvati nekompletirane Alokacije" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "kompletiraj izlaze ako zalihe nisu u potpunosti alocirane" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Troši alocirane zalihe" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Troši bilo koje zalihe koje su već alocirane za ovu izgradnju" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Ukloni nekompletirane izlaze" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Izbriši svei izlaze izgradnje koji nisu kompletirani" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Nije dozvoljeno" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Prihvati kao potrošeno od strane ovog naloga za izgradnju" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Izmesti bre završetka ovog naloga za izgradnju" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Sveukupne izdvojene zalihe" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Šta želite da radite sa viškom stavki u zalihama koje su dodeljene nalogu za izgradnju?" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Neke stavke zaliha su prealocirane" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Prihvati nealocirano" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Prihvati da stavke zaliha nisu u potpunosti alocirane za ovaj nalog za izgradnju" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Tražene zalihe nisu u potpunosti alocirane" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Prihvati nekompletirano" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Prihvati da je traženi broj izlaza izgradnje nekompletan" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Traženi broj izgradnji nije kompletan" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Nalog za izgradnju ima otvoren potčinjene naloge za izgradnju" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Nalog za izgradnju mora biti u stanju produkcije" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Nalog za izgradnju ima nekompletne izlaze" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Porudžbina izgradnje" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Izlaz izgradnje" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Izlaz izgradnje mora da referencira istu izgradnju" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Stavka porudžbine za izradu" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part mora da se referencira istom delu kao u nalogu za izgradnju" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Stavka mora da bude u zalihama" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Dostupna količina ({q}) premašena" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Izlaz izgradnje mora da određen za alokaciju praćenih delova" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Izlaz izgradnje ne može biti određen za alokaciju nepraćenih delova" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Stavke alociranja se moraju odrediti" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Lokacija zaliha koje će da budu izvor delova (ostavi prazno ukoliko uzimate sa bilo koje lokacije)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Isključi lokaciju" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Isključi stavke zaliha za ovu selektovanu lokaciju" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Zamenljive zalihe" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Stavke zaliha koje su na različitim lokacijama se mogu međusobno menjati" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Zamenske zalihe" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Dozvoli alociranje delova koji su zamenski" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Opcionalne stavke" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Alociraj opcione BOM stavke na nalog za izgradnju" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "Referenca BOM" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "BOM ID dela" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "BOM ime dela" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Deo dobavljača" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Alocirana količina" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Referenca izgradnje" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Ime kategorije dela" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Može da se prati" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Nasleđen" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Dozvoli varijante" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "BOM stavka" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "U proizvodnji" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Spoljašnje zalihe" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Dostupne zalihe" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Dostupne zamenske zalihe" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Dostupne varijante zaliha" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Na čekanju" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Proizvodnja" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Na čekanju" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Otkazano" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Gotovo" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Nalog za izgradnju {build} je kompletiran" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Nalog za izgradnju je kompletiran" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Potrebne su zalihe za nalog izgranje" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Prekoračeni nalog za izgradnju" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Nalog za izgradnju {bo} je sada prekoračen" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "je link" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "je datoteka" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Korisnik nema potrebne dozvole da bi izbrisao ove atačmente" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Korisnik nema dozvolu da izbriše ovaj atačment" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Lista odabira je zaključana" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Neispravan kod valute" @@ -1539,15 +1641,20 @@ msgstr "Nisu obezbeđeni ispravni kodovi valuta" msgid "No plugin" msgstr "Nema dodataka" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Naziv koda projekta" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Ažurirano" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Vreme poslednjeg ažuriranja" @@ -1567,794 +1674,844 @@ msgstr "Jedinstveni kod projekta" msgid "Project description" msgstr "Opis projekta" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Korisnik ili grupa odgovorni za ovaj projkat" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Ključ za podešavanje" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Vrednost podešavanja" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Izabrana vrednost nije ispravna opcija" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Vrednost mora da bude boolean tipa" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Vrednost mora da bude integer tipa" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Vrednost mora biti broj" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Vrednost ne prolazi test ispravnosti" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Tekstualni ključ mora da bude jedinstven" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Korisnik" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Prelomna količina cene" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Cena" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Cena jedinice za određenu količinu" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Krajnja tačka" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Krajnja tačka na kojoj je primljen zahtev za izmenu web stranice" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Ime ovog zahteva za izmenu stranice" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktivan" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Korisnik ili grupa odgovorni za ovaj projkat" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Ključ za podešavanje" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Vrednost podešavanja" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Izabrana vrednost nije ispravna opcija" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Vrednost mora da bude boolean tipa" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Vrednost mora da bude integer tipa" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Vrednost mora biti broj" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Vrednost ne prolazi test ispravnosti" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Tekstualni ključ mora da bude jedinstven" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Korisnik" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Prelomna količina cene" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Cena" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Cena jedinice za određenu količinu" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Krajnja tačka" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Krajnja tačka na kojoj je primljen zahtev za izmenu web stranice" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Ime ovog zahteva za izmenu stranice" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Da li je ovaj zahtev za izmenu aktivan?" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Token za pristup" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Tajna" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Deljena tajna za HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "ID poruke" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Jedinstveni identifikator za ovu poruku" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Računar" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Računar koji je primio ovu poruku" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Zaglavlje" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Zaglavlje ove poruke" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Telo" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Telo ove poruke" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Krajnja tačka na kojoj je ova poruka primljena" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Radilo se na " -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Da li je rad sa ovom porukom završen?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Naslov" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Link" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Objavljeno" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Autor" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Rezime" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Čitaj" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Da li je ova stavka vesti pročitana" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Datoteka slike" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Ciljni tip modela za ovu sliku" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "Ciljni ID modela za ovu sliku" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Posebna jedinica" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Simbol jedinice mora biti jedinstven" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Ime jedinice mora da bude ispravan identifikator" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Ime jedinice" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Simbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Opcioni simbol jedinice" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definicija" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Definicija jedinice" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Prilog" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Nedostaje datoteka" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Nedostaje eksterni link" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Izaberite datoteku za prilog" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Komentar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Komentar priloga" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Datum učitavanja" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Datum kada je datoteka učitana" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "Veličina datoteke" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Veličina datoteke u bajtovima" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Određen je neispravan tip modela za prilog" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Posebno stanje" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Posebna stanja" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Referentni status podešen" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Status je podešen i produžen je sa ovim posebnim stanjem" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logički ključ" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "Stanje logičkog ključa je jednako posebnom ključu u poslovnoj logici" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Vrednost" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Numerička vrednost koja će biti sačuvana u bazi podataka modela" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Ime stanja" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etiketa" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Etiketa koja će biti prikazana na korisničkoj strani" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Boja" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Boja koja će biti prikazana na korisničkoj strani" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Model ovog stanja je povezan sa " -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Model mora biti izabran" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Ključ mora biti izabran" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Logički ključ mora biti izabran" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "Ključ mora da se razlikuje od logičkog ključa" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Validna referenca statusa klase mora biti dostavljena" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "Ključ mora biti različit od logičkog ključa referentnog statusa" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "Logički ključ mora biti među logičkim ključevima referentnog statusa" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "Naziv mora biti različit od naziva u statusu reference" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Lista odabira" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Liste odabira" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Ime liste odabira" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Opis liste odabira" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Zaključano" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Da li je ova lista odabira zaključana?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Da li se ova lista odabira može koristiti?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Ekstenzija/dodatak za izvor" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Ekstenzija koja pruža listu odabira" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "String izvora" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Opcioni string koji identifikuje izvor koji se koristi za ovu listu" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Podrazumevani unos" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Podrazumevani unos za ovu listu odabira" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Kreirano" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Datum i vreme kada je ova lista odabira kreirana" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Poslednje ažuriranje" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Datum i vreme kada je ova lista odabira ažurirana" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Unos liste odabira" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Unosi liste odabira" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Lista odabira kojoj ovaj unos pripada" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Vrednost ovog unosa liste odabira" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Naziv ovog unosa liste odabira" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Opis ovog unosa liste odabira" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Da li je unos ove liste odabira aktivan?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Šablon parametra" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Checkbox parametri ne mogu imati jedinice" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Checkbox parametri ne mogu imati izbore" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Izbori moraju biti jedinstveni" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Ime šablona parametra mora biti jedinstveno" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Naziv parametra" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Jedinice" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Fizičke jedinice za ovaj parametar" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Opis parametra" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Polje za potvrdu" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Da li je ovaj parametar checkbox?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Izbori" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Validni izbori za ovaj parametar (razdvojeni zapetom)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Lista izbora za ovaj parametar" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Omogućen" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Nije validan izbor za vrednost parametra" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Šablon" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Podaci" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Vrednost parametra" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Beleška" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Opciona beleška" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Skeniranje bar koda" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Podaci bar koda" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Korisnik koji je skenirao bar kod" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Vremenski trag" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Datum i vreme skeniranja bar koda" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "URL krajnja tačka kojaj je obradila bar kod" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Kontekst" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Kontekst podataka za skeniranje bar koda" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Odgovor" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Podaci odgovora za skeniranje bar koda" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Rezultat" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Da li je skeniranje bar koda bilo uspešno?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Ključ" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} poništeno" msgid "A order that is assigned to you was canceled" msgstr "Narudžbina koja je bila dodeljena vama je otkazana" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Stavke primljene" @@ -2388,104 +2545,100 @@ msgstr "Stavke su primljene uprkos nalogu za kupovinu" msgid "Items have been received against a return order" msgstr "Stavke su primljene uprkos nalogu za povrat" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Pokrenuto je" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Čekaju se zadaci" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Planirani zadaci" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Propali zadaci" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID zadatka" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Jedinstveni ID zadatka" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Zaključaj" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Vreme zaključavanja" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Naziv zadatka" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funkcija" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Ime funkcije" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argumenti" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Argumenti zadatka" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Ključne reči argumenata" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Ključne reči argumenata zadatka" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Ime datoteke" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Tip modela" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Korisnik nema dozvolu da napravi ili izmeni priloge za ovaj model" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Lista odabira je zaključana" - #: common/setting/system.py:97 msgid "No group" msgstr "Nema grupe" @@ -2614,13 +2767,13 @@ msgstr "Interval ažuriranja valuta" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Koliko često ažurirati devizne kurseve (podesi na nulu za onemogućti)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dani" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Dodatak za ažuriranje valute koji će se koristiti" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Stroga validacija URL" @@ -2760,947 +2921,1017 @@ msgstr "Dodatak za generisanje bar koda" msgid "Plugin to use for internal barcode data generation" msgstr "Dodatak koji će se koristiti kao interni generator podataka bar koda" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Revizije dela" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Omogući polje za reviziju dela" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Jedino revizija sastavljanja " -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Dozvoli jedino revizije za sastavne delove" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Dozvoli brisanje iz sastavljanja" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Dozvoli brisanje delova koji su korišćeni u sastavljanju" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Interni broj dela regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Regularni obrazac izraza za podudaranje IPN dela" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Dozvoli duple IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Dozvoli da više delova dele isti IPN" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Dozvoli izmenu IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Dozvoli izmenu IPN vrednosti u toku izmene dela" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Kopiraj BOM podatke dela" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Podrazumevaj kopiranje BOM podataka prilikom pravljenja duplikata dela " -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Kopiraj podatke parametara dela" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Podrazumevaj kopiranje podataka parametara dela prilikom pravljenja duplikata dela" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Kopiraj podatke testiranja dela" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Podrazumevaj kopiranje podataka testiranja dela prilikom pravljenja duplikata dela" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kopiraj šablone parametara kategorije" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Kopiraj šablone parametara kategorije prilikom pravljenja dela" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Podrazumevano je da su delovi šabloni" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Podrazumevano je da se delovi mogu sastavljati od drugih komponenti" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponenta" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Podrazumevano je da se delovi mogu koristi kao pod-komponente" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Može da se kupi" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Podrazumevano je da se delovi mogu kupiti" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Može da se proda" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "podrazumevano je da delovi mogu da se prodaju" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Podrazumevano je da delovi mogu da se prate" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuelni" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Podrazumevano je da su delovi virtuelni" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Prikaži povezane delove" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Prikaži povezane delove za deo" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Inicijalni podaci zaliha" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Dozvoli kreiranje inicijalne alihe prilikom dodavanja novog dela" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Podaci inicijalnog dobavljača" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Dozvoli kreiranje inicijalnog dobavljača prilikom dodavanja novog dela" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Format prikazivanja imena dela" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Format u kome će se prikazivati ime dela" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Podrazumevana ikona za kategoriju dela" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Podrazumevana ikona za kategoriju dela (prazno znači bez ikone)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Minimalan broj decimalnih mesta za cene" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Minimalan broj decimalnih mesta prilikom generisanja cenovnih podataka" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Maksimalan broj decimalnih mesta za cene" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Maksimalan broj decimalnih mesta prilikom generisanja cenovnih podataka" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Koristi cene dobavljača" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Uključi pauziranje cene dobavljača u sveukupnom računanju cene" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Premosti istorijat kupovina" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Prethodne cene narudžbenice zamenjuje pauze cena dobavljača" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Koristi cene stavki u zalihama" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Koristi cene koje su ručno unete u podatke zaliha" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Godina cena stavki u zalihama" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Odstrani stavke zaliha iz kalkulacija cena, koje su starije od ovog broja dana" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Koristi drugačije cene" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Uključi drugačije cene u sveukupnim kalkulacijama cene" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Samo aktivne varijante" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Koristi samo aktivne varijante za određivanje varijante cene" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Vremenski period za ponovno određivanje cena" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Broj dana koji treba da prođe da bi se cene delova automatski ažurirale" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Interne cene" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Omogući interne cene za delove" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Premošćavanje internih cena" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Ako su dostupne, interne cene premošćuju kalkulacije opsega cena" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Omogući štampanje etiketa" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Omogući štampanje etiketa preko web interfejsa" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "DPI slike etikete" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "DPI rezolucija prilikom generisanja slikovne datoteke za dodatak koji štampa etikete" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Omogući izveštaje" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Omogući generisanje izveštaja" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Mod otklanjanja grešaka" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Generiši izveštaje u modu za otklanjanje grešaka (izlaz je u HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Greške evidencije izveštaja" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Greške evidentiranja koje se dese prilikom generisanja izveštaja" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Veličina stranice" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Podrazumevana veličina strane za izveštaje u PDF formatu" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Zahtevaj jedinice parametara" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Ako su jedinice date, vrednosti parametara moraju odgovarati datim jedinicama" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Globalno jedinstveni serijski brojevi" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Serijski brojevi za stavke zaliha moraju da budu globalno jedinstveni" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Obriši ispražnjene zalihe" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Ovo određuje podrazumevano ponašanje kada je stavka zaliha istrošena" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Šablon koda serije" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Šablon za generisanje podrazumevanih kodova serije stavki u zalihama" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Datum isteka zaliha" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Omogući funkcionalnost isteka zaliha" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Prodaja isteklih zaliha" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Dozvoli prodaju isteklih zaliha" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Vreme zastarevanja zaliha" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Broj dana tokom kojih će se stavke zaliha smatrati zastarelim pre isteka" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Izrada sa isteklim zalihama" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Dozvoli izradu sa isteklim zalihama" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Vlasnička kontrola zaliha" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Omogući vlasničku kontrolu nad lokacijama zaliha i stavkama" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Podrazumevana ikonica lokacije zaliha" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Podrazumevana ikonica lokacije zaliha (prazno znači da nema ikonice)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Prikaži instalirane stavke sa zaliha" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Prikaži instalirane stavke sa zaliha u stok tabelama" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "Proveri spisak materijala pri instalaciji stavki" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Instalirane stavke sa zaliha moraju postojati u spisku materijala nadređenog dela" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Dozvoli transfer van zaliha" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Dozvoli da stavke sa zaliha koje nisu na zalihama budu premeštane između lokacija zaliha" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Referentni šablon naloga za izradu" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Potreban šablon za generisanje referentnog polja naloga za izradu" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Potreban odgovoran vlasnik" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Odgovoran vlasnik mora biti dodeljen svakom nalogu" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Potreban aktivan deo" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Spreči kreiranje naloga za izradu za neaktivne delove" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Potreban zaključan deo" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Spreči kreiranje nalogaza izradu za otključane delove" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Potreban validan spisak materijala" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "Spreči kreiranje naloga za izradu pre validacije spiska materijala" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Potrebno završavanje podređenih naloga" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Spreči završavanje naloga za izradu pre završavanja svih podređenih naloga" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Blokiraj dok ne prođe test" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Spreči završavanje naloga za izradu pre uspešnog završetka svih testova" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Omogući naloge za vraćanje" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Omogući funkcionalnost vraćana u korisničkom interfejsu" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Referentni šablon naloga za vraćanje" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "Potreban šablon pri generisanju referentnog polja naloga za vraćanje" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Izmeni završene naloge za vraćanje" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Dozvoli izmenu naloga za vraćanje nakon što su završeni" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Referentni šablon naloga za prodaju" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Potreban šablon pri generisanju referentnog polja naloga za prodaju" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Podrazumevana isporuka naloga za prodaju" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Omogućava kreiranje podrazumevane isporuke sa nalozima za prodaju" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Izmeni završene naloge za prodaju" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Dozvoli izmenu naloga za prodaju nakon što su isporučeni ili završeni" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Označi isporučene naloge kao završene" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Nalozi za prodaju označeni kao isporučeni će automatski biti završeni, zaobilazeći status isporučen" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Referentni šablon naloga za kupovinu" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Potreban šablon pri generisanju referentnog polja naloga za kupovinu" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Izmeni završene naloge za kupovinu" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Dozvoli izmenu naloga za kupovinu nakon što su isporučeni ili završeni" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Automatski završi naloge za kupovinu" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Automatski označi naloge za kupovinu kao završene kada su primljene sve stavke porudžbine" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Omogući zaboravljenu lozinku" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "Omogući funkcionalnost zaboravljene lozinke na stranicama za prijavljivanje" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Omogući registraciju" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "Omogući registraciju korisnicima na stranicama za prijavljivanje" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "Omogući SSO" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "Omogući SSO na stranicama za prijavljivanje" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "Omogući SSO registraciju" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "Omogući registraciju preko SSO za korisnike na stranicaa za prijavljivanje" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "Omogući SSO sinhronizaciju grupa" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "Omogući sinhronizaciju grupa aplikacije sa grupama IdP-a" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSO ključ grupe" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "Nazivi grupa dobijaju atribute od IdP-a" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "Mapiranje SSO grupa" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "Mapiranje SSO grupa u lokalne grupe aplikacije. Ukoliko lokalna grupa ne postoji, biće kreirana." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "Ukloni grupe van SSO" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "Da li će grupe dodeljene korisnicima biti uklonjene ukoliko nisu podržane IdP-om. Onemogućavanje ovoga može dovesti do problema." -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "Email neophodan" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Zahtevaj od korisnika da dostavi mejl prilikom registracije" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Automatski popuni SSO korisnike" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Automatski popuni korisnikove podatke iz SSO naloga" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Email dva puta" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Pitaj korisnika dva puta za email prilikom registracije" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Lozinka dva puta" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Pitaj korisnika dva puta za lozinku prilikom registracije" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Dozvoljeni domeni" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Ograniči registraciju na određene domene (razdvojeni zapetom, počinju sa @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Grupa pri registrovanju" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Grupa kojoj se novi korisnici dodeljuju pri registraciji. Ukoliko je SSO group sync omogućen, ova grupa će se dodavati ukoliko korisnik ne može da dobije grupu iz IdP-a." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Nametni MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Korisnici moraju koristiti multifaktorsku bezbednost" -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Proveri plugine pri pokretanju" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Proveri da li su svi pluginovi instalirani pri pokretanju - omogućeni u kontejnerskim okruženjima" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Proveri ažuriranja pluginova" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Omogući periodično proveranje pluginova" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Omogući URL integraciju" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Omogući da pluginovi dodaju URL rute" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Omogući integraciju u navigaciju" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Omogući integraciju pluginova u navigaciju" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Omogući integraciju aplikacija" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Omogući pluginovima da dodaju aplikacije" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Omogući integraciju planiranja" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Omogući da plugini izvršavaju planirane zadatke" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Omogući integraciju događaja" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Omogući da plugini odgovaraju na unutrašnje događaje" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Omogući integraciju interfejsa" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Omogući integraciju pluginova u korisnički interfejs" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Ne uključuj eksterne lokacije" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Period automatskog popisa" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Prikaži puna imena korisnika" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Prikaži puna imena korisnika umesto korisničkih imena" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Omogući podatke test stanica" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Omogući prikupljanje podataka sa test stanica radi rezultata testova" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Broj rezultata koji će se prikazivati u svakoj sekciji prozora za pregled pretrage" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Regex pretraga" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Omogući regularne izraze u upitima pretrage" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Pretraga celih reči" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Upiti pretrage vraćaju rezultate za poklapanje celih reči" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Escape dugme zatvara forme" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Koristi escape dugme za zatvaranje modalnih formi" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Fiksirana traka za navigaciju" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Pozicija trake za navigaciju je fiksirana na vrhu ekrana" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Format datuma" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Željeni format za prikazivanje datuma" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Primaj izveštaje o greškama" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Primaj notifikacije za sistemske greške" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Poslednje korišćene mašine za štampanje" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Sačuvaj poslednju korišćenu mašinu za štampanje za korisnika" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Nije dostavljen tip modela priloga" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Nevažeći tip modela priloga" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Minimalno mesta ne sme biti veće od maksimalno mesta" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Maksimalno mesta ne sme biti manje od minimalno mesta" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Prazan domen nije dozvoljen." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Nevažeće ime domena: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Vrednost mora biti napisana velikim slovima" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Vrednost mora biti važeći identifikator promenljive" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Deo je aktivan" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Proizvođač je aktivan" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Deo dobavljača je aktivan" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Interni deo je aktivan" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Dobavljač je aktivan" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Proizvođač" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Kompanija" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Ima zalihe" @@ -4123,8 +4387,8 @@ msgstr "Broj telefona kontakta" msgid "Contact email address" msgstr "Email adresa kontakta" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontakt" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adrese" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adrese" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Izaberi kompaniju" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Naslov adrese" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Naslov koji opisuje adresu" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Primarna adresa" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Postavi kao primarnu adresu" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Telefon 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Adresa 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Telefon 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Adresa 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Poštanski broj" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Grad/region" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Poštanski broj" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Država/provincija" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Država ili provincija" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Zemlja" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Adresa zemlje" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Beleške za kurira" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Beleške za kurira" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Interne beleške o isporuci" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Beleške o isporuci za internu upotrebu" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Link za adresne informacije (eksterni)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Deo proizvođača" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Osnovni deo" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Izaberi deo" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Izaberi proizvođača" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "Broj dela proizvođača" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Broj dela proizvođača" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL za link eksternog dela proizvođača" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Opis dela proizvođača" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Jedinice pakovanja moraju biti kompatibilne sa osnovnim jedinicama dela" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Jedinice pakovanja moraju biti veće od nule" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Povezani delovi dobavljača moraju referencirati isti osnovni deo" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Dobavljač" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Izaberi dobavljača" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Jedinica za držanje dobavljačevih zaliha" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Da li je ovaj deo dobavljača aktivan?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Izaberi deo proizvođača" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL za link dela eksternog dobavljača" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Opis dela dobavljača" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "osnovni trošak" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimalna naplata (npr. taksa za slaganje)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Pakovanje" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Pakovanje delova" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Količina pakovanja" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Ukupna količina dostavljena u jednom pakovanju. Ostaviti prazno za pojedinačne stavke." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "više" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Naruči više" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Količine dostupne od dobavljača" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Dostupnost ažurirana" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Datum poslednjeg ažuriranja podataka o dostupnosti" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Smanjenje cene dobavljača" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Podrazumevana valuta koja se koristi za ovog dobavljača" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Naziv kompanije" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Na zalihama" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Dodatne statusne informacije za ovu stavku" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Prilagođen ključ statusa" @@ -4476,123 +4740,152 @@ msgstr "Postavljen" msgid "Invalid status code" msgstr "Nevažeći statusni kod" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Datoteka" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "Fajl sa podacima za uvoz" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Kolone" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "Status uvoza" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Podrazumevane vrednosti polja" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Promene polja" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Filteri polja" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Neka neophodna polja nisu mapirana" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "Kolona je već mapirana u polje u bazi podataka" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Polje je već mapirano u kolonu sa podacima" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Mapiranje kolona mora biti linkovano da bi se uvezla važeća sesija" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Kolona ne postoji u fajlu sa podacima" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Polje ne postoji u ciljnom modelu" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "Izabrano polje je samo za čitanje" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Uvezi sesiju" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Polje" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Kolona" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Indeks vrsta" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Originalni podaci vrste" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Greške" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Važeće" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Nije podržan format fajla sa podacima" @@ -4600,43 +4893,47 @@ msgstr "Nije podržan format fajla sa podacima" msgid "Failed to open data file" msgstr "Greška pri otvaranju fajla sa podacima" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Nevažeće dimenzije fajla sa podacima" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Nevažeće podrazumevane vrednosti polja" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Nevažeće promene polja" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Nevažeći filteri polja" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Vrste" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Lista ID-jeva vrsta za prihvatanje" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Nema dostavljenih vrsta" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "Vrsta ne pripada ovoj sesiji" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "Vrsta sadrži nedozvoljene podatke" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "Vrsta je već završena" @@ -4672,115 +4969,115 @@ msgstr "Fajl sa podacima sadrži previše kolona" msgid "Data file contains too many rows" msgstr "Fajl sa podacima sadrži previše vrsta" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Vrednosti moraju biti validni objekti" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopije" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Broj kopija za štampanje od svakog natpisa" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Konektovano" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Nepoznato" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Štampanje" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Nema medijuma" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Papir zaglavljen" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Diskonektovano" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Štampač natpisa" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Direktno štampaj natpise za razne stavke" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Lokacija štampača" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Podesi štampač na specifičnu lokaciju" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Naziv mašine" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Tip mašine" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Tip mašine" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Drajver" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Drajver koji se koristi za ovu mašinu" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Mašine mogu biti onemogućene" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Drajver dostupan" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Nema grešaka" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Inicijalizovano" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Status mašine" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Mašina" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Mašinska konfiguracija" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Tip konfiguracije" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupa" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Referenca naloga" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Izvanredno" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Ima šifru projekta" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Kreirano do strane" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Kreirano pre" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Kreirano nakon" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Krajnji datum pre" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Krajnji datum nakon" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Ima cenu" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Završen pre" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Završen nakon" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Nalog" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Nalog završen" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Interni deo" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Nalog na čekanju" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Završeno" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Ima isporuku" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Nalog za kupovinu" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Nalog za kupovinu" msgid "Sales Order" msgstr "Nalog za prodaju" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Nalog za vraćanje" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Ukupna cena" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Totalna cena ovog naloga" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Valuta naloga" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Valuta za ovaj nalog (ostaviti prazno za podrazumevanu valutu kompanije)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Kontakt se ne poklapa sa izabranom kompanijom" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Opis naloga (opciono)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Izaberi šifru projekta za ovaj nalog" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Link ka eksternoj stranici" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Ciljani datum" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Očekivani datum za isporuku. Nalog će biti zastareo nakon ovog datuma." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Datum izdavanja" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Datum kada je nalog izdat" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Korisnik ili grupa odgovorni za ovaj nalog" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Lice za kontakt za ovaj nalog" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Adresa kompanije za ovaj nalog" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Referenca naloga" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Status naloga za kupovinu" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Kompanija od koje su stavke naručene" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Referenca dobavljača" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Referentni kod dobavljača naloga" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "primljeno od strane" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Datum kada je nalog završen" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Odredište" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Odredište za primljene stavke" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Dobavljač dela se mora poklapati sa dobavljačem naloga za kupovinu" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Stavka porudžbine se ne poklapa sa nalogom za kupovinu" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Količina mora biti pozitivan broj" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Mušterija" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Kompanija kojoj se prodaju stavke" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Status naloga za prodaju" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Referenca mušterije" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Referentni kod mušterijinog naloga" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Datum isporuke" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "isporučeno od strane" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Stavka porudžbine nije asocirana sa ovim nalogom" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Nema pronađenih poklapanja za sledeće serijske brojeve" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Sledeći serijski brojevi su nedostupni" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Nalog je već završen" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Nalog je već otkazan" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Samo otvoren nalog može biti označen kao završen" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Nalog ne može biti završen jer ima nepotpunih isporuka" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "Nalog ne može biti završen jer ima nepotpunih alokacija" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Nalog ne može biti završen jer ima nezavršenih stavki porudbžine" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Količina stavki" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Referenca stavke porudbžine" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Beleške stavke porudbžine" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Krajnji datum za ovu stavku porudbćine (ostaviti prazno za krajnji datum sa naloga)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Opis stavke porudžbine (opciono)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Dodatni kontekst za ovu porudžbinu" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Cena jedinice" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Stavka porudžbine naloga za kupovinu" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Deo dobavljača se mora poklapati sa dobavljačem" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Deo dobavljača" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Primljeno" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Broj primljenih stavki" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Kupovna cena" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Kupovna cena jedinice" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Dodatna porudbžina naloga za kupovinu" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Stavka porudžbine naloga za prodaju" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Samo delovi koji se mogu prodati mogu biti dodeljeni nalogu za prodaju" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Prodajna cena" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Prodajna cena jedinice" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Poslato" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Isporučena količina" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Isporuka naloga za prodaju" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Datum isporuke" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Datum dostavljanja" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Datum dostavljanja isporuke" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Provereno od strane" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Korisnik koji je proverio ovu isporuku" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Isporuka" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Broj isporuke" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Broj praćenja" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Informacije o praćenju isporuke" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Broj računa" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Referentni broj za dodeljeni račun" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Isporuka je već poslata" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Isporuka nema alocirane stavke sa zaliha" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Dodatne porudbžine naloga za prodaju" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Alokacije naloga za prodaju" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Stavka sa zaliha nije dodeljena" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Ne mogu se alocirati stavke sa zaliha porudbžini sa drugačijim delom" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Ne mogu se alocirati zalihe porudbžini bez dela" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Alocirana količina ne sme da pređe količinu zaliha" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Količina alokacije mora da bude veća od nule" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Količina mora biti 1 za serijalizovane stavke sa zaliha" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Nalog za prodaju se ne poklapa sa isporukom" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Isporuka se ne poklapa sa nalogom za prodaju" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Porudbžina" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Referenca isporuke naloga za prodaju" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Stavka" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Izaberi stavku sa zaliha za alokaciju" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Unesi količinu za alokaciju zaliha" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Referenca naloga za vraćanje" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Kompanija čije stavke su vraćene" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Status naloga za vraćanje" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "Vrati stavku porudbžine" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Stavka sa zaliha mora biti određena" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "Količina vraćanja je premašila količinu zaliha" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "Količina vraćanja mora biti veća od nule" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Nevažeća količina za serijalizovane stavke sa zaliha" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Izaberi stavku za vraćanje od mušterije" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Primljeno datuma" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Ishod" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Ishod za ovu stavku porudžbine" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Trošak asociran sa popravkom ili vraćanjem ove stavke porudžbine" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Doda" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "ID naloga" - -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "ID naloga koji će se duplirati" - -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Kopiraj porudžbine" - -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Kopiraj stavke porudžbine sa originalnog naloga" - -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Kopiraj dodatne porudžbine" - -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Kopiraj dodatne stavke porudžbine sa originalnog naloga" - -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Kopiraj parametre" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" + +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" + +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" + +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" + +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" + +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" + +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Stavke porudbžine" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Završene porudbžine" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Dupliraj nalog" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Odredi opcije za dupliranje ovog naloga" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Nevažeći ID naloga" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Naziv dobavljača" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Nalog ne može biti otkazan" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Dozvoli da nalog bude zatvoren sa nepotpunim porudžbinama" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Nalog ima nepotpune stavke porudžbine" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Nalog nije otvoren" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Automatske cene" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Automatski izračunaj kupovnu cenu na osnovu podataka o delovima dobavljača" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Valuta kupovne cene" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Spoj stavke" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Spoj stavke sa istim delom, odredištem i ciljanim datumom u jednu stavku porudžbine" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "Jedinica za praćenje zaliha" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Interni broj dela" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Interni naziv dela" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Deo dobavljača mora biti određen" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Nalog za kupovinu mora biti određen" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Dobavljač mora da se poklapa sa nalogom za kupovinu" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Nalog za kupovinu mora da se poklapa sa dobavljačem" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Stavka porudbžine" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Izaberi odredišnu lokaciju za primljene stavke" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Unesi šifru ture za nadolazeće stavke sa zaliha" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Datum isteka" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Unesi serijske brojeve za nadolazeće stavke sa zaliha" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Promeni informacije o pakovanju za nadolazeće stavke sa zaliha" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Dodatne beleške za nadolazeće stavke sa zaliha" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Bar kod" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Skeniran bar kod" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Bar kod je već u upotrebi" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Stavke porudžbine moraju biti dostavljene" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Odredišna lokacija mora biti određena" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Pružene vrednosti bar kodova moraju biti jedinstvene" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Isporuke" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Završene isporuke" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Valuta prodajne cene" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Alocirane stavke" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Nisu dostavljeni detalji isporuke" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Stavka porudžbine nije asocirana sa ovim nalogom" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Količina mora biti pozitivna" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Unesi serijske brojeve za alokaciju" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Isporuka je već isporučena" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Isporuka nije povezana sa ovim nalogom" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Nema pronađenih poklapanja za sledeće serijske brojeve" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Sledeći serijski brojevi su nedostupni" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Stavka porudžbine naloga za vraćanje" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Stavka porudžbine se ne poklapa sa nalogom za vraćanje" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Stavka porudžbine je već primljena" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Stavke se mogu primiti samo na osnovu naloga koji su u toku" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "Količina za vraćanje" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Valuta cene porudžbine" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Izgubljeno" @@ -5718,1279 +6125,1312 @@ msgstr "Izgubljeno" msgid "Returned" msgstr "Vraćeno" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "U progresu" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Vrati" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Popravi" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Zameni" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Refundiraj" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Odbij" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Izdato" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Istekli nalozi za kupovinu" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Nalog za kupovinu {po} je sada istekao" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Istekli nalozi za prodaju" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Nalog za prodaju {so} je sada istekao" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Označeno zvezdicom" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Filtiraj po kategorijama označenim zvezdicom" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Dubina" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Filtriraj po dubini kategorije" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Vrhovni" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Filtriraj po vrhovnim kategorijama" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Kaskadno" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Uključi pod-kategorije u filtriranim rezultatima" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Nadređen" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Filtriraj po nadređenoj kategoriji" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Ne uključuj pod-kategorije pod specifičnom kategorijom" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Ima rezultate" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Je revizija" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Ima revizije" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "Spisak materijala validan" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Deo sklopa se može testirati" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Deo komponente se može testirati" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Koristi" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Kategorija dela" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Kategorije delova" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Podrazumevana lokacija" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Podrazumevana lokacija za delove ove kategorije" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Strukturno" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Delovi ne mogu biti direktno dodeljene strukturnoj kategoriji, ali mogu biti dodeljeni podređenim kategorijama." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Podrazumevane ključne reči" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Podrazumevane ključne reči za delove ove kategorije" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ikonica" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ikonica (opciono)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Ova kategorija dela se ne može podesiti kao strukturna jer već ima dodeljene neke delove!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Šablon parametara kategorije dela" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Podrazumevana vrednost" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Podrazumevana vrednost parametra" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Delovi" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Ovaj deo se ne može izbrisati jer je zaključan" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Ovaj deo se ne može izbrisati jer je i dalje aktivan" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Ovaj deo se ne može obrisati jer se koristi u sklopu" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Deo '{self}' ne može biti korišćen u spisku materijala za '{parent}' (recursive)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Deo '{parent}' se koristi u spisku materijala za '{self}' (recursive)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "Interni broj dela se mora slagati sa regex šablonom {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Deo ne može biti revizija samog sebe" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Revizije su dozvoljene samo za delove sklopove" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Ne može se izvršiti revizija šablonskog dela" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "Nadređeni deo mora biti vezan sa istim šablonom" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Stavka sa ovim serijskim brojem već postoji" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Duplirani interni brojevi dela nisu dozvoljeni u podešavanjima dela" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Identična revizija dela već postoji" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Deo sa ovim nazivom, internim brojem dela i revizijom već postoji" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Delovi ne mogu biti dodeljeni strukturnim kategorijama delova!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Naziv dela" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Jeste šablon" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Da li je ovaj deo šablonski deo?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Da li je ovaj deo varijanta drugog dela?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Varijanta od" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Opis dela (opciono)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Ključne reči" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Ključne reči dela da bi se poboljšala vidljivost u rezultatima pretrage" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Kategorija dela" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "Interni broj dela" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Revizija dela ili broj verzije" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revizija" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Da li je ovaj deo revizija drugog dela?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Revizija od" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Gde je ova stavka inače skladištena?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Podrazumevani istek" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Vreme isteka (u danima) za stavke sa zaliha ovog dela" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimalne zalihe" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Minimalni dozvoljen nivo zaliha" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Jedinice mere za ovaj deo" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Da li ovaj deo može biti izgrađen od drugih delova?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Da li ovaj deo može biti korišćen za izradu drugih delova?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Da li ovaj deo ima praćenje za više stavki?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Da li ovaj deo može imati svoje rezultate testa?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Da li ovaj deo može biti kupljen od eksternih dobavljača?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Da li ovaj deo može biti prodat mušterijama?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Da li je ovaj deo aktivan?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Zaključani delovi se ne mogu menjati" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Da li je ovo virtuelni deo, kao na primer softver ili licenca?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Suma spiska materijala" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Uskladištena suma spiska materijala" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "Spisak materijala proveren od strane" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Spisak materijala proveren datuma" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Korisnik koji je kreirao" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Vlasnik odgovoran za ovaj deo" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Prodaj više" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Valuta korišćena za vršenje proračuna o cenama" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimalna vrednost spiska materijala" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Minimalna vrednost komponenti delova" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maksimalna vrednost spiska materijala" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Maksimalna vrednost komponenti delova" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimalna kupovna vrednost" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Minimalna istorijska kupovna vrednost" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maksimalna kupovna vrednost" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Maksimalna istorijska kupovna vrednost" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimalna interna cena" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Minimalna cena bazirana na internim sniženjima cena" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maksimalna interna cena" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Maksimalna vrednost bazirana na internim sniženjima cena" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Minimalna cena dobavljača" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Minimalna cena dela od eksternih dobavljača" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Maksimalna cena dobavljača" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Maksimalna cena dela od eksternih dobavljača" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Minimalna vrednost varijanti" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Izračunata minimalna vrednost varijanti delova" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Maksimalna vrednost varijanti" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Izračunata maksimalna vrednost varijanti delova" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimalna vrednost" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Promeni minimalnu vrednost" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maksimalna vrednost" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Promeni maksimalnu vrednost" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Ukupna izračunata minimalna vrednost" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Ukupna izračunata maksimalna vrednost" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Minimalna prodajna cena" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Minimalna prodajna cena bazirana na osnovu sniženja cena" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Maksimalna prodajna cena" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Maksimalna prodajna cena bazirana na osnovu sniženja cena" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Minimalna prodajna vrednost" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Minimalna istorijska prodajna cena" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Maksimalna prodajna vrednost" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Maksimalna istorijska prodajna cena" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Deo za popis" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Broj stavki" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Broj individualnih unosa zaliha u vreme popisa" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Ukupne dostupne zalihe za vreme popisa" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Datum" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Datum kada je izvršen popis" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Minimalna vrednost zaliha" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Procenjena minimalna vrednost trenutnih zaliha" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maksimalna vrednost zaliha" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Procenjena maksimalna vrednost trenutnih zaliha" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Smanjenje prodajne cene dela" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Šablon testa dela" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Nevažeći naziv šablona - mora da uključuje bar jedan alfanumerički karakter" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Test šabloni mogu biti kreirani samo za delove koje je moguće testirati" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Test šablon sa istim ključem već postoji za ovaj deo" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Naziv testa" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Unesi naziv za ovaj test" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Test ključ" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Pojednostavljen ključ za test" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Opis testa" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Unesi opis za ovaj test" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Da li je ovaj test omogućen?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Neophodno" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Da li je neophodno da ovaj test prođe?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Zahteva vrednost" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Da li ovaj test zahteva vrednost prilikom dodavanja rezultata testa?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Zahteva prilog" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Da li ovaj test zahteva fajl kao prilog prilikom dodavanja rezultata testa?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Validni izbori za ovaj test (razdvojeni zapetom)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "Stavke sa spiska materijala se ne mogu modifikovati - sklapanje je zaključano" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "Stavke sa spiska materijala se ne mogu modifikovati - sklapanje varijanti je zaključano" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Izaberi nadređeni deo" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Pod-deo" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Izaberi deo koji će biti korišćen u spisku materijala" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Količina spiskova materijala za ovu stavku sa spiska materijala" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Ova stavka sa spiska materijala je opciona" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Ova stavka sa spiska materijala se može potrošiti (nije praćena u nalozima za izradu)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Referenca stavke sa spiska materijala" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Beleške stavki sa spiska materijala" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Suma" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Suma spiska materijala" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Validirano" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Ova stavka sa spiska materijala je validirana" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Biva nasleđeno" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Ova stavka sa spiska materijala je nasleđivana od spiska materijala za varijante delova" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Stavke sa zaliha za varijante delova se mogu koristiti za ovu stavku sa spiska materijala" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Količina mora biti ceo broj za delove koji se mogu pratiti" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Zamenski deo mora biti određen" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Zamenska stavka sa spiska materijala" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Zamenski deo ne može biti isti kao glavni deo" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Nadređena stavka sa spiska materijala" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Zamenski deo" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Deo 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Deo 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Izaberi povezan deo" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Beleška za ovu relaciju" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Relacija između delova ne može biti kreirana između jednog istog dela" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Identična veza već postoji" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Nadređena kategorija" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Nadređena kategorija dela" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Podkategorije" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Rezultati" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Broj rezultata napravljenih na osnovu ovog šablona" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Valuta kupovine za ovu stavku sa zaliha" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Originalni deo" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Izaberi originalni deo za duplikaciju" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kopiraj sliku" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Kopiraj sliku sa originalnog dela" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Kopiraj spisak materijala" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Kopiraj spisak materijala sa originalnog dela" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Kopiraj parametarske podatke sa originalnog dela" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Kopiraj beleške" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Kopiraj beleške sa originalnog dela" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Inicijalna količina zaliha" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Odredi inicijalnu količinu zaliha za ovaj deo. Ukoliko je količina nula, neće biti dodate zalihe." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Inicijalna lokacija zaliha" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Odredi inicijalnu lokaciju zaliha za ovaj deo" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Izaberi dobavljača (ostavi prazno za preskakanje)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Izaberi proizvođača (ostavi prazno za preskakanje)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Broj dela proizvođača" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Izabrana kompanija nije validan dobavljač" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Izabrana kompanija nije validan proizvođač" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Deo proizvođača koji se poklapa sa ovim brojem dela proizvođača već postoji" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Deo dobavljača koji se opklapa sa ovim brojem dela dobavljača već postoji" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Naziv kategorije" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Izrađivanje" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Stavke sa zaliha" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Revizije" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Ukupne zalihe" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Nealocirane zalihe" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Varijante zaliha" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Dupliraj deo" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Kopiraj inicijalne podatke od drugog dela" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kopiraj sliku" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Kopiraj sliku sa originalnog dela" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Kopiraj spisak materijala" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Kopiraj spisak materijala sa originalnog dela" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Kopiraj beleške" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Kopiraj beleške sa originalnog dela" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Početne zalihe" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Kreiraj deo sa početnom količinom zaliha" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Informacije o dobavljaču" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Dodaj inicijalne informacije o dobavljaču za ovaj deo" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Kopiraj parametre kategorije" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Kopiraj parametarske šablone sa izabrane kategorije dela" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Postojeća slika" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Ime fajla postojeće slike dela" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Fajl sa slikom ne postoji" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Validiraj ceo spisak materijala" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Može se izgraditi" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Minimalna cena" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Izmeni izračunatu vrednost za minimalnu cenu" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Minimalna valuta cene" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Maksimalna cena" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Izmeni izračunatu vrednost maksimalne cene" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Maksimalna valuta cene" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Ažuriraj" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Ažuriraj cene za ovaj deo" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Nija moguća konverzija iz dostavljen valute u {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Minimalna cena ne sme biti veća od maksimalne cene" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Maksimalna cena ne sme biti manja od minimalne cene" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Izaberi nadređeni sklop" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Izaberi komponentu dela" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Izaberi deo sa kog će se kopirati spisak materijala" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Ukloni postojeće podatke" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Ukloni postojeće stavke sa spiska materijala pre kopiranja" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Uključi nasleđeno" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Uključi stavke sa spiska materijala koje su nasleđene od šablonskih delova" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Preskoči nevažeće vrste" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Omogući ovu opciju za preskakanje nevažećih vrsta" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Kopiraj zamenske delove" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Kopiraj zamenske delove prilikom duplikacije stavki sa spiska materijala" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Notifikacija o niskim zalihama" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Dostupne zalihe za {part.name} su pale ispod konfigurisanog minimalnog nivoa" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Instalirano" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Plugin ne može biti obrisan jer je trenutno aktivan" @@ -7023,23 +7463,23 @@ msgstr "Nema određene akcije" msgid "No matching action found" msgstr "Nema poklapajuće akcije" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Nema poklapanja za podatke sa bar koda" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Pronađeno poklapanje za podatke sa bar koda" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Model nije podržan" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Instanca modela nije pronađena" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Bar kod se poklapa sa postojećom stavkom" @@ -7055,51 +7495,67 @@ msgstr "Nema pronađenih podudarajućih delova dobavljača" msgid "Multiple matching supplier parts found" msgstr "Više podudarajućih delova dobavljača pronađeno" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Nema podudarajućeg plugina za podatke sa bar koda" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Podudarajući deo dobavljača" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Stavka je već primljena" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Nijedan plugin se ne poklapa sa dobavljačevim bar kodom" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Više pronađenih poklapajućih stavki porudžbine" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Nema podudarajućih stavki porudbžine pronađenih" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Nema dostavljenih naloga za prodaju" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Bar kod se ne poklapa sa postojećom stavkom sa zaliha" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Stavka sa zaliha se ne podudara sa stavkom porudbžine" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Nedovoljno dostupnih stavki" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Stavka alocirana nalogu za prodaju" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Nema dovoljno informacija" @@ -7108,23 +7564,23 @@ msgstr "Nema dovoljno informacija" msgid "Found matching item" msgstr "Pronađena stavka" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Deo dobavljača se ne poklapa sa stavkom porudžbine" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Stavka porudžbine je već završena" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Dalje informacije neophodne za primanje ove stavke" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Primljene stavke sa naloga za kupovinu" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Greška pri prijemu stavke porudžbine" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Pruža ugrađenu podršku za bar kodove" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Kratki prefiks bar koda" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Prilagođava prefiks koji se koristi za kratke bar kodove, može biti korisno u okruženjima sa više instanci aplikacije" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL koji služi za slanje poruka na Slack kanal" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Otvori link" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Pruža podršku za štampanje PDF natpisa" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Debug mod" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Omogućava debug mod - vraća sirov HTML umesto PDF-a" @@ -7653,55 +8117,55 @@ msgstr "poslednji put korišćeno" msgid "Options" msgstr "Opcije" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Veličina strane za stranu sa natpisima" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Preskoči natpise" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Preskoči ovaj broj natpisa pri štampanju strane sa natpisima" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Border" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Štampa border oko svakog natpisa" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Lendskejp" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Štampa stranu sa natpisima u landscape modu" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "Štampač natpisa" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Stavlja više natpisa na jednu stranu" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Natpis je prevelik za veličinu stranice" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Nijedan natpis nije generisan" @@ -7753,77 +8217,85 @@ msgstr "Pruža podršku za skeniranje TME bar kodova" msgid "The Supplier which acts as 'TME'" msgstr "Dobavljač koji se ponaša kao 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Instalacija plugina je onemogućena" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Plugin instaliran uspešno" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Instaliran plugin na {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Plugin nije pronađen u registru" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Plugin nije paket plugin" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Ime paketa plugina nije pronađeno" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Samo osoblje može da administrira pluginove" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Deinstaliranje plugina je onemogućeno" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Plugin ne može biti deinstaliran jer je trenutno aktivan" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Plugin nije instaliran" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Instalacija plugina nije pronađena" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Plugin uspešno deinstaliran" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "Paket plugin" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Plugin" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Nije pronađen autor" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Plugin '{p}' nije kompatibilan sa trenutnom verzijom aplikacije {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Plugin zahteva najmanje verziju {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Plugin zahteva najviše verziju {v}" @@ -8114,176 +8586,184 @@ msgstr "Obriši konfiguraciju" msgid "Delete the plugin configuration from the database" msgstr "Obriši konfiguraciju plugina iz baze podataka" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Stavke" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Plugin nije pronađen" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Plugin ne podržava štampanje natpisa" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Nevažeće dimenzije natpisa" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Nema važećih stavki dostavljenih šablonu" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Legal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Letter" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Šablonski fajl sa ovim imenom već postoji" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Ime šablona" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Opis šablona" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Broj revizija (auto-inkrement)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Priloži kao model uz štampanje" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Sačuvaj izveštaj kao prilog uz uvezanu instancu modela prilikom štampanja" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Šablon imena fajlova" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Šablon za generisanje imena fajlova" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Šablon je omogućen" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Tip ciljanog modela za šablon" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filteri" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Filteri upita nad šablonima (lista razdvojena zarezom ključ=vrednost parova)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Šablonski fajl" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Veličina strane za PDF izveštaje" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Renderuj izveštaj u landscape orijentaciji" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Širina (u milimetrima)" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Širina natpisa, u milimetrima" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Visina (u milimetrima)" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Visina natpisa, u milimetrima" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Isečak" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Izveštaj isečka fajla" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Opis isečka fajla" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Sredstvo" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Izveštaj fajla sredstva" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Opis fajla sredstva" @@ -8291,23 +8771,23 @@ msgstr "Opis fajla sredstva" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Izaberi šablon izveštaja" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Spisak primarnih ključeva stavke koje će biti uključene u ovaj izveštaj" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Izaberi šablon natpisa" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Plugin za štampanje" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Izaberi plugin za korišćenje prilikom štampanja natpisa" @@ -8338,13 +8818,10 @@ msgstr "Materijali neophodni" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Slika dela" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Izdato" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Potrebno za" @@ -8380,8 +8857,8 @@ msgstr "Ukupno" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serijski broj" @@ -8405,7 +8882,7 @@ msgstr "Izveštaj sa testa za stavku sa zaliha" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Instalirane stavke" @@ -8438,810 +8915,922 @@ msgstr "Nema rezultata (neophodno)" msgid "No result" msgstr "Nema rezultata" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Slika nije pronađena" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image tag zahteva instancu dela" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image tag zahteva instancu kompanije" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Filtriraj po dubini lokacije" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Filtriraj po nadređenim lokacijama" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Uključi podlokacije u filtriranim rezultatima" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Nadređena lokacija" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Filtriraj po nadređenoj lokaciji" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Ime dela" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Ime dela sadrži" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Ime dela (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "Interni deo broja" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "Interni deo broja sadrži (osetljivo na velika i mala slova)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "Interni broj dela (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Minimalne zalihe" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Maksimalne zalihe" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Statusni kod" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Eksterna lokacija" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Potrošeno od strane naloga za izradu" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "Instalirano u drugu stavku sa zaliha" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Stablo dela" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Ažurirano pre" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Ažurirano nakon" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Popis pre" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Popis nakon" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Datum isteka pre" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Datum isteka nakon" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Zastarelo" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Količina je neophodna" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Validan deo mora biti dosavljen" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Dati dobavljač ne postoji" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Deo dobavljača ima definisanu veličinu pakovanja, ali fleg use_pack_size nije postavljen" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Serijski brojevi ne mogu biti dostavljeni za deo koji nije moguće pratiti" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Tip lokacije zaliha" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Tipovi lokacija zaliha" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Podrazumevana ikonica za sve lokacije koje nemaju podešenu ikonicu (opciono)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Lokacija zaliha" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Lokacija zaliha" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Vlasnik" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Izaberi vlasnika" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Stavke sa zaliha ne mogu biti direktno locirane u strukturnim lokacijama zaliha, ali mogu biti locirane u podređenim lokacijama." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Eksterna" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Ovo je eksterna lokacija zaliha" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Tip lokacije" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Tip lokacija zaliha za ovu lokaciju" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Ne možete postaviti ovu lokaciju zaliha kao strukturnu jer su već neke stavke locirane na njoj!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Deo mora biti određen" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Stavka sa zaliha ne može biti locirana u strukturnim lokacijama zaliha!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Stavka sa zaliha ne može biti kreirana za virtuelne delove" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Deo tipa ('{self.supplier_part.part}') mora biti {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Količina mora biti 1 za stavku sa serijskim brojem" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Serijski broj ne može biti postavljen ukoliko je količina veća od 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Stavka ne može da pripada samoj sebi" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Stavka mora da ima referencu izgradnje ukoliko is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Referenca izgradnje ne ukazuje na isti objekat dela" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Nadređena stavka sa zaliha" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Osnovni deo" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Izaberi odgovarajući deo dobavljača za ovu stavku sa zaliha" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Gde je locirana ova stavka sa zaliha?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Pakovanje u kom je ova stavka sa zaliha" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Instalirano u" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Da li je ova stavka instalirana u drugu stavku?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Serijski broj za ovu stavku" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Šifra ture za ovu stavku sa zaliha" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Količina zaliha" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Izvorna gradnja" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Nalog za ovu stavku sa zaliha" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Potrošeno od strane" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Nalog za izradu koji je potrošio ovu stavku sa zaliha" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Izvorni nalog za kupovinu" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Nalog za kupovinu za ovu stavku sa zaliha" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Odredište naloga za prodaju" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Datum isteka za stavku sa zaliha. Zalihe će se smatrati isteklim nakon ovog datuma" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Obriši kad je potrošeno" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Obriši ovu stavku sa zaliha kada su zalihe potrošene" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Cena kupovine jedne jedinice u vreme kupovine" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Konvertovano u deo" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Deo nije postavljen kao deo koji je moguće pratiti" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Količina mora biti ceo broj" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Količina ne sme da pređe dostupnu količinu zaliha ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Serijski brojevi moraju biti dostavljeni kao lista" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Količine se ne poklapaju sa serijskim brojevima" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Test šablon ne postoji" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Stavka sa zaliha je dodeljena nalogu za prodaju" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Stavka sa zaliha je instalirana u drugu stavku" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Stavka sa zaliha sadrži druge stavke" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Stavka sa zaliha je dodeljena mušteriji" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Stavka sa zaliha je trenutno u produkciji" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Serijalizovane zalihe se ne mogu spojiti" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Dupliraj stavke sa zaliha" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Stavke sa zaliha se moraju odnositi na isti deo" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Stavke sa zaliha se moraju odnositi na isti deo dobavljača" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Statusne šifre zaliha moraju da se poklapaju" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Stavka se ne može pomeriti jer nije na zalihama" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "Praćenje stavke sa zaliha" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Ulazne beleške" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "Rezultat testa stavke sa zaliha" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Vrednost mora biti dostavljena za ovaj test" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Prilog mora biti dostavljen za ovaj test" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "Nevažeća vrednost za ovaj test" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Rezultat testa" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Vrednost završetka testa" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Prilog uz test rezultat" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Beleške sa testa" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "Stanica za testiranje" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "Identifikator stanice za testiranje gde je test izvršen" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Započeto" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "Vreme početka testa" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "Završeno" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "Vreme završetka testa" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "Generisana šifra ture" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "Izaberi nalog za izradu" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "Izaberi stavku sa zaliha za koju će se generisati šifra ture" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "Izaberi lokaciju za koju će se generisati šifra ture" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "Izaberi deo za koji će se generisati šifra ture" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "Izaberi nalog za kupovinu" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "Unesi količinu za šifru ture" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "Generisan serijski broj" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "Izaberi deo za koji će se generisati serijski broj" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "Količina serijskih brojeva koji će se generisati" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "Test šablon za ovaj rezultat" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "ID šablona ili ime testa mora biti dostavljeno" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "Vreme završetka testa ne može biti pre vremena početka testa" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Nadređena stavka" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "Nadređena stavka sa zaliha" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Koristi pakovanja prilikom dodavanja: količina je definisana brojem pakovanja" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Unesi serijske brojeve za nove stavke" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Dobavljački broj dela" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Isteklo" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Podređene stavke" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "Stavke za praćenje" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Nabavna cena ove stavke, po jedinici ili pakovanju" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Unesi broj stavka sa zaliha za serijalizaciju" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Količina ne sme da pređe dostupnu količinu zaliha ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Odredišna lokacija zaliha" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Serijski brojevi ne mogu biti dodeljeni ovom delu" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Serijski broj već postoji" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Izaberi stavku za instaliranje" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Količina za instaliranje" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Izaberi količinu stavki za instaliranje" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Dodaj beleške transakcija (opciono)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Količina za instaliranje mora biti najmanje 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Stavka je nedostupna" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Izabrani deo nije na spisku materijala" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Količina za instaliranje ne sme preći dostupnu količinu" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Odredišna lokacija za deinstalirane stavke" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Izaberi deo u koji će se konvertovati stavka" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Izabrani deo nije validna opcija za konverziju" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Ne može se konvertovati stavka sa dodeljenim delom dobavljača" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Statusni kod stavke sa zaliha" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Izaberi deo u koji će se konvertovati stavka" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Izabrani deo nije validna opcija za konverziju" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Ne može se konvertovati stavka sa dodeljenim delom dobavljača" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Izaberi stavke kojoj će se promeniti status" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Nije izabrana stavka" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Podlokacije" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Lokacija nadređenih zaliha" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Deo mora biti za prodaju" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Stavka je alocirana nalogu za prodaju" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Stavka je alocirana nalogu za izradu" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Mušterija kojoj će se dodeliti stavke sa zaliha" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Izabrana kompanija nije mušterija" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Beleške dodeljivanja zaliha" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Lista stavki mora biti dostavljena" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Beleške spajanja zaliha" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Dozvoli neslagajuće dobavljače" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Dozvoli spajanje stavki sa različitim delovima dobavljača" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Dozvoli neslagajući status" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Dozvoli spajanje stavki sa različitim statusnim kodovima" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Bar dve stavke moraju biti dostavljene" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Nema promena" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Vrednost primarnog ključa stavke" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Stavka nije na zalihama" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Beleške transakcija zaliha" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Beleške transakcija zaliha" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Spojene stavke zaliha" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Pretvoreno u varijaciju" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Započeta obrada naloga za izradu" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Završena obrada naloga za izradu" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Odbijen rezultat naloga za izradu" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Potrošeno od strane nalga za izradu" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Isporučeno prema nalogu za prodaju" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Primljeno prema nalogu za kupovinu" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Vraćeno prema nalogu za vraćanje" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Poslato mušteriji" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Vratila mušterija" @@ -9527,19 +10124,19 @@ msgstr "Korisnici" msgid "Select which users are assigned to this group" msgstr "Odaberi koje korisnike želiš da dodaš u ovu grupu" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Lični podaci" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Dozvole" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Značajni datumi" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Token je opozvan" @@ -9547,279 +10144,283 @@ msgstr "Token je opozvan" msgid "Token has expired" msgstr "Token je istekao" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API token" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API tokeni" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Naziv tokena" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Prilagođen naziv tokena" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Datum isteka tokena" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Poslednji put aktivan" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Poslednji put kada je token korišćen" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Opozvano" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Skup dozvola" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Pregledaj" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Dozvola za pregled stavki" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Dodaj" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Dozvola za dodavanje stavki" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Promeni" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Dozvole za izmenu stavki" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Obriši" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Dozvola za brisanje stavki" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Nalozi za kupovinu" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Nalozi za prodaju" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Nalozi za vraćanje" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Korisničko ime" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Ime" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Ime korisnika" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Prezime" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Prezime korisnika" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Adresa E-pošte korisnika" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Super korisnik" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Da li je ovaj korisnik Super korisnik?" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Da li je nalog ovog korisnika aktivan?" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Vaš nalog je kreiran" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Molimo vas koristite opciju resetovanja lozinke da biste se prijavili" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Dobrodošli u InvenTree" diff --git a/src/backend/InvenTree/locale/sv/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/sv/LC_MESSAGES/django.po index 5366e73e04..6a5ab693a6 100644 --- a/src/backend/InvenTree/locale/sv/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/sv/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API-slutpunkt hittades inte" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Användaren har inte behörighet att se denna modell" @@ -65,150 +69,155 @@ msgstr "Bekräfta e-postadress" msgid "You must type the same email each time." msgstr "Du måste ange samma e-post varje gång." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Den angivna primära e-postadressen är inte giltig." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Den angivna e-postdomänen är inte godkänd." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Ogiltig enhet angiven ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Inget värde angivet" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Kunde inte konvertera {original} till {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Ogiltigt antal angivet" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Information om felet finns under Error i adminpanelen" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Ange datum" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Anteckningar" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Värdet '{name}' visas inte i mönsterformat" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Det angivna värdet matchar inte det obligatoriska mönstret: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Tom serienummersträng" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Serienummret finns redan" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Ogiltig grupp: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Gruppintervall {group} överstiger tillåtet antal ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Inga serienummer hittades" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Ta bort HTML-taggar från detta värde" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Anslutningsfel" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Servern svarade med ogiltig statuskod" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Undantag inträffade" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Servern svarade med ogiltigt innehållslängdsvärde" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Bilden är för stor" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Nedladdning av bilder överskred maximal storlek" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Fjärrservern returnerade tomt svar" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Angiven URL är inte en giltig bildfil" @@ -216,159 +225,203 @@ msgstr "Angiven URL är inte en giltig bildfil" msgid "Log in to the app" msgstr "Logga in på appen" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-postadress" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Du måste aktivera tvåfaktorsautentisering innan du kan göra något annat." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Fel vid validering av plugin" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata måste vara ett python dict objekt" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Metadata för plugin" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "JSON metadata fält, för användning av externa plugins" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Felaktigt formaterat mönster" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Okänd formatnyckel angiven" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Obligatorisk formatnyckel saknas" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Textfältet kan inte lämnas tomt" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referensen måste matcha obligatoriskt mönster" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referensnumret är för stort" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Ogiltigt val" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Namn" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Beskrivning" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Beskrivning (valfritt)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Sökväg" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown anteckningar (valfritt)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Streckkodsdata" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Tredje parts streckkodsdata" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Streckkodsdata" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Unik hash med streckkodsdata" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Befintlig streckkod hittades" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Serverfel" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Ett fel har loggats av servern." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Bild" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Måste vara ett giltigt nummer" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Valuta" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Välj valuta från tillgängliga alternativ" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Ogiltigt värde" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Kopiera parametrar" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabiska" @@ -521,46 +574,48 @@ msgstr "Kinesiska (Förenklad)" msgid "Chinese (Traditional)" msgstr "Kinesiska (Traditionell)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Ogiltig fysisk enhet" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Inte en giltig valutakod" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Orderstatus" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Föregående tillverkning" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Inkludera varianter" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Inkludera varianter" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Inkludera varianter" msgid "Part" msgstr "Del" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategori" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Tilldelad till" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Skapad före" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Skapad efter" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Har startdatum" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Tillverkningen måste avbrytas innan den kan tas bort" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Valfri" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Spårad" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Testbar" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Allokerad" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Konsumerad" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Tillgänglig" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Byggorder" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Plats" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Byggordrar" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Tillverknings order referens" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referens" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Välj del att tillverka" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Försäljningsorderreferens" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Källa Plats" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Välj plats att ta lager från för detta bygge (lämna tomt för att ta från någon lagerplats)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Destinationsplats" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Välj plats där de färdiga objekten kommer att lagras" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Tillverkat antal" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Antal lagerobjekt att bygga" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Slutförda objekt" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Antal lagerposter som har slutförts" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Tillverknings status" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Tillverkning statuskod" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Batchkod" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Batch-kod för denna byggutdata" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Skapad" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Datum för slutförande" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Måldatum för färdigställande. Tillverkningen kommer att förfallas efter detta datum." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Slutförandedatum" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "slutfört av" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Utfärdad av" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Användare som utfärdade denna tillverknings order" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Ansvarig" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Extern länk" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Länk till extern URL" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Projektkod" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Tillverknings order {build} har slutförts" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "En tillverknings order har slutförts" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Ingen byggutgång angiven" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Byggutgång är redan slutförd" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Byggutgång matchar inte bygg order" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Bygg objekt" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Bygg objekt" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Antal" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Byggobjekt måste ange en byggutgång, eftersom huvuddelen är markerad som spårbar" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Antal måste vara 1 för serialiserat lager" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Tilldelad kvantitet ({q}) får inte överstiga tillgängligt lagersaldo ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Lagerposten är överallokerad" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Artikel i lager" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Källa lagervara" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Lagersaldo att allokera för att bygga" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Installera till" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Destination lagervara" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Delnamn" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Bygg utdata" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Byggutdata matchar inte överordnad version" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Serienummer" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Ange serienummer för att tillverkade produkter" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "En lista över tillverkade produkter måste anges" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Lagerplats för skrotade produkter" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Ignorera alla lagerallokeringar för skrotade produkter" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Plats för färdiga produkter" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Slutför utfall om lager inte har tilldelats fullt ut" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Ta bort ofullständiga produkter" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Ta bort eventuella produkter som inte har slutförts" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Acceptera ofullständig" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Acceptera att det önskade antalet produkter som inte har slutförts" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Tillverknings ordern är ofullständig" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Spårbar" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Ärvd" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Tillåt varianter" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Väntar" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Produktion" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Avbruten" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Slutför" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Tillverknings order {build} har slutförts" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "En tillverknings order har slutförts" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "Är länk" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Är fil" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Ogiltig valutakod" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Uppdaterad" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "Unik projektkod" msgid "Project description" msgstr "Projektbeskrivning" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Användare" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Pris" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktiv" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Användare" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Pris" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Hemlig" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Meddelande-ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Värd" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Id" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Titel" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Länk" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Sammanfattning" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Läs" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Bildfil" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Symbol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Definition" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Bilaga" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Saknad fil" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Extern länk saknas" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Modelltyp" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Välj fil att bifoga" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Kommentar" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Uppladdningsdatum" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "Filstorlek" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Filstorlek" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Logisk nyckel" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Värde" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etikett" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Färg" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Modell" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Låst" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Källsträng" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Skapad" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Senast uppdaterad" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Parametermall" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Kryssruta" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Val" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Aktiverad" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Mall" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Data" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Streckkodsdata" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Tidsstämpel" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Sammanhang" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Svar" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Resultat" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Ett fel inträffade" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "E-postmeddelande" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Bekräftad" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Inget svar" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "Tråd-ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Tråd" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "E-posttrådar" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Nyckel" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Väntande uppgifter" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Schemalagda uppgifter" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Misslyckade uppgifter" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Uppgifts-ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Lås" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Uppgiftsnamn" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Funktion" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Funktionsnamn" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argument" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Filnamn" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "Modelltyp" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "Ingen grupp" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "dagar" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Komponent" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Virtuell" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Delar är virtuella som standard" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Visa relaterade delar" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Visa relaterade delar för en del" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Visningsformat för delnamn" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Formatera för att visa artikelnamnet" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Interna priser" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Aktivera etikettutskrift" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Aktivera etikettutskrift från webbgränssnittet" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Etikettbild DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Aktivera rapporter" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Aktivera generering av rapporter" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Debugläge" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "Sidstorlek" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "Standard sidstorlek för PDF-rapporter" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" -msgstr "" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" +msgstr "Sidstorlek" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" -msgstr "" +msgid "Default page size for PDF reports" +msgstr "Standard sidstorlek för PDF-rapporter" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Förhindra produktion från att slutföras tills alla nödvändiga tester är klara" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Aktivera registrering" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Aktivera SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" -msgstr "" +msgid "Enable registration" +msgstr "Aktivera registrering" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" +msgstr "Aktivera SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" -msgstr "Tillåtna domäner" - -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" -msgstr "" +#: common/setting/system.py:1096 +msgid "Allowed domains" +msgstr "Tillåtna domäner" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Datumformat" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Ogiltigt domännamn: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Tillverkare" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Företag" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Kontakt" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adress" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adresser" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Välj företag" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Primär adress" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Rad 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Adressrad 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Rad 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Adressrad 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Postnummer" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Land" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Basdel" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Välj del" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "MPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Leverantör" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Välj leverantör" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Företagsnamn" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "I lager" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Placerad" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Datafil" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Kolumner" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Fältfilter" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Fält" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Kolumn" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "Radindex" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Fel" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Giltig" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Rader" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopior" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Ansluten" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Okänd" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Varning" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Frånkopplad" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Fel" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Etikettskrivare" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Namn på maskin" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Maskintyp" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Typ av maskin" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Inga fel" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Maskin" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Konfigurationstyp" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grupp" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Har projektkod" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Skapad av" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Skapad efter" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Intern del" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Slutförd" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "Försäljningsorder" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Startdatum" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Måldatum" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Status" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Mål" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Kund" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Skickad" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Leveransdatum" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Kontrollerad av" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Fakturanummer" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Allokeringsmängden måste vara större än noll" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Rad" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Kopiera parametrar" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Leverantörsnamn" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Streckkod" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Förlorad" @@ -5718,1279 +6125,1312 @@ msgstr "Förlorad" msgid "Returned" msgstr "Återlämnad" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Pågående" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Reparera" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Ersätt" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Återbetala" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Avvisa" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Djup" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Har resultat" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Är variant" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Använder" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Delkategori" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Ikon" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Ikon (valfritt)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Standardvärde" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Artiklar" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Delnamn" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Är mall" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Variant av" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Nyckelord" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Delkategori" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revision" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Datum" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Validerad" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Del 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Del 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Underkategorier" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Resultat" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Originaldel" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Kopiera bild" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Kopiera test" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Kategorinamn" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Revisioner" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Kopiera bild" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Kopiera test" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Uppdatera" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Hoppa över ogiltiga rader" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Installerad" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "Ingen åtgärd specificerad" msgid "No matching action found" msgstr "Ingen matchande åtgärd hittades" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Öppna länk" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "senast använd" msgid "Options" msgstr "Alternativ" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Hoppa över etiketter" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Mallnamn" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filter" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Mallfil" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Bredd [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Höjd [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Delbild" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Serienummer" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "Inga resultat" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Statuskod" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Extern plats" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Uppdaterad efter" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Ägare" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Välj ägare" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Platstyp" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Grunddel" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Konverterad till del" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Testresultat" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "Startad" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Ingen förändring" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Sammanfogade lagerposter" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Konverterad till variant" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Bygg orderutgång skapad" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Bygg orderutgång slutförd" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Konsumeras av byggorder" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Skickat till kund" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Returnerad från kund" @@ -9527,19 +10124,19 @@ msgstr "Användare" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Personlig information" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Behörigheter" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Tokennamn" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Visa" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Lägg till" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Ändra" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Radera" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "Gäst" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "Språk" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "Tema" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "Visningsnamn" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Användartyp" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organisation" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Primär grupp" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Admin" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Användarnamn" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Förnamn" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Förnamn på användaren" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Efternamn" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Efternamn på användaren" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Avsändarens E-postadress" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superanvändare" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Är den här användaren en superanvändare" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Är detta användarkonto aktivt" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "Lösenord" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Ditt konto har skapats." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Använd funktionen för lösenordsåterställning för att logga in" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Välkommen till InvenTree" diff --git a/src/backend/InvenTree/locale/th/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/th/LC_MESSAGES/django.po index 6fc7cd6b1f..dca27a034e 100644 --- a/src/backend/InvenTree/locale/th/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/th/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Thai\n" "Language: th_TH\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "ไม่พบ API endpoint" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "" @@ -65,150 +69,155 @@ msgstr "การยืนยันอีเมล" msgid "You must type the same email each time." msgstr "" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "ปริมาณสินค้าไม่ถูกต้อง" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "ป้อนวันที่" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "หมายเหตุ" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "หมายเลขซีเรียลซ้ำกัน" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "ไม่พบหมายเลขซีเรียล" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "การเชื่อมต่อขัดข้อง" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "ไฟล์รูปภาพมีขนาดใหญ่เกินไป" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -216,159 +225,203 @@ msgstr "" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "อีเมล" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "ข้อมูลเมตาของปลั๊กอิน" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "ชื่อ" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "คำอธิบาย" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "ข้อมูลบาร์โค้ด" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "บาร์โค้ดนี้มีในระบบแล้ว" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "เกิดข้อผิดพลาดที่เซิร์ฟเวอร์" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "ต้องเป็นตัวเลข" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "สกุลเงิน" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "" msgid "Chinese (Traditional)" msgstr "" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "สถานที่" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "ออกโดย" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "จำนวนต้องมีค่ามากกว่า 0" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "อยู่ระหว่างดำเนินการ" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "ยกเลิกแล้ว" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "สำเร็จแล้ว" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "ผู้ใช้งาน" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "ผู้ใช้งาน" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "ลิงก์" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "ไฟล์แนบ" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "ไม่พบไฟล์" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "เลือกไฟล์ที่ต้องการแนบ" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "ความคิดเห็น" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "ชื่อไฟล์" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" +msgstr "" + +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "ไฟล์ข้อมูล" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "สำเร็จแล้ว" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "สถานะ" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "จัดส่งแล้ว" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "สูญหาย" @@ -5718,1279 +6125,1312 @@ msgstr "สูญหาย" msgid "Returned" msgstr "ส่งคืนแล้ว" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "ชิ้นส่วน" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "จัดส่งให้ลูกค้าแล้ว" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "ยินดีต้อนรับเข้าสู่ Inventree" diff --git a/src/backend/InvenTree/locale/tr/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/tr/LC_MESSAGES/django.po index ac6a778ad0..078c836363 100644 --- a/src/backend/InvenTree/locale/tr/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/tr/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API uç noktası bulunamadı" -#: InvenTree/api.py:438 -msgid "List of items must be provided for bulk operation" -msgstr "" - #: InvenTree/api.py:445 +msgid "List of items must be provided for bulk operation" +msgstr "Toplu işlem için öge listesi sağlanmalıdır" + +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Ögeler bir liste olarak sağlanmalıdır" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Geçersiz ögeler listesi sağlandı" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "Tüm filtre yalnızca true ile kullanılmalıdır" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Sağlanan ölçüte uygun bir eşleşme yok" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Değer verilmemiş" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "Bu alan eşsiz olmalı." -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Kullanıcının bu modeli görüntüleme izni yok" @@ -65,310 +69,359 @@ msgstr "E-posta adresi onayı" msgid "You must type the same email each time." msgstr "Her seferind eaynı e-posta adresini yazmalısınız." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Sağlanan e-posta adresi geçerli değil." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Sağlanan e-posta alanı onaylanmadı." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Geçersiz ürün girildi ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Değer verilmemiş" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "{original} birimi {unit} birimine dönüştürülemedi" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Geçersiz veri sağlandı" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Hata ayrıntıları yönetici panelinde bulunabilir" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Tarih giriniz" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Geçersiz ondalık değer" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Notlar" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "'{name}' değeri desen formatında yer almıyor" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Sağlanan değer gerekli kalıpla eşleşmiyor: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Geçersiz grup: {grup}" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Boş seri numarası dizesi" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Yinelenen seri" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "Geçersiz grup: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Grup aralığı {group}, izin verilen miktarı aşmaktadır ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Seri numarası bulunamadı" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "Benzersiz seri numaralarının sayısı ({n}) miktarla eşleşmeli ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Bu değerden HTML etiketlerini kaldır" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Veriler yasaklanmış işaretleme içeriği içeriyor" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" -msgstr "" +msgstr "Geçersiz URL: ana makina adı yok" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" -msgstr "" +msgstr "Geçersiz URL: ana makina adı çözümlenemedi" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" -msgstr "" +msgstr "URL özel veya ayrılmış bir IP adresini göstermektedir" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" -msgstr "" +msgstr "Çok fazla yeniden yönlendirme" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Bağlantı hatası" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Sunucu geçersiz durum kodu ile cevap verdi" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "İstisna oluştu" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Sunucu geçersiz Content-Length değeriyle yanıt verdi" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Görsel boyutu çok büyük" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Görsel indirme maksimum boyutu aştı" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Uzak sunucu boş cevap döndü" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "Sağlanan URL geçerli bir görsel dosyası değil" #: InvenTree/magic_login.py:31 msgid "Log in to the app" -msgstr "Uygulamaya giriş yapın" +msgstr "Uygulamada oturum aç" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "E-posta" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Başka bir şey yapmadan önce iki faktörlü kimlik doğrulamayı etkinleştirme gerekir." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Eklenti doğrulama sırasında hata oluştu" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata, bir python dict nesnesi olmalıdır" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Plugin Metaverileri" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Harici eklentiler tarafından kullanım için JSON metadata alanı" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Yanlış biçimlendirilmiş desen" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Belirtilen bilinmeyen format anahtarı" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Gerekli format anahtarı eksik" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Referans alanı boş olamaz" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Referans {pattern} deseniyle mutlaka eşleşmeli" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Referans sayısı çok fazla" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Geçersiz seçim" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Adı" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Açıklama" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Açıklama (isteğe bağlı)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Yol" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Aynı kaynak altında birden fazla aynı isim kullanılamaz" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown notları (isteğe bağlı)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Barkod Verisi" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Üçüncü parti barkod verisi" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Barkod Hash" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Barkod verisinin benzersiz hash'i" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Var olan barkod bulundu" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Sunucu Hatası" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Bir hafta sunucu tarafından kayıt edildi." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Görsel" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Geçerli bir numara olmalı" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Para birimi" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Mevcut seçeneklerden para birimini seçin" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "Bu alan boş olamaz." -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Geçersiz değer" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "Geçersiz içerik türü biçimi" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "İçerik türü bulunamadı" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "İçerik türü gerekli mixin sınıfı ile eşleşmemektedir" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Parametreleri Kopyala" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "Satırları Kopyala" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "Satırları orijinal siparişten kopyala" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "Ek Kalemleri Kopyala" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "Orijinal siparişten ek kalemleri kopyala" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arapça" @@ -521,46 +574,48 @@ msgstr "Çince (Basitleştirilmiş)" msgid "Chinese (Traditional)" msgstr "Çince (Geleneksel)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "Güncelleme mevcut" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "InvenTree için güncelleme mevcut" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Geçersiz fiziksel birim" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Geçerli bir para birimi kodu değil" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Sipariş Durumu" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Üst Yapım İşi" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "Varyantları Dahil Et" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "Varyantları Dahil Et" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "Varyantları Dahil Et" msgid "Part" msgstr "Parça" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Kategori" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Kök Üretim" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Bana atandı" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Atanılan Kişi" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "Daha önce oluşturuldu" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "Sonra oluşturuldu" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "Başlangıç tarihi var" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "Başlangıç tarihi önce" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "Başlangıç tarihi sonra" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "Hedef tarihi var" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "Hedef tarihi önce" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "Hedef tarihi sonra" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "Daha önce tamamlandı" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "Sonra tamamlandı" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "En yakın tarih" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "Maksimum Tarih" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "Ağacı Hariç Tut" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Üretim silinemeden önce iptal edilmelidir" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Sarf Malzemesi" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "İsteğe Bağlı" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Montaj" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "İzlenen" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Test Edilebilir" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "Sipariş Açık" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Tahsis Edildi" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Tüketildi" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Mevcut" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Siparişte" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" -msgstr "" +msgstr "Üretim bulunamadı" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Üretim Emri" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Konum" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "Çıktı" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "Çıktı stok kalemi ID'sine göre filtrele. Takılmamış üretim kalemlerini bulmak için ‘null’ kullan." -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Üretim Emirleri" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Montaj BOM listesi henüz doğrulanmadı" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Pasif bir parça için üretim emri oluşturulamaz" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Kilidi açılmış bir parça için üretim emri oluşturulamaz" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "Harici üretim emirleri yalnızca satın alınabilir parçalar için yerine getirilebilir" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Sorumlu kullanıcı veya grup belirtilmelidir" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Üretim emri parçası değiştirilemez" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "Hedef tarih başlangıç tarihinden sonra olmalıdır" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Üretim Emri Referansı" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Referans" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Üretimin kısa açıklaması (isteğe bağlı)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "Bu üretimin tahsis edildiği üretim emri" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Üretilecek parçayı seçin" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Satış Emri Referansı" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "Bu üretimin tahsis edildiği satış siparişi" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Kaynak Konum" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Bu üretim için stok alınacak konumu seçin (herhangi bir stok konumundan amak için boş bırakın)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "Harici Üretim" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "Bu üretim emri harici olarak tamamlanmıştır" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Hedef Konum" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Tamamlanmış ögelerin saklanacağı konumu seçiniz" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Üretim Miktarı" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Üretilecek stok kalemlerinin sayısı" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Tamamlanmış ögeler" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Tamamlanan stok kalemlerinin sayısı" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Üretim Durumu" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Üretim durum kodu" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Sıra numarası" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Bu üretim çıktısının parti kodu" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Oluşturulma tarihi" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "Üretim başlangıç tarihi" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "Bu üretim emri için planlanan başlangıç tarihi" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Hedef tamamlama tarihi" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Üretimin tamamlanması için hedef tarih. Bu tarihten sonra üretim gecikmiş olacak." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Tamamlama tarihi" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "tamamlayan" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Düzenleyen" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Bu üretim emrini düzenleyen kullanıcı" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Sorumlu" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Bu üretim emrinden sorumlu kullanıcı veya grup" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Harici Bağlantı" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Harici URL'ye bağlantı" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Üretim Önceliği" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Bu üretim emrinin önceliği" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Proje Kodu" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Bu üretim emri için proje kodu" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "Açık alt üretim işlemleri varken üretim emri tamamlanamaz" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "Eksik çıktılar varken üretim emri tamamlanamaz" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Üretim tahsisatını tamamlamak için boşaltma görevi başarısız oldu" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "{build} üretim emri tamamlandı" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Bir üretim emri tamamlandı" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "İzlenebilir parçalar için seri numaraları sağlanmalıdır" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Hiçbir üretim çıktısı belirtilmedi" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Üretim çıktısı zaten tamamlanmış" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Üretim çıktısı, üretim emri ile eşleşmiyor" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Miktar sıfırdan büyük olmalıdır" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Miktar çıktı miktarından büyük olamaz" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "Üretim çıktısı tüm gerekli testleri geçmedi" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "{serial} üretim çıktısı gerekli testleri geçmedi" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "Tahsis edilen stok kalemleri hâlâ üretimde" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "Tahsisli kalemler içeren bir üretim çıktısı kısmi olarak tamamlanamaz" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Mevcut miktar ({q}) aşıldı" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Üretim Emri Satırı" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Üretim nesnesi" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Üretim nesnesi" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Miktar" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Üretim emri için gereken miktar" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "Tüketilen Stok Miktarı" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Ana parça izlenebilir olarak işaretlendiğinden, üretim kalemi bir üretim çıktısı belirtmelidir" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" -msgstr "Seçilen stok kalemi BOM satırı ile eşleşmiyor" +msgstr "Seçili stok kalemi BOM satırı ile eşleşmiyor" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "Tahsis edilen miktar sıfırdan büyük olmalıdır" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Seri numaralı stok için miktar bir olmalı" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Tahsis edilen miktar ({q}) mevcut stok miktarını ({a}) aşmamalıdır" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Stok kalemi fazladan tahsis edilmiş" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Stok Kalemi" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Kaynak stok kalemi" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Üretime tahsis edilecek stok miktarı" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Kur" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Hedef stok kalemi" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Üretim Seviyesi" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Parça Adı" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Üretim Çıktısı" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Üretim çıktısı üst üretim ile eşleşmiyor" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Çıktı parçası üretim emri parçası ile eşleşmiyor" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Bu üretim çıktısı zaten tamamlandı" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Bu üretim çıktısı tam tahsis edilmedi" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Üretim çıktısının miktarını girin" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "İzlenebilir parçalar için tamsayı miktar gerekir" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Ürün ağacı izlenebilir parçalar içerdiğinden tamsayı miktar gereklidir" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Seri Numaraları" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Üretim çıktıları için seri numaraları girin" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Üretim çıktısı için stok konumu" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Seri Numaralarını Otomatik Tahsis Et" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Eşleşen seri numaralı gerekli kalemleri otomatik tahsis et" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Şu seri numaraları zaten varlar veya geçersizler" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Bir üretim çıktıları listesi sağlanmalıdır" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Hurdaya ayrılan çıktılar için stok konumu" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Ayırmaları İptal Et" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" -msgstr "Hurdaya ayrılan çıktılar için yapılan tüm stok ayırmalarını iptal et" +msgstr "Hurdaya ayrılan çıktılar için yapılan tüm stok tahsislerini iptal et" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Üretim çıktı(larını) hurdaya ayırma nedeni" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Tamamlanan üretim çıktıları içi konum" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" -msgstr "Tamamlanmamış Ayırmayı Onayla" +msgstr "Eksik Tahsisi Kabul Et" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" -msgstr "Stok henüz tamamen tahsis edilmemşse çıktıları tamamla" +msgstr "Stok henüz tamamen tahsis edilmemişse çıktıları tamamla" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Tahsis Edilen Stoku Tüket" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Bu üretim için zaten tahsis edilmiş olan tüm stokları tüket" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" -msgstr "Tamamlanmamış Çıktıları Kaldır" +msgstr "Eksik Çıktıları Kaldır" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Henüz tamamlanmamış tüm üretim çıktılarını sil" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "İzin verilmedi" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Bu üretim emri tarafından tüketildi olarak kabul et" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Bu üretim emrini tamamlamadan önce tahsisi kaldır" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Aşırı Tahsis Edilmiş Stok" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Üretim emrine atanan ek stok kalemlerini nasıl işlemek istersiniz" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Bazı stok kalemleri aşırı tahsis edilmiştir" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Tahsis Edilmeyeni Kabul Et" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Stok kalemlerinin bu üretim emrine tamamen tahsis edilmediğini kabul et" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Gerekli stok tamamen tahsis edilemedi" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" -msgstr "Tamamlanmamış Kabul et" +msgstr "Eksik Kabul et" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Gereken miktarda üretim çıktısının tamamlanmadığını kabul et" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Gereken üretim miktarı tamamlanmadı" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Üretim emrinin açık alt üretim emirleri var" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Üretim emri üretim durumunda olmalıdır" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Üretim emrinde eksik çıktılar var" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Üretim Satırı" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Üretim çıktısı" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Üretim çıktısı aynı üretimi göstermelidir" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Üretim Satırı" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part üretim emri ile aynı parçayı göstermelidir" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Kalem stokta olmalıdır" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Mevcut miktar ({q}) aşıldı" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "İzlenen parçaların tahsisi için üretim çıktısı belirtilmelidir" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "İzlenmeyen parçaların tahsisi için üretim çıktısı belirtilemez" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" -msgstr "Ayrılma ögeleri sağlanmalıdır" +msgstr "Tahsis ögeleri belirtilmelidir" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Parçaların alınacağı stok konumu (herhangi bir konumdan almak için boş bırakın)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Konumu Hariç Tut" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" -msgstr "Bu seçilen konumdan stok kalemlerini hariç tut" +msgstr "Stok kalemlerini bu seçili konumdan hariç tut" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Birbirinin Yerine Kullanılabilir Stok" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Birden fazla konumdaki stok kalemleri birbirinin yerine kullanılabilir" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" -msgstr "Yedek Stok" +msgstr "Muadil Stok" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" -msgstr "Yedek parçaların ayrılmasına izin ver" +msgstr "Muadil parçaların tahsis edilmesine izin ver" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "İsteğe Bağlı Ögeler" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "İsteğe bağlı BOM kalemlerini üretim emrine tahsis et" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "Tüm Ögeler" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "Takip edilmeyen kalemler" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "Takipli Kalemler" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "Kalem Türü" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" -msgstr "Otomatik tahsis edilecek ürün tipini seçin" +msgstr "Otomatik tahsis edilecek ürün türünü seçin" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "Stok Önceliği" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "Eşleşen stok kalemlerinin tüketilmesinde tercih edilen sıra" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "Üretim Satırları" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "Tahsisatı şu üretim satırlarına sınırla (tüm satırlara tahsis etmek için boş bırakın)" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "ML Referansı" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "BOM Parça ID" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "ML Parça Adı" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "Kur" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "Yap" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Tedarikçi Parçası" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Tahsis Edilen Miktar" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Üretim Referansı" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Parça Kategorisi Adı" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Takip Edilebilir" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Devralınmış" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Varyantlara İzin Ver" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "ML Ögesi" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "Üretimde" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "Üretim için Planlandı" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Harici Stok" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Mevcut Stok" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Mevcut Yedek Stok" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Mevcut Varyant Stok" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "Tüketilen miktar tahsis edilen miktarı aşıyor" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "Stok tüketimi için isteğe bağlı notlar" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "Üretim kalemi doğru üretim emrini göstermelidir" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "Üretim kalemi tahsisini yinele" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "Üretim satırı doğru üretim emrini göstermelidir" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "Üretim satırı tahsisini yinele" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "En az bir kalem veya satır sağlanmalıdır" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Bekliyor" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Üretim" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Beklemede" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "İptal edildi" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Tamamlandı" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "{build} üretim emri tamamlandı" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Bir üretim emri tamamlandı" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Üretim emri için gereken stok" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "Üretim emri {build} ek stok gerektiriyor" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Geciken Üretim Emri" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "{bo} üretim emri şimdi gecikti" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "Küçük Resim Var" + +#: common/api.py:773 msgid "Is Link" msgstr "Link Olanlar" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "Dosya Olanlar" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Kullanıcının bu ekleri silmek için izni yok" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" -msgstr "" +msgstr "Kullanıcının bu eki düzenleme izni yok" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Kullanıcının bu eki silmek için izni yok" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "Seçim listesi kilitli" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Geçersiz para birimi kodu" @@ -1539,15 +1641,20 @@ msgstr "Geçerli bir para birimi kodu sağlanmamış" msgid "No plugin" msgstr "Eklenti yok" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "Etiketler" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Proje Kodu Etiketi" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Güncellendi" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Son güncellemenin zaman damgası" @@ -1567,794 +1674,844 @@ msgstr "Eşsiz proje kodu" msgid "Project description" msgstr "Proje açıklaması" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Bu projeden sorumlu kullanıcı veya grup" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "Ayarlar anahtarı" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Ayarlar değeri" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Seçilen değer geçerli bir seçenek değil" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Değer bir boolean değer olmalıdır" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Değer bir integer değer olmalıdır" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "Değer geçerli bir sayı olmalıdır" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "Değer doğrulama kontrollerini geçemiyor" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Anahtar dizesi benzersiz olmalı" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Kullanıcı" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Fiyat kademesi miktarı" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Fiyat" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Belirtilen miktardaki birim fiyat" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Bitiş Noktası" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Bu web kancasının alındığı uç nokta" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Bu web kancası için ad" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Aktif" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Bu projeden sorumlu kullanıcı veya grup" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "Ayarlar anahtarı" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Ayarlar değeri" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Seçilen değer geçerli bir seçenek değil" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Değer bir boolean değer olmalıdır" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Değer bir integer değer olmalıdır" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "Değer geçerli bir sayı olmalıdır" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "Değer doğrulama kontrollerini geçemiyor" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Anahtar dizesi benzersiz olmalı" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Kullanıcı" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Fiyat kademesi miktarı" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Fiyat" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Belirtilen miktardaki birim fiyat" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Bitiş Noktası" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Bu web kancasının alındığı uç nokta" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Bu web kancası için ad" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Bu web kancası aktif mi" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Token" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Erişim için belirteç" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Gizli" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "HMAC için paylaşılan gizli bilgi" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Mesaj ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Bu mesaj için benzersiz tanımlayıcı" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Sağlayıcı" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Bu mesajın alındığı ana bilgisayar" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Başlık" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Bu mesajın başlığı" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Gövde" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Bu mesajın gövdesi" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Bu mesajın alındığı uç nokta" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Üzerinde çalışıldı" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Bu mesajdaki iş bitirildi mi?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Kimlik" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Başlık" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Bağlantı" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Yayınlandı" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Yazar" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Özet" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Oku" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Haberi okudunuz mu?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Görsel dosyası" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "Bu görsel için hedef model türü" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "Bu görsel için hedef model ID" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "Özel Birim" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "Birim simgesi benzersiz olmalıdır" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Birim adı geçerli bir tanımlayıcı olmalıdır" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Birim adı" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Sembol" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "İsteğe bağlı birim simgesi" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Tanımlama" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Birim tanımlaması" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Ek" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Eksik dosya" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Bozuk dış bağlantı" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" -msgstr "" +msgstr "Yeniden adlandırmak için dosya eklenmemiş" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" -msgstr "" +msgstr "Dosya adı boş olamaz" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" -msgstr "" +msgstr "Geçersiz dosya adı" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" -msgstr "" +msgstr "Dosya uzantısı değiştirilemiyor" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" -msgstr "" +msgstr "Bu adda bir dosya zaten var" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" -msgstr "" +msgstr "Yeniden adlandırılan dosyayı kaydetme başarısız oldu" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "Model türü" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "Görsel için hedef model türü" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Eklenecek dosyayı seç" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "Küçük görsel" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "Bu ek için küçük görsel" + +#: common/models.py:2155 msgid "Comment" msgstr "Yorum" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "Ek yorumu" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Yükleme tarihi" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Dosyanın yüklendiği tarih" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "Görsel mi" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "Bu ek geçerli bir görsel dosyası ise true" + +#: common/models.py:2183 msgid "File size" msgstr "Dosya Boyutu" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "Bayt cinsinden dosya boyutu" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "Ek için belirtilen model türü geçersiz" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "Özel Durum" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "Özel Durumlar" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "Referans Durum Seti" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "Bu özel durum ile genişletilen durum seti" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "Mantıksal anahtar" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "İş mantığında bu özel duruma eşit olan durum mantıksal anahtarı" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Değer" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "Modeller veritabanına kaydedilecek sayısal değer" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "Durumun adı" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Etiket" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "Ön yüzde gösterilecek etiket" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Renk" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "Ön yüzde gösterilecek renk" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Model" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "Bu durumun ilişkilendirildiği model" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "Model seçilmelidir" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "Anahtar Seçilmelidir" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "Mantıksal anahtar seçilmelidir" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "Anahtar, mantık anahtarından farklı olmalıdır" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "Geçerli bir referans durum sınıfı sağlanmalıdır" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "Anahtar, referans durumunun mantık anahtarlarından farklı olmalıdır" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" -msgstr "Mantık anahtarı, referans durumunun mantık anahtarları içinde olmalıdır" +msgstr "Mantıksal anahtar, referans durumunun mantıksal anahtarları içinde olmalıdır" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "İsim, referans durumunun isimlerinden farklı olmalıdır" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Seçim Listesi" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "Seçim Listeleri" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "Seçim listesinin adı" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "Seçim listesinin açıklaması" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Kilitli" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "Bu seçim listesi kilitli mi?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "Bu seçim listesi kullanılabilir mi?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "Kaynak Eklentisi" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "Seçim listesini sağlayan eklenti" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "Kaynak Dize" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "Bu liste için kullanılan kaynağı belirten isteğe bağlı dize" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "Varsayılan Girdi" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "Bu seçim listesi için varsayılan girdi" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Oluşturuldu" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "Seçim listesinin oluşturulduğu tarih ve saat" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Son Güncelleme" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "Seçim listesinin son güncellendiği tarih ve saat" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "Seçim Listesi Girdisi" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "Seçim Listesi Girişleri" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "Bu girdinin ait olduğu seçim listesi" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "Seçim listesi girdisinin değeri" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "Seçim listesi girdisi için etiket" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "Seçim listesi girdisinin açıklaması" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "Bu seçim listesi girdisi aktif mi?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Parametre Şablonu" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "Parametre Şablonları" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Onay kutusu parametrelerinin birimleri olamaz" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Onay kutusu parametrelerinin seçenekleri olamaz" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Seçenekler eşsiz olmalıdır" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Parametre şablon adı benzersiz olmalıdır" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "Bu parametre şablonu için hedef modeli türü" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Parametre Adı" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Birim" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Bu parametre için fiziksel birimler" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Parametre açıklaması" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Onay kutusu" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Bu parametre bir onay kutusu mu?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Seçenekler" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Bu parametre için geçerli seçenekler (virgül ile ayrılmış)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "Bu parametre için seçim listesi" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Etkin" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "Bu parametre şablonu etkin mi?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "Parametre" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "Parametreler" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Parametre değeri için geçersiz seçim" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "Parametre için belirtilen model türü geçersiz" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "Model ID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "Bu parametre için hedef modelin ID'si" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Şablon" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "Parametre şablonu" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Veri" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Parametre Değeri" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Not" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "İsteğe bağlı not alanı" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "Barkod Taraması" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "Barkod verisi" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "Barkodu taratan kullanıcı" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "Zaman damgası" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "Barkod taramasının tarihi ve saati" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "Barkodu işleyen URL uç noktası" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Bağlam" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "Barkod taraması için bağlam verisi" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "Yanıt" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "Barkod taramasından gelen yanıt verisi" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Sonuç" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "Barkod taraması başarılı mıydı?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "Bir hata oluştu" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "NVE-ER: E-posta günlüğünün silinmesi korumalı. Silmeye izin vermek için INVENTREE_PROTECT_EMAIL_LOG ayarını False olarak ayarlayın." -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "E-posta İletisi" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "E-posta İletileri" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "Duyuruldu" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "Gönderildi" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "Başarısız" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "Teslim edildi" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "Onaylandı" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "Gelen" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "Giden" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "Yanıt Yok" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "Teslimat Takibi" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "Okumayı Takip Et" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "Tıklamayı Takip Et" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "Global ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "Bu ileti için tanımlayıcı (harici sistem tarafından sağlanabilir)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "Konu Kimliği" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "Bu ileti konusu için tanımlayıcı (harici sistem tarafından sağlanabilir)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "Konu" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "Bu mesaja bağlı konu" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "Öncelik" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "E-Posta Konusu" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "E-posta Konuları" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Anahtar" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "Bu konu için benzersiz anahtar (konuyu tanımlamak için kullanılır)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "Bu konu için benzersiz tanımlayıcı" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "Dahili Olarak Başlatıldı" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "Bu konu dahili olarak mı başlatıldı?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "Konunun oluşturulduğu tarih ve saat" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "Konunun son güncellendiği tarih ve saat" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} iptal edildi" msgid "A order that is assigned to you was canceled" msgstr "Size atanmış bir emir iptal edildi" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Teslim Alınan Kalemler" @@ -2388,104 +2545,100 @@ msgstr "Kalemler, bir satın alma siparişine istinaden teslim alındı" msgid "Items have been received against a return order" msgstr "Kalemler, bir iade siparişine istinaden teslim alındı" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "Bu ayarın değiştirilmesi için onay gerekip gerekmediğini gösterir" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "Bu ayar değiştirilmeden önce onay gerektirir. Lütfen değişikliği onaylayın." -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "Ayarın bir ortam değişkeni tarafından üstüne yazılıp yazılmadığını belirtir" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "Üstüne Yaz" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Çalışıyor" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Bekleyen Görevler" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Planlanan Görevler" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Başarısız Görevler" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "Görev ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "Benzersiz Görev ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Kilit" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Kilit Zamanı" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Görev Adı" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Fonksiyon" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Fonksiyon Adı" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Argümanlar" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Görev Argümanları" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Anahtar Argümanlar" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Anahtar görev argümanları" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Dosya adı" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" -msgstr "Model Tipi" +msgstr "Model Türü" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "Kullanıcının bu model için ek oluşturma veya düzenleme izni yok" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "Kullanıcı bu model için parametre oluşturma veya düzenleme iznine sahip değil" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "Seçim listesi kilitli" - #: common/setting/system.py:97 msgid "No group" msgstr "Grup yok" @@ -2500,15 +2653,15 @@ msgstr "Yeniden başlatma gerekli" #: common/setting/system.py:188 msgid "A setting has been changed which requires a server restart" -msgstr "Sunucunun yeniden başlatılmasını gerektiren bir ayar değişti" +msgstr "Sunucunun yeniden başlatılmasını gerektiren bir ayar değiştirildi" #: common/setting/system.py:194 msgid "Pending migrations" -msgstr "Bekleyen taşıma işlemleri" +msgstr "Bekleyen geçişler" #: common/setting/system.py:195 msgid "Number of pending database migrations" -msgstr "Bekleyen veritabanı taşıma sayısı" +msgstr "Bekleyen veritabanı geçişlerinin sayısı" #: common/setting/system.py:200 msgid "Active warning codes" @@ -2560,19 +2713,19 @@ msgstr "`Hakkında` kipini yalnızca süper kullanıcılara göster" #: common/setting/system.py:239 msgid "Show superuser banner" -msgstr "" +msgstr "Süper kullanıcı afişini göster" #: common/setting/system.py:240 msgid "Show a warning banner in the UI when logged in as superuser" -msgstr "" +msgstr "Süper kullanıcı olarak oturum açınca arayüzde bir uyarı afişi göster" #: common/setting/system.py:245 msgid "Show admin banner" -msgstr "" +msgstr "Yönetici afişi göster" #: common/setting/system.py:246 msgid "Show a warning banner in the UI when logged in as admin" -msgstr "" +msgstr "Yönetici olarak oturum açınca arayüzde bir uyarı afişi göster" #: common/setting/system.py:251 company/models.py:147 company/models.py:148 msgid "Company name" @@ -2614,13 +2767,13 @@ msgstr "Para Birimi Güncelleme Aralığı" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Döviz kurlarını şu sıklıkla güncelle (etkisizleştirmek için sıfır yapın)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "günler" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Kullanılacak para birimi güncelleme eklentisi" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "Yükleme Boyutu Sınırı" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "Görseller ve dosyalar için maksimum izin verilebilir yükleme boyutu" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "Sıkı URL Doğrulama" @@ -2760,947 +2921,1017 @@ msgstr "Barkod Üreteci Eklentisi" msgid "Plugin to use for internal barcode data generation" msgstr "Dahili barkod üretimi için kullanılacak eklenti" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "Parça Kilitleme" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "Değişiklikleri önlemek için parçaları kilitlemeyi etkinleştir" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "Parça Revizyonları" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "Parça için revizyon alanını etkinleştir" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "Yalnızca Montaj Revizyonu" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "Yalnızca montaj parçaları için revizyona izin ver" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "Montajdan Silmeye İzin Ver" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "Bir montajda kullanılan parçaları silmeye izin ver" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "DPN Regex" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Parça DPN eşleştirmesi için Düzenli İfade Kalıbı (Regex)" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Yinelenen DPN'ye İzin Ver" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Birden çok parçanın aynı DPN'yi paylaşmasına izin ver" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "DPN Düzenlemeye İzin Ver" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Parçayı düzenlerken DPN değiştirmeye izin ver" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Parça ML Verisini Kopyala" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Bir parçayo çoğaltırken varsayılan olarak ML verisini kopyala" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Parça Parametre Verisini Kopyala" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Bir parçayı çoğaltırken varsayılan olarak parametre verisini kopyala" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Parça Test Verisini Kopyala" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Bir parçayı çoğaltırken varsayılan olarak test verisini kopyala" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Kategori Paremetre Sablonu Kopyala" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Parça oluştururken kategori parametre şablonlarını kopyala" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Parçaları varsayılan olan şablondur" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Parçalar varsayılan olarak başka bileşenlerden monte edilebilir" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Bileşen" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Parçalar varsayılan olarak alt bileşen olarak kullanılabilir" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Satın Alınabilir" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Parçalar varsayılan olarak satın alınabilir" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Satılabilir" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Parçalar varsayılan olarak satılabilir" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Parçalar varsayılan olarak takip edilebilir" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Sanal" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Parçalar varsayılan olarak sanaldır" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "İlgili parçaları göster" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Bir parça için ilgili parçaları görüntüle" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Başlangıç Stok Verisi" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Yeni bir parça eklerken başlangıç stoku oluşturmaya izin ver" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "İlk Tedarikçi Bilgileri" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Yeni bir parça eklerken ilk tedarikçi bilgilerinin oluşturulmasına izin ver" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Parça Adı Görüntüleme Biçimi" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Parça adını görüntüleme biçimi" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Parça Kategorisi Varsayılan Simgesi" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Parça kategorisi için varsayılan simge (boş bırakılırsa simge kullanılmaz)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Minimum Fiyatlandırma Ondalık Basamakları" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Fiyat verilerinde görüntülenecek maksimum ondalık hane sayısı" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Maksimum Fiyatlandırma Ondalık Basamakları" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Fiyat verilerinde görüntülenecek maksimum ondalık hane sayısı" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Tedarikçi Fiyatlandırmasını Kullan" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Tedarikçi fiyat kademelerini genel fiyat hesaplamalarına dahil et" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Satın Alma Geçmişini Geçersiz Kılma" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Tarihsel satın alma siparişi fiyatlandırması, tedarikçi fiyat kademelerini geçersiz kılar" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Stok Kalemi Fiyatlandırmasını Kullan" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Fiyatlandırma hesaplamaları için elle girilen stok verisinin fiyatlandırmasını kullan" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Stok Kalemi Fiyatlandırma Süresi" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Bu gün sayısından daha eski olan stok kalemlerini fiyatlandırma hesaplamalarından hariç tut" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Varyant Fiyatlandırması Kullan" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Genel fiyat hesaplamalarına varyant fiyatlarını dahil et" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Yalnızca Aktif Varyantlar" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Varyant fiyatlandırmasını hesaplamak için yalnızca aktif varyant parçaları kullan" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "Fiyatlandırmayı Otomatik Güncelle" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "Dahili veri değişince parça fiyatını otomatik güncelle" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Fiyatlandırmayı Yeniden Oluşturma Aralığı" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Parça fiyatlandrımasının otomatik güncellenmesinden önceki gün sayısı" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Dahili Fiyatlar" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Parçalar için dahili fiyatları etkinleştir" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Dahili Fiyat Geçersiz Kılma" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Varsa, dahili fiyatlar fiyat aralığı hesaplarını geçersiz kılar" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "Malzeme listesinde sıfır miktara izin ver" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "Malzeme listesinde bir ürün için sıfır miktarın kabul edilmesini sağlar. Böylece üretim miktarından bağımsız olarak, her üretim için gerekli miktarı belirlemek amacıyla kurulum miktarı kullanılabilir" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Etiket yazdırmayı etkinleştir" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Web arayüzünden etiket yazdırmayı etkinleştir" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "Etiket Görseli DPI Değeri" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Görsel dosyaları üretirken etiket yazdırma eklentilerine sağlanacak DPI çözünürlüğü" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Raporları Etkinleştir" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Rapor üretimini etkinleştir" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Hata Ayıklama Modu" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Raporları hata ayıklama modunda oluştur (HTML çıktısı)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "Rapor URL Alma" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "Rapor oluştururken uzak URL'lerin alınmasına izin ver" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "Rapor Hatalarını Günlüğe Kaydet" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "Raporlar üretirken oluşan hataları günlüğe kaydet" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Sayfa Boyutu" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "PDF raporlar için varsayılan sayfa boyutu" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Parametre Birimlerini Zorunlu Kıl" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Birimler sağlanırsa, parametre değerleri belirtilen birimlere uymalıdır" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Küresel Çapta Benzersiz Seri Numaraları" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Stok kalemleri için seri numaraları küresel çapta benzersiz olmalıdır" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Tükenen Stoku Sil" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "Bir stok kalemi tükendiğinde varsayılan davranışı belirler" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" -msgstr "" +msgstr "Seri Numarası Düzenlemeye İzin ver" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" -msgstr "" +msgstr "Stok kalemlerinin seri numarasını düzenlemeye izin ver" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" -msgstr "" +msgstr "Seri Numaralı Stokları Sil" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" -msgstr "" +msgstr "Seri numarasına sahip stok kalemlerinin silinmesine izin ver" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Parti Kodu Şablonu" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Stok kalemleri için varsayılan parti kodları oluşturma şablonu" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" -msgstr "Stok Sona Erme Tarihi" +msgstr "Stok Raf Ömrü" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" -msgstr "Stokun sona erme işlevselliğini etkinleştir" +msgstr "Stokun raf ömrü özelliğini etkinleştir" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Süresi Dolan Stoku Sat" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Süresi dolan stok satışına izin ver" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Stok Eskime Süresi" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Stok kalemlerinin son kullanma tarihinden önce eskimiş sayılacağı gün sayısı" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Süresi Dolmuş Stoktan Üretim" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Süresi dolmuş stok ile üretime izin ver" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Stok Sahipliği Kontrolü" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Stok konumu ve kalemleri üzerinde sahiplik kontrolünü etkinleştir" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Varsayılan Stok Konumu Simgesi" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Stok konumu için varsayılan simge (boşsa simge yok demektir)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Takılı Stok Kalemlerini Göster" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Stok tablolarında takılı stok kalemlerini görüntüle" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" -msgstr "Kalemlerin kurulumunu yaparken BOM'u kontrol et" +msgstr "Ögeleri takarken BOM'u kontrol et" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "Takılı stok kalemleri üst parçanın BOM listesinde mevcut olmalıdır" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "Stok Dışı Aktarıma İzin Ver" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "Stokta olmayan kalemlerin stok konumları arasında aktarılmasına izin ver" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Üretim Emri Referans Şablonu" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Üretim emri referans alanını üretmek için gerekli şablon" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "Sorumlu Sahip Gerektir" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "Her siparişe sorumlu bir yetkili atanmalıdır." -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "Aktif Parça Gerektirir" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "Pasif parçalarla üretim emri oluşturmayı engelle" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "Kilitli Parça Gerekli" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "Kilidi açılmış parçalarla üretim emri oluşturmayı engelle" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "Geçerli BOM gereklidir." -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "BOM henüz doğrulanmadan üretim emri oluşturmayı engelle" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "Kapalı Alt Siparişler Gerekli" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "Tüm alt emirler kapatılana kadar üretim emrini tamamlamayı engelle" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "Harici Üretim Emirleri" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "Harici üretim emri işlevselliğini etkinleştir" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" -msgstr "" +msgstr "Harici Üretim Emirlerini Gerekli Kıl" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" -msgstr "" +msgstr "Harici bir tedarikçiden montajlı parçalar sipariş ederken harici bir üretim emri gerekli kıl" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "Testler Geçene Kadar Engelle" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "Tüm gerekli testler geçene kadar üretim çıktılarını tamamlamayı engelle" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "İade Siparişlerini Etkinleştir" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Kullanıcı arayüzünde iade siparişi işlevselliğini etkinleştir" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Kullanıcı arayüzünde iade siparişi işlevselliğini etkinleştirin." -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "İade Sipariş referans alanı oluşturmak için gerekli desen" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Tamamlanan İade Siparişlerini Düzenle" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Tamamlandıktan sonra iade siparişlerini düzenlemeye izin ver" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Satış Siparişi Referans Şablonu" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Satış Siparişi referans alanını üretmek için gerekli şablon" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Satış Siparişi Varsayılan Gönderi" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Satış siparişleriyle varsayılan gönderi oluşturmayı etkinleştir" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Tamamlanmış Satış Siparişlerini Düzenle" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Gönderilen veya tamamlanan satış siparişlerini düzenlemeye izin ver" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "Kontrol Gerektiren Gönderi" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "Kalemler kontrol edilene dek gönderilerin tamamlanmasını engelle" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "Gönderilen Siparişleri Tamamlandı Olarak İmle" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "Gönderildi olarak işaretli satış siparişleri \"gönderildi\" durumu atlanarak otomatik olarak tamamlanacaktır" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "Aktarım Emirlerini Etkinleştir" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "Kullanıcı arayüzünde aktarım emri işlevselliğini etkinleştir" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "Aktarım Emri Referans Deseni" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "Aktarım emri referans alanını üretmek için gereken desen" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" -msgstr "" +msgstr "Eksik Ürün Testlerini Engelle" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" -msgstr "" +msgstr "Gerekli ürün testleri eksik ise, stok kalemlerinin satış siparişlerine tahsis edilmesini engelle" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Satın Alma Siparişi Referans Şablonu" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Satın Alma Siparişi referans alanını üretmek için gerekli şablon" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Tamamlanan Satın Alma Siparişlerini Düzenle" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Gönderildikten veya tamamlandıktan sonra satın alma siparişlerini düzenlemeye izin ver" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "Para Birimini Dönüştür" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "Stok alınırken kalem değerini temel para birimine dönüştür" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Satın Alma Siparişlerini Otomatik Tamamla" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "Tüm satırlar alındığında satın alma siparişini otomatikmen tamamlandı olarak işaretle" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "Şifremi unuttum seçeneğini etkinleştir" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" -msgstr "Giriş yapma sayfasında şifremi unuttum işlevini etkinleştir" +msgstr "Oturum açma sayfasında şifremi unuttum özelliğini etkinleştir" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "Kayıt olmayı etkinleştir" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" -msgstr "Giriş yapma sayfalarında kullanıcılar için kendini kaydetme işlevini etkinleştir" +msgstr "Oturum açma sayfalarında kullanıcılar için kendini kaydetme özelliğini etkinleştir" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "SSO Etkinleştir" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" -msgstr "Kullanıcı girişi sayfalarında SSO etkinleştir" +msgstr "Oturum açma sayfalarında SSO etkinleştir" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "SSO ile kayıt olmayı etkinleştir" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Giriş yapma sayfalarında kullanıcılar için SSO ile kendini kaydetmeyi etkinleştir" +msgstr "Oturum açma sayfalarında kullanıcılar için SSO ile kendini kaydetmeyi etkinleştir" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "SSO grup eşitlemeyi etkinleştir" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "InvenTree gruplarını IdP tarafından sağlanan gruplar ile eşitlemeyi etkinleştir" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSO grup anahtarı" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "IdP tarafından sağlanan talep özniteliğinin adı" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "SSO grup haritası" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "SSO gruplarından yerel InvenTree gruplarına bir eşleme. Yerel grup yoksa, oluşturulacaktır." -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "SSO dışındaki grupları kaldır" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "IdP arka ucu tarafından olmayan, kullanıcıya atanmış grupların kaldırılıp kaldırılmayacağı. Bu ayarı etkisizleştirmek güvenlik sorunlarına neden olabilir" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "E-posta Gerekir" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Üyelik sırasında kullanıcının eposta sağlamasını gerektir" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "SSO kullanıcıları otomatik doldur" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Kullanıcı ayrıntılarını TOA hesabı verisinden otomatik olarak doldur" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Postayı iki kez gir" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Hesap oluştururken kullanıcıların postalarını iki kez girmelerini iste" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Şifreyi iki kez gir" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Hesap oluştururken kullanıcıların şifrelerini iki kez girmesini iste" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Alanlara izin ver" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Belirli alanlara hesap açmayı kısıtla (virgülle ayrılmış, @ ile başlayan)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Hesap oluştururken grup" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "Yeni kullanıcıların kayıt sırasında atanacağı grup. Eğer TOA grup eşitlemesi etkinse, yalnızca ıdP'den hiçbir grup atanamazsa bu grup ayarlanır." -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "ÇFKD'yi Zorunlu Kıl" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Kullanıcıların çok faktörlü kimlik doğrulamasını kullanması gerekmektedir." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "Bu ayarı etkinleştirmek, tüm kullanıcıların çok faktörlü kimlik doğrulamayı ayarlamasını gerektirecektir. Tüm oturumlar hemen kapatılacaktır." -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Başlangıçta eklentileri kontrol et" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Başlangıçta tüm eklentilerin kurulmuş olduğunu kontrol et - konteyner ortamlarında etkinleştir" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Eklenti güncellemelerini kontrol et" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "Kurulu eklentiler için periyodik güncelleme kontrolünü etkinleştir" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "URL entegrasyonunu etkinleştir" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "URL yönlendirmesi eklemek için eklentileri etkinleştir" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Gezinti entegrasyonunu etkinleştir" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Eklentilerin gezintiye entegre edilmesini etkinleştir" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Uygulama entegrasyonunu etkinleştir" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Uygulamalar eklemek için eklentileri etkinleştir" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Zamanlama entegrasyonunu etkinleştir" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Zamanlanmış görevleri çalıştırmak için eklentileri etkinleştir" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Olay entegrasyonunu etkinleştir" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Eklentilerin olaylara yanıt verebilmesini etkinleştirin" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "Arayüz entegrasyonunu etkinleştir" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "Eklentilerin kullanıcı arayüzüne entegre olmasını etkinleştir" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "Posta entegrasyonunu etkinleştir" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "Eklentilerin giden/gelen postaları işlemesini etkinleştir" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "Proje kodlarını etkinleştir" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" -msgstr "Projeleri izlemek için proje kodlarını etkinleştir" +msgstr "Projeleri takip etmek için proje kodlarını etkinleştir" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "Stok Sayımını Etkinleştir" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "Geçmiş stok seviyelerini ve değerini kaydetme işlevini etkinleştir" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Harici Konumları Hariç Tut" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "Harici konumlardaki stok kalemlerini stok geçmişi hesaplamalarının dışında tut" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Otomatik Stok Sayımı Periyodu" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "Otomatik stok geçmişi kaydı arasındaki gün sayısı" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "Eski Stok Geçmişi Girdilerini Sil" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "Belirtilen gün sayısından daha eski stok geçmişi girdilerini sil" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "Stok Geçmişi Silme Aralığı" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "Stok geçmişi girdileri belirtilen gün sayısı sonrasında silinecektir" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" -msgstr "Eski Stok Geçmişi Girdilerini Sil" +msgstr "Eski Stok Takip Kayıtlarını Sil" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" -msgstr "Belirtilen gün sayısından daha eski stok geçmişi girdilerini sil" +msgstr "Belirtilen gün sayısından daha eski stok takip kayıtlarını sil" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "Stok Geçmişi Silme Aralığı" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" -msgstr "Stok geçmişi girdileri belirtilen gün sayısı sonrasında silinecektir" +msgstr "Stok takip kayıtları belirtilen gün sayısı sonrasında silinecektir" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Kullancıların tam isimlerini görüntüle" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Kullanıcı adı yerine kullanıcıların tam adlarını görüntüle" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "Kullanıcı Profillerini Göster" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "Kullanıcıların Profillerini kendi profil sayfalarında göster" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" -msgstr "" +msgstr "Haftanın başladığı gün" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" -msgstr "" +msgstr "Takvimlerde görüntülemek için haftanın başlangıç günü" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" -msgstr "" +msgstr "Pazar" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" -msgstr "" +msgstr "Pazartesi" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" -msgstr "" +msgstr "Salı" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" -msgstr "" +msgstr "Çarşamba" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" -msgstr "" +msgstr "Perşembe" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" -msgstr "" +msgstr "Cuma" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" -msgstr "" +msgstr "Cumartesi" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "Takvim Ufku" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "Takvim görünümlerinde görüntülenecek gelecek ayların sayısı" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "aylar" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "Test İstasyon Verisini Etkinleştir" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "Test sonuçları için test istasyonundan veri toplamayı etkinleştir" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "Makine Pingini Etkinleştir" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "Durumlarını kontrol etmek için kayıtlı makinelerin periyodik ping görevini etkinleştir" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Arama önizleme penceresinin her bir bölümünde gösterilecek sonuç sayısı" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Regex Arama" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Arama sorgularında düzenli ifadeleri etkinleştir" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Tam Kelime Arama" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Arama sorguları, tam kelime eşleşmeleri için sonuçlar döndürür" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "Notları Ara" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "Arama sorguları, nesnenin notlarındaki eşleşmelere ilişkin sonuçları verir" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Esc Tuşu Formları Kapatır" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Açılır formları kapatmak için ESC tuşunu kullanın" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Navigasyon Çubuğunu Sabitle" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Gezinti çubuğu konumu ekranın üstüne sabitlenir" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "Sabit Tablo Başlıkları" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "Tablo başlıkları tablonun üstüne sabitlenir" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "Hızlı Aramayı Göster" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "Hızlı arama gezinti işlevselliğini etkinleştir" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "Gezinti Simgeleri" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "Gezinti çubuğunda simgeleri göster" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Tarih Biçimi" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Tarihleri görüntülemek için tercih edilen biçim" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "Stok Geçmişini Göster" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "Parça ayrıntısı sayfasında stok geçmişi bilgisini görüntüle" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "Son Gezinti Yolunu Göster" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "Şimdiki sayfayı gezinti yollarında göster" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "Ek Model Bilgilerini Göster" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "Model seçim açılır menülerinde ek bilgileri göster" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "Tablolarda tam stok konumunu göster" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "Devre dışı: Tam konumun yolu fareyle üzerine gelindiğinde bir araç ipucu olarak görüntülenir. Etkin: Tam konumun yolu düz metin olarak görüntülenir." -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "Tablolarda tam parça kategorilerini göster" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "Devre dışı: Tam kategori yolu fareyle üzerine gelindiğinde bir araç ipucu olarak görüntülenir. Etkin: Tam kategori yolu düz metin olarak görüntülenir." -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" -msgstr "" +msgstr "BOM Tablosunda Alt Montajları Göster" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" -msgstr "" +msgstr "BOM tablosunda alt montajların görüntülenmesini etkinleştir" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Hata raporları alın" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Sistem hataları için bildirim alın" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "Son kullanılan yazdırma makineleri" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "Son kullanılan yazdırma makinelerini bir kullanıcı için kaydet" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" -msgstr "" +msgstr "En Son Seviyede Ögeleri Görüntüle" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" -msgstr "" +msgstr "Alt ögesi olmayan konumlar veya kategoriler için alt düzeyler yerine otomatik olarak ögeleri/parçaları göster" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "Tüm modeller" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "Ekli model türü sağlanamadı" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "Geçersiz ek modeli türü" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "Dosya boyutu {max_size} MB maksimum yükleme sınırını aşmaktadır" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "Geçersiz dosya adı" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "Minimum yer sayısı maksimum yer sayısından fazla olamaz" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "Maksimum yer sayısı minimum yer sayısından az olamaz" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Boş bir alan adına izin verilmez." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Geçersiz alan adı: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "Değer büyük harf olmalıdır" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "Değer geçerli bir değişken tanımlayıcısı olmalıdır" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Parça Aktif" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "Üretici Aktif" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Tedarikçi Parçası Aktif" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "Ana Tedarikçi Parçası" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Dahili Parça Aktif" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "Tedarikçi Aktif" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Üretici" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Şirket" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "Stoku Var" @@ -4123,8 +4387,8 @@ msgstr "İletişim telefon numarası" msgid "Contact email address" msgstr "İletişim e-posta adresi" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "İletişim" @@ -4176,283 +4440,283 @@ msgstr "Vergi Numarası" msgid "Company Tax ID" msgstr "Şirket Vergi Numarası" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Adres" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Adres" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Şirket Seç" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Adres Adı" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Adres girdisini açıklayan başlık" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Birincil Adres" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Birincil adres olarak ayarla" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "1. Satır" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "1. Adres Satırı" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "2. Satır" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "2. Adres Satırı" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Posta Kodu" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Şehir/Bölge" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Posta kodu şehir/bölge" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Eyalet/İlçe" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Eyalet veya ilçe" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Ülke" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Adres ülkesi" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Sevkiyat taşıyıcısı için notlar" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Sevkiyat taşıyıcısı için notlar" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Dahili sevkiyet notları" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Dahili kullanım için sevkiyat notları" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Adres bilgisine bağlantı (harici)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Üretici Parçası" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Temel Parça" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Parça seçin" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Üretici seçin" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "ÜPN" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Üretici Parça Numarası" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "Harici üretici bağlantısı için URL" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Parça üreticisi açıklaması" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Paket birimleri, temel parça birimleriyle uyumlu olmalıdır" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Paket birimleri sıfırdan büyük olmalıdır" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Bağlantılı üretici parçası aynı temel parçayı referans almalıdır" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Tedarikçi" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Tedarikçi seçin" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Tedarikçi stok kodu" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "Bu tedarikçi parçası aktif mi?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "Ana" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "Bu, bağlı parça için birincil tedarikçi ürünü mü?" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Parça üreticisi seç" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "Harici tedarikçi parçası bağlantısı için URL" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Tedarikçi parçası açıklaması" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "temel maliyet" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Minimum ücret (örneğin stoklama ücreti)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Paketleme" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Parça paketleme" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Paket Miktarı" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Tek bir pakette tedarik edilen toplam miktar. Tekli ürünler için boş bırakın." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "çoklu" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Birden fazla sipariş ver" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Tedarikçiden temin edilebilir miktar" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Temin Edilebilir Miktar Güncellendi" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Temin edilebilirlik verisinin güncellendiği son tarih" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "Tedarikçi Fiyat Kademesi" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Bu tedarikçi için kullanılan varsayılan para birimi" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "Şirket Adı" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Stokta" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "Fiyat Kademeleri" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" -msgstr "" +msgstr "Güzel Ad" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "Veri dışa aktarma sırasında hata oluştu" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "Veri dışa aktarma eklentisi yanlış veri biçimi döndürdü" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "Dışa Aktarma Biçimi" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "Çıktı dosyası biçimi seçin" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "Dışa Aktarma Eklentisi" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "Dışa aktarma eklentisi seçin" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "Bu kalem için ek durum bilgisi" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "Özel durum anahtarı" @@ -4476,123 +4740,152 @@ msgstr "Sipariş verildi" msgid "Invalid status code" msgstr "Geçersiz durum kodu" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Veri Dosyası" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "İçe aktarılacak veri dosyası" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "Sütunlar" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "Bu içe aktarma oturumu için hedef model türü" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "İçe aktarma durumu" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "Alan Varsayılanları" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "Alan Geçersiz Kılmaları" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "Alan Filtreleri" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "Mevcut Kayıtları Güncelle" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "Etkinleştirilirse, mevcut kayıtlar yeni veri ile güncellenecektir" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "Bazı zorunlu alanlar eşleştirilmemiştir" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "Tamamlanan Satır Sayısı Geçmişi" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "Satır Sayısı Geçmişi" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "Kayıt için mevcut veritabanı tanımlayıcısı" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "Sütun zaten bir veritabanı alanına eşlenmiştir" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "Alan zaten bir veri sütununa eşlenmiştir" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "Sütun eşlemesi geçerli bir içe aktarma oturumuna bağlanmalıdır" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "Sütun veri dosyasında bulunmuyor" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "Alan hedef modelde bulunmuyor" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" -msgstr "Seçilen alan salt okunurdur" +msgstr "Seçili alan salt okunurdur" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "Arama alanı yalnızca ilişkili (yabancı anahtar) alanlar için ayarlanabilir" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "Geçersiz arama alanı. Geçerli seçenekler şunlardır: {options}" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "Oturumu İçe Aktar" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "Alan" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "Sütun" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "Arama Alanı" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "Yabancı anahtar araması için kullanılacak veritabanı alanı. Otomatik arama için boş bırakın." + +#: importer/models.py:674 msgid "Row Index" msgstr "Satır İndeksi" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "Orijinal satır verisi" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "Hatalar" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Geçerli" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "Mevcut kayıtları güncellemek için ID gereklidir." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "Değer için birden fazla eşleşme bulundu – lütfen değerin benzersiz olduğundan emin olun veya belirli bir arama alanı seçin" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "Sağlanan ID ile kayıt bulunamadı" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "Sağlanan ID biçimi geçersiz" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "Mevcut kayıtları güncellemek için ID gereklidir." + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "Desteklenmeyen veri dosyası biçimi" @@ -4600,43 +4893,47 @@ msgstr "Desteklenmeyen veri dosyası biçimi" msgid "Failed to open data file" msgstr "Veri dosyasını açılamadı" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "Geçersiz veri dosyası boyutları" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "Geçersiz alan varsayılanları" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "Geçersiz alan geçersiz kılmaları" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "Geçersiz alan filtreleri" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "Satırlar" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "Kabul edilecek satır ID'leri" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "Hiç satır sağlanmadı" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "Satır bu oturuma ait değil" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "Satır geçersiz veri içeriyor" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "Satır zaten tamamlandı" @@ -4672,115 +4969,115 @@ msgstr "Veri dosyası çok fazla sütun içeriyor" msgid "Data file contains too many rows" msgstr "Veri dosyası çok fazla satır içeriyor" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "Değer geçerli bir sözlük nesnesi olmalıdır" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "Kopyalar" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "Her etiket için yazdırılacak kopya sayısı" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "Bağlı" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Bilinmeyen" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "Yazdırılıyor" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "Uyarı" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "Ortam yok" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "Kağıt sıkışması" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "Bağlı değil" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "Hata" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "Etiket Yazdırma" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "Çeşitli ürünler için etiketleri doğrudan yazdırın." -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "Yazıcı Konumu" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "Yazıcıyı belirli bir konuma ayarlayın" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "Makinenin adı" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "Makine Türü" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "Makinenin türü" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "Sürücü" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "Makine için kullanılan sürücü" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "Makineler devre dışı bırakılabilir" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "Sürücü mevcut" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "Hata yok" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "Başlatıldı" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "Makine durumu" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "Makine" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "Makine Yapılandırması" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "Yapılandırma türü" @@ -4792,7 +5089,7 @@ msgstr "Özelliğin anahtarı" msgid "Value of the property" msgstr "Özelliğin değeri" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Grup" @@ -4816,117 +5113,118 @@ msgstr "Maksimum İlerleme" msgid "Maximum value for progress type, required if type=progress" msgstr "İlerleme türünün maksimum değeri, tür=ilerleme ise gerekli" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Sipariş Referansı" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "Açık" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "Proje Kodu Var" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Oluşturan" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "Öncesinde Oluşturuldu" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "Sonrasında Oluşturuldu" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "Başlangıç Tarihi Var" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "Öncesi Başlangıç Tarihi" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "Sonrası Başlangıç Tarihi" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "Hedef Tarihi Var" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "Öncesi Hedef Tarih" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "Sonrası Hedef Tarih" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "Daha önce güncellendi" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "Güncellendi (den sonra)" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "Fiyatlandırılmış" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "Öncesinde Tamamlandı" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "Sonrasında Tamamlandı" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "Harici Üretim Emri" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Sipariş" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "Sipariş Tamamlandı" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Dahili Parça" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "Sipariş Bekliyor" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Tamamlandı" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "Sevkiyatı Var" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" -msgstr "" +msgstr "Sevkiyat bulunamadı" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Satın Alma Siparişi" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Satın Alma Siparişi" msgid "Sales Order" msgstr "Satış Siparişi" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "İade Siparişi" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "Aktarım Emri" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Toplam Fiyat" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Bu sipariş için toplam fiyat" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Sipariş Para Birimi" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Bu sipariş için para birimi (şirket varsayılanını kullanmak için boş bırakın)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "Bu sipariş kilitli olduğundan değiştirilemez" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" -msgstr "İletişim bilgileri seçilen şirketle eşleşmiyor" +msgstr "Kişi, seçili şirket ile eşleşmiyor" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "Başlangıç tarihi hedef tarihinden önce olmalıdır" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" -msgstr "Adres bilgileri seçilen şirketle eşleşmiyor" +msgstr "Adres, seçili şirket ile eşleşmiyor" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Açıklama (isteğe bağlı)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Bu sipariş için proje kodu seçin" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Harici sayfaya bağlantı" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "Başlangıç ​​tarihi" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "Bu üretim emri için planlanan başlangıç tarihi" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Hedeflenen tarih" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Sipariş teslimatı için beklenen tarih. Bu tarihten sonra sipariş gecikmeli olacaktır." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Düzenleme Tarihi" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Siparişin düzenlendiği tarih" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "Güncellenme Tarihi" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Bu siparişten sorumlu kullanıcı veya grup" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Bu sipariş için ilgili kişi" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Bu sipariş için şirket adresi" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Sipariş referansı" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Durum" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Satın alma siparişi durumu" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Ürünlerin sipariş edilmekte olduğu şirket" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Tedarikçi Referansı" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Tedarikçi siparişi referans kodu" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "teslim alan" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Siparişin tamamlandığı tarih" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Hedef" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "Teslim alınan kalemler için varış yeri" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Parça tedarikçisi PO tedarikçisi ile eşleşmelidir" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Satır, satın alma siparişi ile eşleşmiyor" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "Satırda bağlantılı bir parça eksik" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Miktar pozitif bir sayı olmalıdır" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" -msgstr "" +msgstr "Sanal parçalara seri numaraları atanamaz" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "Her türlü stoka izin ver (seri numaralı veya seri numarasız)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "Sadece seri numaralı stok" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "Sadece seri numarasız stok" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Müşteri" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Ürünlerin satılmakta olduğu şirket" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "Satış siparişi durumu" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Müşteri Referansı " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Müşteri siparişi referans kodu" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Sevkiyat Tarihi" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "tarafından sevk edildi" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Ürün kalemi bu siparişle ilişkilendirilmemiştir" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Şu seri numaraları için bir eşleşme bulunamadı" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "Şu seri numaraları mevcut değildir" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "Sipariş zaten tamamlandı" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "Sipariş zaten iptal edildi" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Yalnızca açık siparişler tamamlandı olarak işaretlenebilir" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" -msgstr "Tamamlanmamış sevkiyatlar olduğundan sipariş tamamlanamaz" +msgstr "Eksik sevkiyatlar olduğundan sipariş tamamlanamaz" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" -msgstr "Tamamlanmamış tahsisatlar olduğundan sipariş tamamlanamaz" +msgstr "Eksik tahsisler olduğu için sipariş tamamlanamıyor" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Tamamlanmamış satırlar olduğundan sipariş tamamlanamaz" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "Bu sipariş kilitli olduğundan değiştirilemez" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Kalem miktarı" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" -msgstr "" +msgstr "Satır Numarası" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" -msgstr "" +msgstr "Bu ögenin satır numarası (isteğe bağlı)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Satır referansı" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Satır notları" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Bu satır için hedef tarih (siparişin hedef tarihini kullanmak için boş bırakın)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Satır açıklaması (isteğe bağlı)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Bu satır için ek bağlam" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Birim Fiyat" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "Satın Alma Siparişi Kalemi" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Tedarikçi parçası tedarikçi ile eşleşmelidir" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "Üretim emri harici olarak işaretlenmelidir" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "Üretim emirleri yalnızca montaj parçalarına bağlanabilir" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "Üretim emri parçası satır parçası ile eşleşmelidir" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" -msgstr "" +msgstr "Montaj parçaları için harici bir üretim emri gereklidir" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Tedarikçi parçası" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Teslim Alındı" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Teslim alınan miktar" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Alış Fiyatı" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Birim alış fiyatı" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "Bu kalem tarafından karşılanacak harici Üretim Emri" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "Ek Sipariş Kalemi" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "Satış Siparişi Kalemi" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Yalnızca satışa uygun parçalar bir satış siparişine atanabilir" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Satış Fiyatı" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Birim satış fiyatı" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Sevk edildi" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Sevk edilen miktar" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "Satış Siparişi Sevkiyatı" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "Sevk adresi müşteri ile eşleşmelidir" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "Bu sevkiyatın sevk adresi" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Sevkiyat tarihi" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Teslimat Tarihi" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Sevkiyatın teslimat tarihi" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Kontrol Eden" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Bu sevkiyatı kontrol eden kullanıcılar" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Sevkiyat" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Sevkiyat numarası" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Takip Numarası" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Sevkiyat takip numarası" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Fatura Numarası" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Fatura referans numarası" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Sevkiyat zaten sevk edildi" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Sevkiyatın tahsis edilen stok kalemleri bulunmuyor" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "Sevkiyat tamamlanmadan önce kontrol edilmelidir" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "Ek Sipariş Kalemi" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "Satış Siparişi Tahsisatı" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Stok kalemi henüz atanmadı" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Farklı bir parçaya sahip satıra stok kalemi tahsis edilemez" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Parça içermeyen bir satıra stok tahsis edilemez" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Tahsis miktarı stok miktarını aşamaz" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Tahsis edilen miktar sıfırdan büyük olmalıdır" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Seri numaralı stok kalemi için miktar 1 olmalıdır" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Satış siparişi sevkiyatla eşleşmiyor" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Sevkiyat satış siparişiyle eşleşmiyor" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Satır" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Satış siparişinin sevkiyat referansı" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Kalem" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Tahsis edilecek stok kalemini seçin" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Stok tahsis miktarını girin" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "İade Siparişi referansı" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Ürünlerin iade edildiği şirket" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "İade siparişi durumu" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "İade Siparişi Satırı" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "Stok kalemi belirtilmelidir" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "İade miktarı stok miktarını aşıyor" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "İade miktarı sıfırdan büyük olmalıdır" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "Seri numaralı stok kalemi için geçersiz miktar" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Müşteriden iade edilecek ürünü seçin" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Teslim Alma Tarihi" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "Bu iade kaleminin teslim alındığı tarih" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Sonuç" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Bu satırın sonucu" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Bu kalem için iade veya onarımla ilgili maliyet" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "Ek Sipariş Kalemi" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "Sipariş ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "Aktarım Emri Referansı" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "Kopyası oluşturulacak siparişin ID'si" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "Aktarım emri durumu" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "Satırları Kopyala" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "Aktarılan kalemlerin kaynağı" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "Satırları orijinal siparişten kopyala" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "Aktarılan kalemlerin varış yeri" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "Ek Kalemleri Kopyala" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "Stoku Tüket" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "Orijinal siparişten ek kalemleri kopyala" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "Stokları hedef noktaya aktarmak yerine, tahsis edilen stok kaleminden aktarılan miktarı çıkararak \"tüket\"" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Parametreleri Kopyala" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "Hedef konum belirlenene kadar emir tamamlanamaz" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" -msgstr "Parametreleri orijinal siparişten kopyala" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "Tümüyle tahsis edilene kadar emir tamamlanamaz" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "Emir Satırını Aktar" + +#: order/models.py:4027 +msgid "transferred" +msgstr "aktarıldı" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "aktarılan miktar" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "Transfer Emri Tahsisatı" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Satırlar" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "Tamamlanan Satırlar" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "Siparişin Kopyasını Oluştur" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "Özel Durum Anahtarı" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "Bu siparişin kopyasını oluşturmak için seçenekleri belirtin" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "Bu mantıksal değer için sipariş durumunu özel bir değere güncelle" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "Geçersiz sipariş ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "Özel durum anahtarı bir tamsayı olmalıdır" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "Geçersiz özel durum anahtarı" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "Bu sipariş durumu için geçersiz özel durum anahtarı" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Tedarikçi Adı" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Sipariş iptal edilemez" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Satır eksiği olan siparişin kapatılmasına izin ver" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Siparişin eksik satırları var" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Sipariş açık değil" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "Otomatik Fiyatlandırma" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "Tedarikçi parça verilerine göre satın alma fiyatını otomatik olarak hesapla" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Satın alma fiyatı para birimi" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "Kalemleri Birleştir" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "Aynı parça, hedef ve hedef tarihe sahip kalemleri tek bir satırda birleştir" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "SKU" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Dahili Parça Numarası" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "Dahili Parça Adı" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Tedarikçi parçası belirtilmeli" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Satın alma siparişi belirtilmeli" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Tedarikçi satın alma siparişi ile eşleşmelidir" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Satın alma siparişi tedarikçi ile eşleşmelidir" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Satır" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Teslim alınan kalemler için varış konumunu seçin" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Gelen stok kalemleri için parti numarası girin" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" -msgstr "Son Kullanma Tarihi" +msgstr "Raf Ömrü Tarihi" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" -msgstr "Gelen stok kalemleri için son kullanma tarihi girin" +msgstr "Gelen stok kalemleri için raf ömrü tarihi girin" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Gelen stok kalemlerinin seri numaralarını girin" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "Gelen stok kalemlerinin paketleme bilgilerini geçersiz kıl" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "Gelen stok kalemleri için ek not" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Barkod" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Taranan barkod" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Barkod zaten kullanımda" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Satırlar sağlanmalıdır" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Hedef konum belirtilmelidir" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Sağlanan barkod değerleri benzersiz olmalıdır" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "Sevkiyatlar" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Tamamlanan Sevkiyatlar" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "Tahsis Edilen Kalemler" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Satış para birimi" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "Tahsis Edilen Kalemler" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Sevkiyat bilgileri sağlanmadı" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Ürün kalemi bu siparişle ilişkilendirilmemiştir" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Miktar pozitif olmalıdır" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" -msgstr "" +msgstr "Stok kalemi gerekli tüm testleri geçmedi" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Tahsis edilecek seri numaralarını girin" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Sevkiyat zaten sevk edildi" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Sevkiyat bu sipariş ile ilişkilendirilmemiştir" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Şu seri numaraları için bir eşleşme bulunamadı" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "Kalemlerin alınacağı stok konumu (herhangi bir konumdan almak için boş bırakın)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "Şu seri numaraları mevcut değildir" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "Stok kalemlerini bu konumdan hariç tut" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "Tahsisleri bu sevkiyata ata" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "Tek bir satır kalemini karşılamak için birden fazla konumdan mal alınmasına izin ver" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "Seri Numaralı Stok" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "Otomatik tahsise seri numaralı stok kalemlerinin dahil edilip edilmediğini kontrol et" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "Tahsisatı şu satırlara sınırla (tüm satırlara tahsis etmek için boş bırakın)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "Satır bu emre ait değil" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "İade siparişi kalemi" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Ürün kalemi iade siparişi ile eşleşmiyor" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Ürün kalemi zaten teslim alındı" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Ürün kalemleri yalnızca işlemdeki siparişlere istinaden teslim alınabilir" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "İade olacak miktar" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Satır para birimi" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "Üretimin eksik tahsisler ile tamamlanmasına izin ver" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "Üretimin eksik tahsisleri var" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Kayıp" @@ -5718,1279 +6125,1312 @@ msgstr "Kayıp" msgid "Returned" msgstr "İade" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Devam Ediyor" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Geri Dön" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Onar" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Değiştir" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Geri öde" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Reddet" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Düzenlendi" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Geciken Satın Alma Siparişi" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Satın alma siparişi {po} şimdi gecikti" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Geciken Satış Siparişi" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Satış siparişi {so} şimdi gecikti" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "Gecikmiş İade Siparişi" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "İade siparişi {ro} şimdi gecikti" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "Yıldızlı" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "Yıldızlı kategorilere göre filtrele" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Derinlik" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "Kategori derinliğine göre filtrele" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "Üst Seviye" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "Üst seviye kategorilere göre filtrele" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "Kademeli" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "Filtrelenmiş sonuçlara alt kategorileri dahil et" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Üst" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Üst kategoriye göre filtrele" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "Belirtilen kategorideki alt kategorileri hariç tut" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "Sonuçları Olanlar" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "Varyant mı" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "Revizyon mu" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "Revizyonu Olanlar" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "BOM Geçerli" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "Kategorileri Kademele" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "Etkin ise, verilen kategorinin alt kategorilerindeki ögeleri dahil et" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "Sayısal kategori ID veya 'null' sabitine göre filtrele" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "Montaj parçası etkin" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "Montaj parçası takip edilebilir" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "Montaj test edilebilir" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" -msgstr "" +msgstr "Montaj parçası kilitlidir" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "Bileşen etkin" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "Bileşen takip edilebilir" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "Bileşen test edilebilir" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "Bileşen bir montaj parçası" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "Bileşen sanal" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "Stok mevcut" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "Kullanımlar" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Parça Kategorisi" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Parça Kategorileri" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Varsayılan Konum" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Bu kategori içindeki parçalar için varsayılan konum" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Yapısal" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Parçalar doğrudan bir yapısal kategoriye atanamayabilir, ancak alt kategorilere atanabilir." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Varsayılan anahtar kelimeler" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Bu kategoridaki parçalar için varsayılan anahtar kelimeler" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Simge" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Simge (isteğe bağlı)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Bu parça kategorisini yapısal hale getiremezsiniz çünkü bazı parçalar zaten bu kategoriye atanmıştır!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "Parça Kategorisi Parametre Şablonu" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Varsayılan Değer" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Varsayılan Parametre Değeri" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Parçalar" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "Kilitli bir parçanın parametreleri silinemez" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "Kilitli bir parçanın parametreleri değiştirilemez" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Bu parça kilitli olduğu için silinemez" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Bu parça hala aktif olduğundan silinemez" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Bu parça bir montajda kullanıldığından silinemez" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "'{self}' parçası, '{parent}' için BOM'da kullanılamaz (yinelemeli)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "'{parent}' parçası, '{self}' için BOM'da kullanılır (yinelemeli)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN, düzenli ifade kalıbı {pattern} ile eşleşmelidir" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "Parça, kendisinin revizyonu olamaz" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" -msgstr "" +msgstr "Bir revizyon olarak işaretlenen bir parçaya revizyon kodu belirtilmelidir" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "Revizyonlara yalnızca montaj parçaları için izin verilir" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "Bir şablon parçanın revizyonu yapılamaz" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "Üst parça aynı şablonu göstermelidir" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Bu seri numarasına sahip stok kalemi zaten var" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "Yinelenen DPN'ye parça ayarlarında izin verilmiyor" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "Kopyası oluşturulan parça revizyonu zaten var." -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Bu Ad, IPN ve Revizyona sahip parça zaten var." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Parçalar yapısal parça kategorilerine atanamaz!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Parça adı" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Şablon Mu" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Bu parça bir şablon parçası mı?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Bu parça başka bir parçanın varyantı mı?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Şunun Varyantı" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Açıklama (isteğe bağlı)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Anahtar kelimeler" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Arama sonuçlarında görünürlüğü artırmak için parça anahtar kelimeleri" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Parça kategorisi" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "DPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Parça revizyon veya versiyon numarası" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Revizyon" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "Bu parça başka bir parçanın revizyonu mu?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Şunun Revizyonu" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Bu kalem normalde nerede depolanır?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" -msgstr "Varsayılan Son Kullanma" +msgstr "Varsayılan Raf Ömrü" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" -msgstr "Bu parçanın stok kalemleri için son kullanma süresi (gün olarak)" +msgstr "Bu parçanın stok kalemleri için raf ömrü süresi (gün olarak)" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Minimum Stok" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "İzin verilen minimum stok düzeyi" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" -msgstr "" +msgstr "Maksimum Stok" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" -msgstr "" +msgstr "İzin verilen maksimum stok düzeyi" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Bu parça için ölçü birimleri" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Bu parça diğer parçalardan üretilebilir mi?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Bu parça diğer parçaların üretiminde kullanılabilir mi?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" -msgstr "Bu parçanın benzersiz kalemler için izleme özelliği var mı?" +msgstr "Bu parçanın benzersiz kalemler için takip özelliği var mı?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "Bu parçanın test sonuçları kaydedilebilir mi?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Bu parça dış tedarikçilerden satın alınabilir mi?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Bu parça müşterilere satılabilir mi?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Bu parça aktif mi?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "Kilitli parçalar değiştirilemez" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Bu, yazılım ürünü veya lisans gibi sanal bir parça mı?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "BOM Doğrulandı" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "Bu parçanın BOM'u geçerli mi?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "BOM sağlama toplamı" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Saklanan BOM sağlama toplamı" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOM'u kontrol eden" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "BOM kontrol tarihi" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Oluşturan Kullanıcı" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Bu parçanın sorumlu sahibi" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Birden fazla sat" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Fiyat hesaplamalarını önbelleğe almak için kullanılan para birimi" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Minimum BOM Maliyeti" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Bileşenlerin minimum maliyeti" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Maksimum BOM Maliyeti" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Bileşenlerin maksimum maliyeti" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Minimum Satın Alma Maliyeti" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Minimum tarihsel satın alma maliyeti" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Maksimum Satın Alma Maliyeti" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Maksimum tarihsel satın alma maliyeti" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Minimum Dahili Fiyat" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Dahili fiyat kademelerine dayalı minimum maliyet" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Maksimum Dahili Fiyat" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Dahili fiyat kademelerine dayalı maksimum maliyet" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Minimum Tedarikçi Fiyatı" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Parça için minimum dış tedarikçi fiyatı" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Maksimum Tedarikçi Fiyatı" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Parça için maksimum dış tedarikçi fiyatı" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Minimum Varyant Maliyeti" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Varyant parçaların hesaplanan minimum maliyeti" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Maksimum Varyant Maliyeti" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Varyant parçaların hesaplanan maksimum maliyeti" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Minimum Maliyet" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Minimum maliyeti geçersiz kıl" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Maksimum Maliyet" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Maksimum maliyeti geçersiz kıl" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Hesaplanan genel minimum maliyet" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Hesaplanan genel maksimum maliyet" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Minimum Satış Fiyatı" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Fiyat kademelerine dayalı minimum satış fiyatı" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Maksimum Satış Fiyatı" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Fiyat kademelerine dayalı maksimum satış fiyatı" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Minimum Satış Maliyeti" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Minimum tarihsel satış fiyatı" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Maksimum Satış Maliyeti" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Maksimum tarihsel satış fiyatı" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Stok sayımı için parça" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Kalem Sayısı" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Sayım anındaki tekil stok kaydı sayısı" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Sayım anındaki toplam mevcut stok" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Tarih" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Stok sayımının yapıldığı tarih" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Minimum Stok Maliyeti" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Mevcut stokun tahmini minimum maliyeti" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Maksimum Stok Maliyeti" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Mevcut stokun tahmini maksimum maliyeti" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "Parça Satış Fiyat Kademesi" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "Parça Test Şablonu" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "Geçersiz şablon adı - en az bir alfasayısal karakter içermelidir" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "Test şablonları sadece test edilebilir paçalar için oluşturulabilir" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "Aynı anahtara sahip test şablonu parça için zaten mevcut" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Test Adı" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Test için bir ad girin" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "Test Anahtarı" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "Test için basitleştirilmiş anahtar" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Test Açıklaması" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Bu test için açıklama girin" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "Bu test etkinleştirildi mi?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Gerekli" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Testi geçmesi için bu gerekli mi?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Değer Gerektirir" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Bir test sonucu eklerken bu test bir değer gerektirir mi?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Ek Gerektirir" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Bir test sonucu eklerken bu test bir dosya eki gerektirir mi?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "Bu test için geçerli seçenekler (virgül ile ayrılmış)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" -msgstr "" +msgstr "Geçersiz miktar - parça için bir birim belirtilmedi" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "Miktar sıfır veya daha büyük olmalıdır" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "BOM kalemi değiştirilemez - montaj kilitlidir" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "BOM kalemi değiştirilemez - varyant montajı kilitlidir" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Üst parçayı seçin" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Alt parça" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "BOM'da kullanılacak parçayı seçin" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" -msgstr "" +msgstr "Miktar" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" -msgstr "" +msgstr "Bir parçayı üretmek için tüketilen alt parçanın miktarı" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Bu BOM kalemi için BOM miktarı" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Bu BOM kalemi isteğe bağlıdır" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Bu BOM kalemi bir sarf malzemesidir (üretim emirlerinde izlenmez)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "Hazırlık Payı" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "Bir üretimdeki hazırlık kayıplarını telafi etmek için gereken ek miktar" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "Fire" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "Bir üretim için tahmini fire oranı, yüzde olarak ifade edilir (0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "Kat Yuvarlama" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "Gerekli üretim miktarını bu değerin en yakın katına yuvarlayın" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "BOM kalemi referansı" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "BOM kalemi notları" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Sağlama Toplamı" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "BOM satırı sağlama toplamı" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Doğrulandı" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Bu BOM kalemi doğrulandı" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Devralınır" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Bu BOM kalemi, varyant parçaların BOM'larından devralınmıştır" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Varyant parçaların stok kalemleri bu BOM kalemi için kullanılabilir" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "İzlenebilir parçalar için miktar tamsayı olmalıdır" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Alt parça belirtilmelidir" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "BOM Kalemi Muadili" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Muadil parça ile asıl parça aynı olamaz" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Üst BOM kalemi" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Muadil parça" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Parça 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Parça 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "İlgili Parçayı Seçin" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "Bu ilişki için not" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Bir parça ile kendisi arasında parça ilişkisi oluşturulamaz" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Kopyalanan ilişki zaten mevcut" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "Alt Kategorileri Sil" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "Bu kategoride barındırılan tüm alt kategorileri sil" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "Parçaları Sil" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "Bu kategoride barındırılan tüm parçaları sil" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "Üst Kategori" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "Üst parça kategorisi" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Alt kategoriler" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Sonuçlar" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "Bu şablon ile ilişkilendirilmiş sonuç sayısı" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Bu stok kaleminin alış para birimi" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "Dosya bir görsel değil" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Orijinal Parça" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Kopyalanacak orijinal parçayı seçin" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Görseli Kopyala" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Orijinal parçadan görseli kopyala" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "BOM'u Kopyala" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Orijinal parçadan ürün ağacını kopyala" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Orijinal parçadan parametreleri kopyala" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Notları Kopyala" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Orijinal parçadan notları kopyala" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "Testleri Kopyala" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "Orijinal parçadan test şablonlarını kopyala" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Başlangıç Stok Miktarı" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Bu parça için başlangıç stok miktarını belirtin. Miktar sıfır ise, stok eklenmez." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Başlangıç Stok Konumu" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Bu parça için başlangıç stok konumunu belirtin" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Tedarikçiyi seçin (veya atlamak için boş bırakın)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Üreticiyi seçin (veya atlamak için boş bırakın)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Üretici parça numarası" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" -msgstr "Seçilen şirket geçerli bir tedarikçi değildir" +msgstr "Seçili şirket geçerli bir tedarikçi değildir" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" -msgstr "Seçilen şirket geçerli bir üretici değildir" +msgstr "Seçili şirket geçerli bir üretici değildir" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Bu MPN ile eşleşen üretici parçası zaten mevcut" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Bu SKU ile tedarikçi parçası zaten mevcut" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Kategori Adı" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Üretiliyor" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "Bu parçanın şu anda üretimde olan miktarı" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "Bu parçanın üretilmesi planlanan açık miktarı" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Stok Kalemleri" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "Revizyonlar" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Toplam Stok" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "Tahsis Edilmemiş Stok" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "Varyant Stoku" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Parçanın Kopyasını Oluştur" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Başlangıç verisini diğer parçadan kopyala" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Görseli Kopyala" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Orijinal parçadan görseli kopyala" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "BOM'u Kopyala" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Orijinal parçadan ürün ağacını kopyala" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Notları Kopyala" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Orijinal parçadan notları kopyala" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "Testleri Kopyala" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "Orijinal parçadan test şablonlarını kopyala" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Başlangıç Stoku" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Başlangıç stok miktarı ile parça oluştur" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Tedarikçi Bilgileri" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Bu parça için ilk tedarikçi bilgilerini ekleyin" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Kategori Parametrelerini Kopyala" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" -msgstr "Seçilen parça kategorisinden parametre şablonlarını kopyala" +msgstr "Parametre şablonlarını seçili parça kategorisinden kopyala" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Mevcut Görsel" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Mevcut parça görselinin dosya adı" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Görsel dosyası mevcut değil" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Tüm ürün ağacını doğrula" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Üretebilir Miktar" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "Üretim Emirleri için Gerekli" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "Üretim Emirlerine Tahsis Edildi" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "Satış Siparişleri için Gerekli" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "Satış Siparişlerine Tahsis Edildi" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "Parça DPN" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "Parça Açıklaması" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "Stok sayımı bilgisi oluşturmak üzere bir parça (ve varsa varyantlarını) seçin" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "Kategorideki (ve alt kategorilerdeki) tüm parçaları dahil etmek için bir kategori seçin" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "Konumda (ve alt konumlarda) stoğu bulunan tüm parçaları dahil etmek için bir konum seçin" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "Stok Sayımı Kayıtları Oluşturun" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" -msgstr "Seçili parçalar için stok sayımı girdilerini kaydedin" +msgstr "Seçili parçalar için stok sayımı girdilerini kaydet" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "Rapor Oluştur" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" -msgstr "Seçili parçalar için stok sayımı raporu oluşturun" +msgstr "Seçili parçalar için bir stok sayımı raporu oluştur" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Minimum Fiyat" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Minimum fiyat için hesaplanan değeri geçersiz kıl" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Minimum fiyat para birimi" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Maksimum Fiyat" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Maksimum fiyat için hesaplanan değeri geçersiz kıl" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Maksimum fiyat para birimi" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Güncelle" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Bu parçanın fiyatlandırmasını güncelle" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Sağlanan para birimlerinden {default_currency} para birimine dönüştürülemedi" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Minimum fiyat maksimum fiyattan yüksek olamaz" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Maksimum fiyat minimum fiyattan düşük olamaz" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" -msgstr "" +msgstr "Bu öge için gereken miktar (birim içerebilir)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "Üst montajı seçin" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "Bileşeni seçin" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" -msgstr "" +msgstr "Geçersiz miktar biçimi" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "BOM'u kopyalanacak parçayı seçin" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Mevcut Verileri Temizle" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Kopyalamadan önce mevcut BOM kalemlerini temizle" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Devralınanı Dahil Et" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Şablon parçalardan devralınan BOM kalemlerini dahil et" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Geçersiz Satırları Atla" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Geçersiz satırları atlamak için bu seçeneği etkinleştir" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Muadil Parçaları Kopyala" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "BOM kalemlerinin kopyasını oluştururken muadil parçaları kopyala" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Düşük stok bildirimi" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "{part.name} için mevcut stok, yapılandırılan minimum seviyenin altına düştü" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "Eskimiş stok bildirimi" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" -msgstr "Geçerlilik tarihi yaklaşan 1 adet stok kaleminiz var" +msgstr "Raf ömrünü doldurmak üzere olan 1 adet stok kaleminiz var" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" -msgstr "Geçerlilik tarihleri yaklaşan {item_count} adet stok kaleminiz var" +msgstr "Raf ömrünü doldurmak üzere olan {item_count} adet stok kaleminiz var" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" -msgstr "Geçerlilik tarihi yok" +msgstr "Raf ömrü yok" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "{abs(days_diff)} Gün önce süresi doldu" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "Süresi bugün doluyor" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry} gün" @@ -7011,7 +7451,7 @@ msgstr "Numune" msgid "Installed" msgstr "Kuruldu" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "Bu eklenti şu an aktif olduğundan silinemez" @@ -7023,23 +7463,23 @@ msgstr "İşlem belirtilmedi" msgid "No matching action found" msgstr "Eşleşen eylem bulunamadı" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Barkod verisi için eşleşme bulunamadı" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Barkod verisi için eşleşme bulundu" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "Model desteklenmiyor" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "Model örneği bulunamadı" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Barkod mevcut kalemle eşleşiyor" @@ -7055,51 +7495,67 @@ msgstr "Eşleşen tedarikçi parçası verisi bulunamadı" msgid "Multiple matching supplier parts found" msgstr "Birden çok eşleşen tedarikçi parçası bulundu" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "Barkod verisi için eşleşen eklenti bulunamadı" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Eşleşen tedarikçi parçası" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Ürün kalemi zaten teslim alındı" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "Satın alma siparişi bulundu\\rEşleşen Tedarikçi Parçası Yok" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "Tedarikçi Parçası Bulundu\\rEşleşen Satın Alma Siparişi Yok" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "Tedarikçi barkodu için uygun eklenti bulunamadı" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "Birden çok eşleşen satır bulundu" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "Eşleşen satır bulunamadı" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "Satış siparişi sağlanmadı" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "Barkod mevcut bir stok kalemiyle eşleşmiyor" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "Stok kalemi satır kalemiyle eşleşmiyor" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Mevcut stok yetersiz" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "Stok kalemi satış siparişine tahsis edilmiştir" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Yetersiz bilgi" @@ -7108,23 +7564,23 @@ msgstr "Yetersiz bilgi" msgid "Found matching item" msgstr "Eşleşen öge bulundu" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "Tedarikçi parçası satır ile eşleşmiyor" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "Satır zaten tamamlandı" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Satır kalemini teslim almak için gerekli ek bilgiler" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Teslim alınan satın alma satırı" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "Satırı teslim alınamadı" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Barkodlar için yerleşik destek sağlar" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "Kısa Barkod Ön Eki" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "Kısa barkodlar için kullanılan ön eki özelleştirin; birden fazla InvenTree örneği bulunan ortamlar için kullanışlı olabilir" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "Üretimleri Otomatik Oluştur" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "Montajlar için otomatik olarak üretim emirleri oluşturun" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "Varyantları Ekle" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "Fiyat hesaplamalarına parça varyant stokunu ekle" +msgid "Include part variant stock in stocktake data" +msgstr "Stok sayımı verilerine parça varyant stoklarını dahil et" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "Sıfır Stoklu Kayıtları Hariç Tut" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "Stok seviyesi sıfır olan parçaları dışa aktarılan veri kümesinden hariç tut" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "Parça Stok Sayımı Dışa Aktarıcı" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "Parça stok sayımı dışa aktarıcısı" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "Minimum Birim Maliyeti" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "Maksimum Birim Maliyeti" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "Minimum Toplam Maliyet" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "Maksimum Toplam Maliyet" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "InvenTree Arayüz Bildirimleri" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "Entegre arayüz bildirim yöntemleri" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree E-posta Bildirimleri" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "Entegre e-posta bildirim yöntemleri" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "E-posta bildirimlerine izin verin" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "Bu kullanıcıya e-posta bildirimlerinin gönderilmesine izin verin" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree Slack Bildirimleri" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "InvenTree Slack bildirim yöntemleri" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "Slack gelen webhook URL'si" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "Bir Slack kanalına mesajlar göndermek için kullanılacak URL" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Bağlantıyı aç" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "PDF etiketleri yazdırmak için yerleşik destek sağlar" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Hata ayıklama modu" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Hata ayıklama modunu etkinleştir - PDF yerine ham HTML döndürür" @@ -7653,55 +8117,55 @@ msgstr "son kullanılan" msgid "Options" msgstr "Seçenekler" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Etiket sayfasının boyutu" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Etiketleri Atla" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Etiket sayfası yazdırılırken atlanacak etiket sayısı" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Kenarlık" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "Her etiketin etrafına kenarlık ekle" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Yatay" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "Etiket sayfasını yatay olarak yazdır" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "Sayfa Kenar Boşluğu" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "Sayfanın kenar boşluğu (mm)" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "InvenTree Etiket Sayfası Yazıcısı" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Birden fazla etiketi tek bir sayfaya dizer" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Etiket bu sayfa boyutu için çok büyük" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Hiç etiket oluşturulmadı" @@ -7753,77 +8217,85 @@ msgstr "TME barkodları taraması için destek sağlar" msgid "The Supplier which acts as 'TME'" msgstr "'TME' rolünü üstlenen tedarikçi" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 -#: plugin/serializers.py:275 -msgid "Only superuser accounts can administer plugins" +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 +#: plugin/serializers.py:275 +msgid "Only superuser accounts can administer plugins" +msgstr "Eklentileri yalnızca süper kullanıcı hesapları yönetebilir" + +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "Eklenti kurulumu devre dışı bırakıldı" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" -msgstr "" +msgstr "Kurulum için bir paket adı veya URL belirtilmemiştir" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" -msgstr "" +msgstr "Paket adı veya URL içinde geçersiz karakterler" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Eklenti kurulumu başarılı" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Eklenti {path} yoluna kuruldu" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "Eklenti kayıt defterinde bulunamadı" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "Eklenti paketlenmiş bir eklenti değildir" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "Eklenti paketi adı bulunamadı" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "Eklentileri yalnızca yetkili personel yönetebilir" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "Eklenti kaldırma devre dışı bırakıldı" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "Bu eklenti şu an aktif olduğundan kaldırılamaz" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "Eklenti zorunlu olduğu için kaldırılamaz" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "Eklenti örnek bir eklenti olduğu için kaldırılamaz" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "Eklenti yerleşik bir eklenti olduğu için kaldırılamaz" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "Eklenti kurulu değil" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "Eklenti kurulumu bulunamadı" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "Eklenti başarıyla kaldırıldı" @@ -7871,25 +8343,25 @@ msgstr "Zorunlu Eklenti" msgid "Package Plugin" msgstr "Paket Eklenti" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Eklenti" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Yazar bulunamadı" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "'{p}' eklentisi, şu anki InvenTree sürümü {v} ile uyumlu değildir" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Eklenti en az {v} sürümünü gerektirir" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Eklenti en fazla {v} sürümünü gerektirir" @@ -8114,200 +8586,208 @@ msgstr "Yapılandırmayı sil" msgid "Delete the plugin configuration from the database" msgstr "Eklenti yapılandırmasını veritabanından sil" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "Bu ayarın yapılandırma tarafından geçersiz kılınıp kılınmadığını gösterir" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "Bu ayarların uygulanacağı kullanıcı" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "Kalemler" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "Eklenti bulunamadı" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "Eklenti, etiket yazdırmayı desteklemiyor" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "Bu model türünü görme izniniz yok" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "Geçersiz etiket boyutları" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "Şablona geçerli öge sağlanmadı" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Yasal" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Harf" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "Aynı isimde bir şablon zaten mevcut" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Şablon adı" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "Şablon açıklaması" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "Revizyon numarası (otomatik artar)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "Yazdırmada Modele Ekle" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "Yazdırırken rapor çıktısını bağlantılı model örneğine ek olarak kaydet" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Dosya Adı Deseni" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "Dosya adları oluşturmak için desen" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "Şablon etkinleştirildi" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "Şablon için hedef model türü" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Filtreler" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "Şablon sorgu filtreleri (virgülle ayrılmış anahtar=değer çiftleri listesi)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "Şablon dosyası" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "PDF raporları için sayfa boyutu" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Raporu yatay yönde işle" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "Birleştir" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "Seçili ögeler için tek bir rapor oluştur" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "{self.name} şablonundan oluşturulan rapor" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "Şablon sözdizimi hatası" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "Rapor işleme hatası" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "Rapor oluşturma hatası" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "Rapor çıktılarını birleştirme hatası" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Genişlik [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Etiket genişliği mm olarak belirtilmeli" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Yükseklik [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Etiket yüksekliği mm olarak belirtilmeli" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "Etiket yazdırma hatası" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Parçacık" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Rapor parçacık dosyası" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Parçacık dosyası açıklaması" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Kaynak Dosyası" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Rapor kaynak dosyası" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Kaynak dosyası açıklaması" #: report/serializers.py:37 msgid "User must be authenticated to save report templates" -msgstr "" +msgstr "Rapor şablonlarını kaydetmek için kullanıcının kimliği doğrulanmış olmalıdır" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "Rapor şablonu seç" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "Rapora dahil edilecek öge birincil anahtarlarının listesi" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "Etiket Şablonu Seç" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "Yazdırma Eklentisi" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "Etiket yazdırma için kullanılacak eklentiyi seç" @@ -8338,13 +8818,10 @@ msgstr "Gerekli Malzemeler" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Parça görseli" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Düzenlendi" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "İçin Gerekli Olan" @@ -8380,8 +8857,8 @@ msgstr "Toplam" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Seri Numara" @@ -8405,7 +8882,7 @@ msgstr "Stok Kalemi Test Raporu" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Takılı Kalemler" @@ -8438,810 +8915,922 @@ msgstr "Sonuç yok (gerekli)" msgid "No result" msgstr "Sonuç yok" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "Aktarıldı" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" -msgstr "" +msgstr "Geçersiz ortam dosya yolu" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" -msgstr "" +msgstr "Geçersiz statik dosya yolu" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" -msgstr "" +msgstr "Varlık dosyası bulunamadı" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Görsel dosyası bulunumadı" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" -msgstr "" +msgstr "Görüntü dosyası belirtilmedi" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "part_image etiketi bir parça örneği gerektirir" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "company_image etiketi bir şirket örneği gerektirir" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "Konum derinliğine göre filtrele" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "Üst seviye konumlara göre filtrele" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "Filtrelenmiş sonuçlara alt konumları dahil et" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "Üst Konum" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "Üst konuma göre filtrele" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "Parça adı (büyük/küçük harf duyarlı değildir)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "Parça adı şunu içerir (büyük/küçük harf duyarlı değildir)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "Parça adı (regex)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "Parça IPN (büyük/küçük harf duyarlı değildir)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "Parça IPN şunu içerir (büyük/küçük harf duyarlı değildir)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "Parça IPN (regex)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "Minimum stok" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "Maksimum stok" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Durum Kodu" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Harici Konum" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "Üretim Emrine göre Tüketilenler" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" -msgstr "Başka bir stok kalemine bağlı" +msgstr "Başka bir stok kalemine takılı" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Parça Ağacı" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "Daha önce güncellendi" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "Güncellendi (den sonra)" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "Stok Sayımı (-dan önce)" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "Stok Sayımı (-dan sonra)" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "Stok Sayım Tarihi Olanlar" + +#: stock/api.py:1001 msgid "Expiry date before" -msgstr "Son kullanma tarihi öncesi" +msgstr "Raf ömrü şu tarihten önce" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" -msgstr "Son kullanma tarihi sonrası" +msgstr "Raf ömrü şu tarihten sonra" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Bozuk" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "Bu stok kalemini ve bağlı tüm alt kalemleri hariç tutmak için bir PK girin" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "Konumları alt konumlara uygula" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "Açıksa belirtilen konumun alt konumlarındaki öğeleri de dahil eder" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "Sayısal konum ID'si veya \"null\" değeriyle filtreleyin" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Miktar gereklidir" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Geçerli bir parça girilmelidir" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Belirtilen tedarikçi parçası bulunamadı" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Tedarikçi parçası için paket boyutu tanımlanmış, ancak ‘use_pack_size’ seçeneği etkin değil" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Takibi olmayan bir parça için seri numarası verilemez" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "Takılıyı Dahil Et" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "Aktifse verilen stok kaleminin altına takılı öğelerin test sonuçları da dahil edilir" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "Sayısal Stok Kalemi ID’sine göre Filtrele" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "Belirtilen ID {id} ile bir stok kalemi bulunamadı" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "Varyantları Dahil Et" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "(-den sonra) sil" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "Önce" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Stok Konumu Türü" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Stok Konum Türleri" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Simge atanmamış tüm konumlar için varsayılan simge (isteğe bağlı)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Stok Konumu" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Stok Konumları" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Sahip" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Sahibi Seçin" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Stok kalemleri yapısal stok konumlarına doğrudan yerleştirilemez; ancak alt konumlara yerleştirilebilir." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Harici" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Bu, harici bir stok konumudur" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Konum türü" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Bu konumun stok konumu türü" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Bazı stok kalemleri zaten bu stok konumunda bulunduğundan, bu stok konumunu yapısal hale getiremezsiniz!" -#: stock/models.py:537 -msgid "Serialized stock items cannot be deleted" -msgstr "" +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "Önce en eski stok (FIFO)" -#: stock/models.py:674 +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "Önce en yeni stok (LIFO)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "Önce en küçük miktar" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "Önce en büyük miktar" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "Önce en yakın raf ömrü" + +#: stock/models.py:582 +msgid "Serialized stock items cannot be deleted" +msgstr "Seri numaralı stok kalemleri silinemez" + +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field} mevcut değil" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "Parça belirtilmelidir" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Stok kalemleri yapısal stok konumlarına yerleştirilemez!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "Seri numalarının düzenlemesine izin verilmez - bu ögeye zaten bir seri numarası atanmıştır" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Sanal parçalar için stok kalemi oluşturulamaz" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Parça türü ('{self.supplier_part.part}'), {self.part} olmalıdır" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Seri numarası olan ögenin miktarı bir olmalı" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Miktar birden büyük ise seri numarası ayarlanamaz" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Öge kendisine ait olamaz" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "is_building=True ise ögenin bir üretim referansı olmalıdır" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Üretim referansı aynı parça nesnesini göstermiyor" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Üst Stok Kalemi" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Temel parça" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Bu stok kalemiyle eşleşen bir tedarikçi parçası seçin" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Bu stok kalemi nerede bulunur?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Bu stok kaleminin ambalajı şu şekilde saklanmaktadır" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Şuna Takıldı" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Bu öge başka bir ögeye takılı mı?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Bu öge için seri numarası" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Bu stok kalemine ait parti kodu" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Stok Miktarı" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Kaynak Üretim" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Bu stok kalemi için üretim kaydı" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Tüketen" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Bu stok kaleminin kullanıldığı üretim emri" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Kaynak Satın Alma Emri" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Bu stok kalemi için satın alma emri" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Hedef satış siparişi" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" -msgstr "Stok kalemi için son kullanma tarihi. Bu tarihten sonra stok süresi dolmuş kabul edilir" +msgstr "Stok kalemi için raf ömrü tarihi. Bu tarihten sonra stok raf ömrünü doldurmuş kabul edilir" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "Bu stok kaleminin oluşturulduğu tarih" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Tükendiğinde sil" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Stok tükendiğinde bu stok kalemini sil" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Satın alma anındaki birim alış fiyatı" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Parçaya dönüştürüldü" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "Miktar, mevcut stoğu aşıyor" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "Stok, yapısal bir konuma atanamaz" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Parça için izlenebilirlik etkin değil" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Miktar tam sayı olmalıdır" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Miktar, mevcut stok miktarını ({self.quantity}) aşmamalıdır" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "Seri numaraları liste halinde girilmelidir" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Miktar seri numaları ile eşleşmiyor" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "Stok, yapısal bir konuma atanamaz" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "Test şablonu mevcut değil" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Stok kalemi bir satış siparişine atanmıştır" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Stok kalemi başka bir stok kalemine takılıdır" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" -msgstr "Bu öge, başka ögeler de içeriyor" +msgstr "Stok kalemi başka kalemleri de içermektedir" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" -msgstr "" +msgstr "Stok kalemi bir müşteriye atanmıştır" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" -msgstr "" +msgstr "Stok kalemi şu anda üretim aşamasındadır" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" -msgstr "" +msgstr "Seri numaralı stok birleştirilemez" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" -msgstr "" +msgstr "Yinelenen stok kalemleri" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" -msgstr "" +msgstr "Stok kalemleri aynı parçayı ifade etmelidir" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" -msgstr "" +msgstr "Stok kalemleri aynı tedarikçi parçasını ifade etmelidir" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" -msgstr "" +msgstr "Stok durum kodları eşleşmelidir" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Stok kalemi stokta olmadığı için taşınamaz" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" -msgstr "" +msgstr "Stok Kalemi Takibi" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" -msgstr "" +msgstr "Giriş notları" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" -msgstr "" +msgstr "Stok Kalemi Test Sonucu" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" -msgstr "" +msgstr "Bu test için değer sağlanmalıdır" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" -msgstr "" +msgstr "Bu test için dosya eki yüklenmelidir" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" -msgstr "" +msgstr "Bu tet için geçersiz değer" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" -msgstr "" +msgstr "Test sonucu" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" -msgstr "" +msgstr "Test çıktı değeri" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" -msgstr "" +msgstr "Test sonucu eki" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" -msgstr "" +msgstr "Test notları" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" -msgstr "" +msgstr "Test istasyonu" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" -msgstr "" +msgstr "Testin gerçekleştirildiği test istasyonunun tanımlayıcısı" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" -msgstr "" +msgstr "Başladı" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" -msgstr "" +msgstr "Test başlangıcı zaman damgası" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" -msgstr "" +msgstr "Bitti" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" -msgstr "" +msgstr "Test bitişi zaman damgası" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" -msgstr "" +msgstr "Oluşturulan parti kodu" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" -msgstr "" +msgstr "Üretim emri seç" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" -msgstr "" +msgstr "Parti kodu oluşturulacak stok kalemini seç" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" -msgstr "" +msgstr "Parti kodu oluşturulacak konumu seç" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" -msgstr "" +msgstr "Parti kodu oluşturulacak parçayı seç" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" -msgstr "" +msgstr "Satın alma siparişi seç" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" -msgstr "" +msgstr "Parti kodu için miktar gir" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" -msgstr "" +msgstr "Oluşturulan seri numarası" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" -msgstr "" +msgstr "Seri numarası oluşturulacak parçayı seç" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" -msgstr "" +msgstr "Oluşturulacak seri numaralarının miktarı" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" -msgstr "" +msgstr "Bu sonuç için test şablonu" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" -msgstr "" +msgstr "Bu parça ile eşleşen test bulunamadı" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" -msgstr "" +msgstr "Şablon ID veya test adı belirtilmelidir" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" -msgstr "" +msgstr "Testin bitiş zamanı, testin başlama zamanından daha erken olamaz" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" -msgstr "" +msgstr "Üst Kalem" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" -msgstr "" +msgstr "Üst stok kalemi" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" -msgstr "" +msgstr "Ekleme yaparken paket boyutunu kullan: tanımlanan miktar, paket sayısıdır" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" -msgstr "" +msgstr "Paket boyutunu kullan" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" -msgstr "" +msgstr "Yeni kalemler için seri numaraları gir" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Tedarikçi Parça Numarası" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" -msgstr "" +msgstr "Süresi dolmuş" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" -msgstr "" +msgstr "Alt Kalemler" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" -msgstr "" +msgstr "Takip Edilen Kalemler" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" -msgstr "" +msgstr "Bu stok kaleminin birim veya paket başına satın alma fiyatı" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" -msgstr "" +msgstr "Seri numarası verilecek stok kalemlerinin sayısını gir" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" -msgstr "" +msgstr "Stok kalemi belirtilmedi" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" -msgstr "" +msgstr "Miktar, mevcut stok miktarını ({q}) aşmamalıdır" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" -msgstr "" +msgstr "Hedef stok konumu" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Bu parçaya seri numarası atanamaz" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Seri numaraları zaten mevcut" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Takılacak stok kalemini seçin" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" -msgstr "Miktar" +msgstr "Takılacak Miktar" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Takılacak kalemlerin miktarını girin" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "İşlem notu ekle (isteğe bağlı)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Miktar en az \"1\" olmalıdır" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Stok kalemi mevcut değil" -#: stock/serializers.py:870 -msgid "Selected part is not in the Bill of Materials" -msgstr "Seçilen parça malzeme listesinde bulunamadı" - #: stock/serializers.py:883 +msgid "Selected part is not in the Bill of Materials" +msgstr "Seçili parça ürün ağacında bulunamadı" + +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Takılacak miktar, mevcudu geçmemeli" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Sökülen ürün için hedef konum" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Stok kaleminin dönüştürüleceği parçayı seçin" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Seçilen parça dönüştürülmeye uygun değil" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Tedarikçi parçası atanmış stok kalemi dönüştürülemez" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Stok kalemi durum kodu" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Stok kaleminin dönüştürüleceği parçayı seçin" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Seçili parça dönüştürme için geçerli bir seçenek değil" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Tedarikçi parçası atanmış stok kalemi dönüştürülemez" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Durumu değiştirilecek stok kalemlerini seçin" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Hiçbir stok kalemi seçilmedi" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Alt konumlar" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "Stok Kalemlerini Sil" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "Bu konumda barındırılan tüm stok kalemlerini sil" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "Alt Konumları Sil" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "Bu konumda barındırılan tüm alt konumları sil" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "Üst stok konumu" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Parça satılabilir olmalıdır" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Ürün bir satış siparişine tahsis edilmiştir" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "Kalem, bir transfer emrine tahsis edilmiştir" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Ürün bir üretim emrine tahsis edilmiştir" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Stok kalemlerini atamak için müşteri" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" -msgstr "Seçilen şirket bir müşteri değil" +msgstr "Seçili şirket bir müşteri değil" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Stok tahsis notları" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Bir stok kalemleri listesi girilmelidir" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Stok birleştirme notları" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Farklı tedarikçilere izin ver" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Farklı tedarikçi parçalarına sahip stokları birleştirmeye izin ver" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Farklı durumlara sahip kalemlere izin ver" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Farklı durum kodlarına sahip stokları birleştirmeye izin ver" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "En az iki stok kalemi girilmelidir" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "Değişiklik Yok" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Stok Kalemi birincil anahtar (PK) değeri" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "Stok kalemi mevcut stokta yok" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "Stok kalemi zaten stokta" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "Miktar negatif olamaz" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Stok aktarım notları" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "Mevcut stokla birleştir" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Stok aktarım notları" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "Sayılan kalemler için stok konumunu belirle (isteğe bağlı)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "Mümkünse iade edilen ürünleri mevcut stoklarla birleştir" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "Sıradaki Seri Numarası" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "Önceki Seri Numarası" @@ -9271,7 +9860,7 @@ msgstr "Karantinaya alındı" #: stock/status_codes.py:44 msgid "Legacy stock tracking entry" -msgstr "Eski stok izleme girişi" +msgstr "Eski stok takip kaydı" #: stock/status_codes.py:46 msgid "Stock item created" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Birleştirilen stok kalemleri" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Varyanta dönüştürüldü" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Üretim emri çıktısı oluşturuldu" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Üretim emri çıktısı tamamlandı" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Üretim emri çıktısı reddedildi" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Üretim emri tarafından tüketildi" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Satış siparişi kapsamında sevk edildi" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Satın alma siparişi kapsamında teslim alındı" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "İade siparişine karşılık iade edildi" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Müşteriye gönderildi" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Müşteriden geri döndü" @@ -9395,65 +9992,65 @@ msgstr "Kimlik Doğrulaması Başarısız" #: templates/403_csrf.html:12 msgid "You have been logged out from InvenTree." -msgstr "" +msgstr "InvenTree oturumunuzu kapattınız." #: templates/404.html:6 templates/404.html:10 msgid "Page Not Found" -msgstr "" +msgstr "Sayfa Bulunamadı" #: templates/404.html:11 msgid "The requested page does not exist" -msgstr "" +msgstr "İstenen sayfa mevcut değil" #: templates/500.html:6 templates/500.html:10 msgid "Internal Server Error" -msgstr "" +msgstr "Dahili Sunucu Hatası" #: templates/500.html:11 #, python-format msgid "The %(inventree_title)s server raised an internal error" -msgstr "" +msgstr "%(inventree_title)s sunucusu dahili bir hata verdi" #: templates/500.html:12 msgid "Refer to the error log in the admin interface for further details" -msgstr "" +msgstr "Daha ayrıntılı bilgi için yönetici arayüzündeki hata günlüğüne bakın" #: templates/503.html:11 templates/503.html:15 msgid "Site is in Maintenance" -msgstr "" +msgstr "Site Bakımda" #: templates/503.html:17 msgid "The site is currently in maintenance and should be up again soon!" -msgstr "" +msgstr "Site şu anda bakımda ve kısa süre içinde tekrar kullanıma açılacaktır!" #: templates/base.html:51 msgid "Server Restart Required" -msgstr "" +msgstr "Sunucunun Yeniden Başlatılması Gerekli" #: templates/base.html:54 msgid "A configuration option has been changed which requires a server restart" -msgstr "" +msgstr "Sunucunun yeniden başlatılmasını gerektiren bir yapılandırma seçeneği değiştirildi" #: templates/base.html:54 templates/base.html:64 msgid "Contact your system administrator for further information" -msgstr "" +msgstr "Daha fazla bilgi için sistem yöneticinizle iletişime geçin" #: templates/base.html:61 msgid "Pending Database Migrations" -msgstr "" +msgstr "Bekleyen Veritabanı Geçişleri" #: templates/base.html:64 msgid "There are pending database migrations which require attention" -msgstr "" +msgstr "Dikkat gerektiren bekleyen veritabanı geçişleri mevcut" #: templates/config_error.html:6 templates/config_error.html:10 msgid "Configuration Error" -msgstr "" +msgstr "Yapılandırma Hatası" #: templates/config_error.html:11 #, python-format msgid "The %(inventree_title)s server raised a configuration error" -msgstr "" +msgstr "%(inventree_title)s sunucusu bir yapılandırma hatası verdi" #: templates/email/build_order_completed.html:9 #: templates/email/canceled_order_assigned.html:9 @@ -9465,59 +10062,59 @@ msgstr "" #: templates/email/purchase_order_received.html:9 #: templates/email/return_order_received.html:9 msgid "Click on the following link to view this order" -msgstr "" +msgstr "Bu işlemi görüntülemek için aşağıdaki bağlantıya tıklayın" #: templates/email/build_order_required_stock.html:7 msgid "Stock is required for the following build order" -msgstr "" +msgstr "Aşağıdaki üretim emri için stok gereklidir" #: templates/email/build_order_required_stock.html:8 #, python-format msgid "Build order %(build)s - building %(quantity)s x %(part)s" -msgstr "" +msgstr "%(build)s üretim emri - %(quantity)s x %(part)s üretiliyor" #: templates/email/build_order_required_stock.html:10 msgid "Click on the following link to view this build order" -msgstr "" +msgstr "Bu üretim emrini görüntülemek için aşağıdaki bağlantıya tıklayın" #: templates/email/build_order_required_stock.html:14 msgid "The following parts are low on required stock" -msgstr "" +msgstr "Aşağıdaki parçaların stok seviyesi düşük" #: templates/email/build_order_required_stock.html:18 msgid "Required Quantity" -msgstr "" +msgstr "Gereken Miktar" #: templates/email/build_order_required_stock.html:38 #: templates/email/low_stock_notification.html:30 msgid "You are receiving this email because you are subscribed to notifications for this part " -msgstr "" +msgstr "Bu e-postayı almanızın nedeni, bu parçayla ilgili bildirimlere abone olmanızdır " #: templates/email/low_stock_notification.html:9 #: templates/email/part_event_notification.html:9 msgid "Click on the following link to view this part" -msgstr "" +msgstr "Bu parçayı görüntülemek için aşağıdaki bağlantıya tıklayın" #: templates/email/low_stock_notification.html:18 #: templates/email/part_event_notification.html:19 msgid "Minimum Quantity" -msgstr "" +msgstr "Minimum Miktar" #: templates/email/part_event_notification.html:32 msgid "You are receiving this email because you are subscribed to notifications for this part or a category that it is part of " -msgstr "" +msgstr "Bu e-postayı almanızın nedeni, bu parçaya veya parçanın dahil olduğu kategoriye ilişkin bildirimlere abone olmanızdır " #: templates/email/stale_stock_notification.html:10 msgid "The following stock items are approaching their expiry dates:" -msgstr "" +msgstr "Aşağıdaki stok kalemlerinin raf ömrü dolmak üzere:" #: templates/email/stale_stock_notification.html:23 msgid "Days Until Expiry" -msgstr "" +msgstr "Raf Ömrü Bitimine Kalan Günler" #: templates/email/stale_stock_notification.html:57 msgid "You are receiving this email because you are subscribed to notifications for these parts" -msgstr "" +msgstr "Bu e-postayı almanızın nedeni, bu parçalarla ilgili bildirimlere abone olmanızdır" #: users/admin.py:101 msgid "Users" @@ -9527,299 +10124,303 @@ msgstr "Kullanıcılar" msgid "Select which users are assigned to this group" msgstr "Bu gruba atanacak kullanıcıyı seçin" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Kullanıcı bilgisi" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Yetkiler" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Önemli tarihler" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" -msgstr "" +msgstr "Anahtar geçerliliği iptal edildi" #: users/authentication.py:33 msgid "Token has expired" -msgstr "" +msgstr "Anahtarın süresi doldu" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" -msgstr "" +msgstr "API Anahtarı" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" -msgstr "" +msgstr "API Anahtarları" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" -msgstr "" +msgstr "Anahtar Adı" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" -msgstr "" +msgstr "Özel anahtar adı" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" -msgstr "" +msgstr "Anahtar geçerlilik tarihi" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" -msgstr "" +msgstr "Son Görülme" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" -msgstr "" +msgstr "Anahtarın en son kullanıldığı tarih" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" -msgstr "" +msgstr "İptal Edildi" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "İzinleri ayarla" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Görünüm" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Parçayı görüntüleme izni" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" -msgstr "" +msgstr "Ekle" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Parça ekleme izni" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Değiştir" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Parçaları düzenleme izni" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" -msgstr "" +msgstr "Sil" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Parçaları silme izni" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" -msgstr "" +msgstr "Bot" + +#: users/models.py:492 +msgid "Internal" +msgstr "Dahili" #: users/models.py:494 -msgid "Internal" -msgstr "" - -#: users/models.py:496 msgid "Guest" -msgstr "" +msgstr "Konuk" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" -msgstr "" +msgstr "Dil" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" -msgstr "" +msgstr "Kullanıcının tercih ettiği dil" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" -msgstr "" +msgstr "Tema" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" -msgstr "" +msgstr "JSON formatında web kullanıcı arayüzü ayarları - lütfen manuel olarak düzenlemeyin!" + +#: users/models.py:515 +msgid "Widgets" +msgstr "Kartlar" #: users/models.py:517 -msgid "Widgets" -msgstr "" - -#: users/models.py:519 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" -msgstr "" +msgstr "JSON formatında pano kartları ayarları - lütfen manuel olarak düzenlemeyin!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" -msgstr "" +msgstr "Görünen Ad" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "Kullanıcının görünen adı" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "Konumu" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "Ana unvanı veya pozisyonu" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "Kullanıcı durum mesajı" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "Kullanıcı konum bilgisi" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "Kullanıcı, sistemi aktif kullanıyor" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "Kullanıcının tercih edilen iletişim bilgileri" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "Kullanıcı Türü" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "Bu, hangi tür kullanıcı?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "Organizasyon" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "Kullanıcının ana organizasyonu/ilişkisi" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "Birincil Grup" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "Kullanıcının birincil grubu" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Yönetici" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" -msgstr "" +msgstr "Ürün Ağaçları" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Satın Alma Siparişleri" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Satış Siparişleri" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" -msgstr "İade Emirleri" +msgstr "İade Siparişleri" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "Aktarım Emirleri" + +#: users/serializers.py:196 msgid "Username" msgstr "Kullanıcı Adı" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Adı" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Kullanıcının adı" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Soyadı" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Kullanıcının soyadı" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Kullanıcının e-posta adresi" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" -msgstr "" +msgstr "Kullanıcının kimlik doğrulaması yapılması gerekmektedir" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" -msgstr "" +msgstr "Yalnızca süper kullanıcı başka bir kullanıcı için bir token oluşturabilir" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" -msgstr "" +msgstr "Yönetici" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" -msgstr "" +msgstr "Bu kullanıcı yönetici yetkisine sahip mi" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Süper Kullanıcı" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Bu kullanıcı bir süper kullanıcı mı" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Bu kullanıcı hesabı aktif mi" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "Bu alanı sadece bir yönetici değiştirebilir" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" -msgstr "Parola" +msgstr "Şifre" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" -msgstr "Kullanıcının parolası" +msgstr "Kullanıcı için şifre" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "Uyarıları yok say" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "Şifre kuralları uyarılarını yok say" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" -msgstr "" +msgstr "Personel" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" -msgstr "" +msgstr "Bu kullanıcı personel yetkisine sahip mi" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "Kullanıcı yaratmak için yetkiniz yok" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Kullanıcı hesabınız oluşturulmuştur." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" -msgstr "Giriş yapmak için lütfen şifre sıfırlama fonksiyonunu kullanınız" +msgstr "Oturum açmak için lütfen şifre sıfırlama özelliğini kullanın" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "InvenTree'ye Hoşgeldiniz" diff --git a/src/backend/InvenTree/locale/uk/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/uk/LC_MESSAGES/django.po index 6be6d0a2d2..a92ec27bd6 100644 --- a/src/backend/InvenTree/locale/uk/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/uk/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "Кінцева точка API не знайдена" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "Сутності необхідно надати списком" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "Надано неправильний список сутностей" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "Немає сутностей що відповідають наданим критеріям" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" -msgstr "" +msgstr "Дані відсутні" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "У користувача немає дозволу на перегляд цієї моделі" @@ -65,150 +69,155 @@ msgstr "Підтвердження адреси електронної пошт msgid "You must type the same email each time." msgstr "Ви повинні використовувати щоразу однаковий email." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Вказана основна адреса електронної пошти недійсна." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Наданий домен електронної пошти не затверджено." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Надано неправильну одиницю виміру ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Значення не вказане" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Не вдалося перетворити {original} на {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Невірна кількість" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Деталі помилки можна знайти на панелі адміністратора" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Введіть дату" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "Неправильне десяткове значення" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Нотатки" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Значення '{name}' не відповідає шаблону формату" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Надане значення не відповідає обов'язковому шаблону: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "Неможливо серіалізувати більше ніж 1000 сутностей за раз" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Пустий серійний номер" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Видаліть HTML тег з цього значення" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "Дані містять заборонений вміст у форматі Markdown" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Помилка підключення" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Сервер відправив некоректний код статусу" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Відбулося виключення" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Сервер повернув невірне значення Content-Length" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Розмір зображення занадто великий" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Розмір зображення перевищує максимально дозволений розмір" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Віддалений сервер повернув пусту відповідь" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "" @@ -216,159 +225,203 @@ msgstr "" msgid "Log in to the app" msgstr "Авторизуватися в додатку" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Електронна пошта" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "Необхідно увімкнути двофакторну автентифікацію, перед тим як робити будь-що інше." -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Назва" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Опис" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Опис (опціонально)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Шлях" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Примітки в Markdown (опціонально)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Помилка сервера" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Зображення" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "" @@ -521,46 +574,48 @@ msgstr "Китайська (спрощена)" msgid "Chinese (Traditional)" msgstr "Китайська (Традиційна)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Деталь" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Розхідний матеріал" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Збірка" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Тестуємо" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Доступно" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Місце" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Обрати деталь для створення" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Кількість" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Дозволити варіанти" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "У виробництві" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "" @@ -1539,15 +1641,20 @@ msgstr "" msgid "No plugin" msgstr "" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "" @@ -1567,794 +1674,844 @@ msgstr "" msgid "Project description" msgstr "" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Користувач" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Ціна" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Користувач" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Ціна" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Назва" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Посилання" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Коментар" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "Дата завантаження" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "Дата завантаження файлу" -#: common/models.py:2118 -msgid "File size" -msgstr "Розмір файлу" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "Розмір файлу в байтах" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "Розмір файлу" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "Розмір файлу в байтах" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "Етикетка" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "Колір" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "Модель" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "Список вибору" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "Заблоковано" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Прапорець" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Шаблон" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Дані" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Примітка" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "" msgid "A order that is assigned to you was canceled" msgstr "" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "" @@ -2388,104 +2545,100 @@ msgstr "" msgid "Items have been received against a return order" msgstr "" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "" @@ -2614,13 +2767,13 @@ msgstr "" msgid "How often to update exchange rates (set to zero to disable)" msgstr "" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 -msgid "Allow deletion of parts which are used in an assembly" +msgid "Part Revisions" msgstr "" -#: common/setting/system.py:417 -msgid "IPN Regex" +#: common/setting/system.py:413 +msgid "Enable revision field for Part" msgstr "" #: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 +msgid "Allow deletion of parts which are used in an assembly" +msgstr "" + +#: common/setting/system.py:430 +msgid "IPN Regex" +msgstr "" + +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Компонент" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Доступний для продажу" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Віртуальний" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Показати пов'язані деталі" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "" -#: common/setting/system.py:668 -msgid "Log Report Errors" -msgstr "" - -#: common/setting/system.py:669 -msgid "Log errors which occur when generating reports" -msgstr "" - -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 -msgid "Page Size" -msgstr "" - -#: common/setting/system.py:675 -msgid "Default page size for PDF reports" -msgstr "" - -#: common/setting/system.py:680 -msgid "Enforce Parameter Units" +#: common/setting/system.py:681 +msgid "Report URL Fetching" msgstr "" #: common/setting/system.py:682 -msgid "If units are provided, parameter values must match the specified units" +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 +msgid "Log Report Errors" msgstr "" #: common/setting/system.py:688 -msgid "Globally Unique Serials" +msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:689 -msgid "Serial numbers for stock items must be globally unique" +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 +msgid "Page Size" msgstr "" #: common/setting/system.py:694 -msgid "Delete Depleted Stock" +msgid "Default page size for PDF reports" msgstr "" -#: common/setting/system.py:695 -msgid "Determines default behavior when a stock item is depleted" -msgstr "" - -#: common/setting/system.py:700 -msgid "Allow Edit Serial Number" +#: common/setting/system.py:699 +msgid "Enforce Parameter Units" msgstr "" #: common/setting/system.py:701 -msgid "Allow editing of serial number for stock items" -msgstr "" - -#: common/setting/system.py:706 -msgid "Delete Serialized Stock" +msgid "If units are provided, parameter values must match the specified units" msgstr "" #: common/setting/system.py:707 -msgid "Allow deletion of stock items which have a serial number" +msgid "Globally Unique Serials" msgstr "" -#: common/setting/system.py:712 -msgid "Batch Code Template" +#: common/setting/system.py:708 +msgid "Serial numbers for stock items must be globally unique" msgstr "" #: common/setting/system.py:713 -msgid "Template for generating default batch codes for stock items" +msgid "Delete Depleted Stock" msgstr "" -#: common/setting/system.py:717 -msgid "Stock Expiry" +#: common/setting/system.py:714 +msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:718 -msgid "Enable stock expiry functionality" +#: common/setting/system.py:719 +msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:723 -msgid "Sell Expired Stock" +#: common/setting/system.py:720 +msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:724 -msgid "Allow sale of expired stock" +#: common/setting/system.py:725 +msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:729 -msgid "Stock Stale Time" +#: common/setting/system.py:726 +msgid "Allow deletion of stock items which have a serial number" msgstr "" #: common/setting/system.py:731 -msgid "Number of days stock items are considered stale before expiring" +msgid "Batch Code Template" msgstr "" -#: common/setting/system.py:738 -msgid "Build Expired Stock" +#: common/setting/system.py:732 +msgid "Template for generating default batch codes for stock items" msgstr "" -#: common/setting/system.py:739 -msgid "Allow building with expired stock" +#: common/setting/system.py:736 +msgid "Stock Expiry" msgstr "" -#: common/setting/system.py:744 -msgid "Stock Ownership Control" +#: common/setting/system.py:737 +msgid "Enable stock expiry functionality" msgstr "" -#: common/setting/system.py:745 -msgid "Enable ownership control over stock locations and items" +#: common/setting/system.py:742 +msgid "Sell Expired Stock" +msgstr "" + +#: common/setting/system.py:743 +msgid "Allow sale of expired stock" +msgstr "" + +#: common/setting/system.py:748 +msgid "Stock Stale Time" msgstr "" #: common/setting/system.py:750 -msgid "Stock Location Default Icon" -msgstr "" - -#: common/setting/system.py:751 -msgid "Stock location default icon (empty means no icon)" -msgstr "" - -#: common/setting/system.py:756 -msgid "Show Installed Stock Items" +msgid "Number of days stock items are considered stale before expiring" msgstr "" #: common/setting/system.py:757 -msgid "Display installed stock items in stock tables" +msgid "Build Expired Stock" msgstr "" -#: common/setting/system.py:762 -msgid "Check BOM when installing items" +#: common/setting/system.py:758 +msgid "Allow building with expired stock" +msgstr "" + +#: common/setting/system.py:763 +msgid "Stock Ownership Control" msgstr "" #: common/setting/system.py:764 -msgid "Installed stock items must exist in the BOM for the parent part" +msgid "Enable ownership control over stock locations and items" +msgstr "" + +#: common/setting/system.py:769 +msgid "Stock Location Default Icon" msgstr "" #: common/setting/system.py:770 +msgid "Stock location default icon (empty means no icon)" +msgstr "" + +#: common/setting/system.py:775 +msgid "Show Installed Stock Items" +msgstr "" + +#: common/setting/system.py:776 +msgid "Display installed stock items in stock tables" +msgstr "" + +#: common/setting/system.py:781 +msgid "Check BOM when installing items" +msgstr "" + +#: common/setting/system.py:783 +msgid "Installed stock items must exist in the BOM for the parent part" +msgstr "" + +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" -msgstr "Чи призначені групи користувачеві повинні бути видалені, якщо вони не є резервним сервером IdP. Відключення цього налаштування може спричинити проблеми безпеки" - #: common/setting/system.py:1009 -msgid "Email required" -msgstr "" - -#: common/setting/system.py:1010 -msgid "Require user to supply mail on signup" -msgstr "" - -#: common/setting/system.py:1015 -msgid "Auto-fill SSO users" +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" msgstr "" #: common/setting/system.py:1016 -msgid "Automatically fill out user-details from SSO account-data" +msgid "Enable password forgot" msgstr "" -#: common/setting/system.py:1021 -msgid "Mail twice" +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" msgstr "" #: common/setting/system.py:1022 -msgid "On signup ask users twice for their mail" +msgid "Enable registration" msgstr "" -#: common/setting/system.py:1027 -msgid "Password twice" +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" msgstr "" #: common/setting/system.py:1028 -msgid "On signup ask users twice for their password" +msgid "Enable SSO" msgstr "" -#: common/setting/system.py:1033 -msgid "Allowed domains" +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" msgstr "" -#: common/setting/system.py:1035 -msgid "Restrict signup to certain domains (comma-separated, starting with @)" +#: common/setting/system.py:1034 +msgid "Enable SSO registration" msgstr "" -#: common/setting/system.py:1041 -msgid "Group on signup" +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" msgstr "" -#: common/setting/system.py:1043 -msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" msgstr "" -#: common/setting/system.py:1049 -msgid "Enforce MFA" +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "" #: common/setting/system.py:1050 -msgid "Users must use multifactor security." +msgid "SSO group key" msgstr "" -#: common/setting/system.py:1055 -msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" msgstr "" -#: common/setting/system.py:1060 -msgid "Check plugins on startup" +#: common/setting/system.py:1056 +msgid "SSO group map" msgstr "" -#: common/setting/system.py:1062 -msgid "Check that all plugins are installed on startup - enable in container environments" +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "" -#: common/setting/system.py:1069 -msgid "Check for plugin updates" +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" msgstr "" -#: common/setting/system.py:1070 -msgid "Enable periodic checks for updates to installed plugins" +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "Чи призначені групи користувачеві повинні бути видалені, якщо вони не є резервним сервером IdP. Відключення цього налаштування може спричинити проблеми безпеки" + +#: common/setting/system.py:1072 +msgid "Email required" msgstr "" -#: common/setting/system.py:1076 -msgid "Enable URL integration" +#: common/setting/system.py:1073 +msgid "Require user to supply mail on signup" msgstr "" -#: common/setting/system.py:1077 -msgid "Enable plugins to add URL routes" +#: common/setting/system.py:1078 +msgid "Auto-fill SSO users" msgstr "" -#: common/setting/system.py:1083 -msgid "Enable navigation integration" +#: common/setting/system.py:1079 +msgid "Automatically fill out user-details from SSO account-data" msgstr "" #: common/setting/system.py:1084 -msgid "Enable plugins to integrate into navigation" +msgid "Mail twice" +msgstr "" + +#: common/setting/system.py:1085 +msgid "On signup ask users twice for their mail" msgstr "" #: common/setting/system.py:1090 -msgid "Enable app integration" +msgid "Password twice" msgstr "" #: common/setting/system.py:1091 -msgid "Enable plugins to add apps" +msgid "On signup ask users twice for their password" msgstr "" -#: common/setting/system.py:1097 -msgid "Enable schedule integration" +#: common/setting/system.py:1096 +msgid "Allowed domains" msgstr "" #: common/setting/system.py:1098 -msgid "Enable plugins to run scheduled tasks" +msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "" #: common/setting/system.py:1104 -msgid "Enable event integration" +msgid "Group on signup" msgstr "" -#: common/setting/system.py:1105 -msgid "Enable plugins to respond to internal events" -msgstr "" - -#: common/setting/system.py:1111 -msgid "Enable interface integration" +#: common/setting/system.py:1106 +msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" #: common/setting/system.py:1112 -msgid "Enable plugins to integrate into the user interface" +msgid "Enforce MFA" +msgstr "" + +#: common/setting/system.py:1113 +msgid "Users must use multifactor security." msgstr "" #: common/setting/system.py:1118 -msgid "Enable mail integration" +msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1119 -msgid "Enable plugins to process outgoing/incoming mails" +#: common/setting/system.py:1123 +msgid "Check plugins on startup" msgstr "" #: common/setting/system.py:1125 -msgid "Enable project codes" +msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "" -#: common/setting/system.py:1126 -msgid "Enable project codes for tracking projects" -msgstr "" - -#: common/setting/system.py:1131 -msgid "Enable Stocktake" +#: common/setting/system.py:1132 +msgid "Check for plugin updates" msgstr "" #: common/setting/system.py:1133 -msgid "Enable functionality for recording historical stock levels and value" +msgid "Enable periodic checks for updates to installed plugins" msgstr "" #: common/setting/system.py:1139 -msgid "Exclude External Locations" +msgid "Enable URL integration" msgstr "" -#: common/setting/system.py:1141 -msgid "Exclude stock items in external locations from stocktake calculations" +#: common/setting/system.py:1140 +msgid "Enable plugins to add URL routes" +msgstr "" + +#: common/setting/system.py:1146 +msgid "Enable navigation integration" msgstr "" #: common/setting/system.py:1147 -msgid "Automatic Stocktake Period" +msgid "Enable plugins to integrate into navigation" msgstr "" -#: common/setting/system.py:1148 -msgid "Number of days between automatic stocktake recording" +#: common/setting/system.py:1153 +msgid "Enable app integration" msgstr "" #: common/setting/system.py:1154 -msgid "Delete Old Stocktake Entries" +msgid "Enable plugins to add apps" msgstr "" -#: common/setting/system.py:1156 -msgid "Delete stocktake entries older than the specified number of days" +#: common/setting/system.py:1160 +msgid "Enable schedule integration" msgstr "" -#: common/setting/system.py:1162 -msgid "Stocktake Deletion Interval" +#: common/setting/system.py:1161 +msgid "Enable plugins to run scheduled tasks" msgstr "" -#: common/setting/system.py:1164 -msgid "Stocktake entries will be deleted after specified number of days" +#: common/setting/system.py:1167 +msgid "Enable event integration" msgstr "" -#: common/setting/system.py:1171 -msgid "Delete Old Stock Tracking Entries" +#: common/setting/system.py:1168 +msgid "Enable plugins to respond to internal events" msgstr "" -#: common/setting/system.py:1173 -msgid "Delete stock tracking entries older than the specified number of days" +#: common/setting/system.py:1174 +msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1179 -msgid "Stock Tracking Deletion Interval" +#: common/setting/system.py:1175 +msgid "Enable plugins to integrate into the user interface" msgstr "" #: common/setting/system.py:1181 -msgid "Stock tracking entries will be deleted after specified number of days" +msgid "Enable mail integration" +msgstr "" + +#: common/setting/system.py:1182 +msgid "Enable plugins to process outgoing/incoming mails" msgstr "" #: common/setting/system.py:1188 -msgid "Display Users full names" +msgid "Enable project codes" msgstr "" #: common/setting/system.py:1189 -msgid "Display Users full names instead of usernames" +msgid "Enable project codes for tracking projects" msgstr "" #: common/setting/system.py:1194 -msgid "Display User Profiles" +msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1195 -msgid "Display Users Profiles on their profile page" +#: common/setting/system.py:1196 +msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1200 -msgid "Week Starts On" -msgstr "" - -#: common/setting/system.py:1201 -msgid "Starting day of the week, for display in calendar views" +#: common/setting/system.py:1202 +msgid "Exclude External Locations" msgstr "" #: common/setting/system.py:1204 -msgid "Sunday" -msgstr "" - -#: common/setting/system.py:1205 -msgid "Monday" -msgstr "" - -#: common/setting/system.py:1206 -msgid "Tuesday" -msgstr "" - -#: common/setting/system.py:1207 -msgid "Wednesday" -msgstr "" - -#: common/setting/system.py:1208 -msgid "Thursday" -msgstr "" - -#: common/setting/system.py:1209 -msgid "Friday" +msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" #: common/setting/system.py:1210 +msgid "Automatic Stocktake Period" +msgstr "" + +#: common/setting/system.py:1211 +msgid "Number of days between automatic stocktake recording" +msgstr "" + +#: common/setting/system.py:1217 +msgid "Delete Old Stocktake Entries" +msgstr "" + +#: common/setting/system.py:1219 +msgid "Delete stocktake entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1225 +msgid "Stocktake Deletion Interval" +msgstr "" + +#: common/setting/system.py:1227 +msgid "Stocktake entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1234 +msgid "Delete Old Stock Tracking Entries" +msgstr "" + +#: common/setting/system.py:1236 +msgid "Delete stock tracking entries older than the specified number of days" +msgstr "" + +#: common/setting/system.py:1242 +msgid "Stock Tracking Deletion Interval" +msgstr "" + +#: common/setting/system.py:1244 +msgid "Stock tracking entries will be deleted after specified number of days" +msgstr "" + +#: common/setting/system.py:1251 +msgid "Display Users full names" +msgstr "" + +#: common/setting/system.py:1252 +msgid "Display Users full names instead of usernames" +msgstr "" + +#: common/setting/system.py:1257 +msgid "Display User Profiles" +msgstr "" + +#: common/setting/system.py:1258 +msgid "Display Users Profiles on their profile page" +msgstr "" + +#: common/setting/system.py:1263 +msgid "Week Starts On" +msgstr "" + +#: common/setting/system.py:1264 +msgid "Starting day of the week, for display in calendar views" +msgstr "" + +#: common/setting/system.py:1267 +msgid "Sunday" +msgstr "" + +#: common/setting/system.py:1268 +msgid "Monday" +msgstr "" + +#: common/setting/system.py:1269 +msgid "Tuesday" +msgstr "" + +#: common/setting/system.py:1270 +msgid "Wednesday" +msgstr "" + +#: common/setting/system.py:1271 +msgid "Thursday" +msgstr "" + +#: common/setting/system.py:1272 +msgid "Friday" +msgstr "" + +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 -msgid "Receive error reports" -msgstr "" - -#: common/setting/user.py:262 -msgid "Receive notifications for system errors" +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "" #: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 +msgid "Receive error reports" +msgstr "" + +#: common/setting/user.py:282 +msgid "Receive notifications for system errors" +msgstr "" + +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "Позиція активна" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "Позиція постачальника активна" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "Внутрішня позиція активна" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Виробник" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "" msgid "Contact email address" msgstr "" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Позиція виробника" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Базова позиція" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Обрати позицію" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "Базова вартість" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Мінімальний платіж (напр. комісія за збереження)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "В наявності" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Дійсно" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Внутрішній компонент" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "" msgid "Sales Order" msgstr "" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "" -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "" @@ -5718,1279 +6125,1312 @@ msgstr "" msgid "Returned" msgstr "" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "Глибина" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "Батьківський елемент" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "Фільтр за батьківською категорією" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Позиції" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "Неможливо видалити цю позицію, оскільки вона заблокована" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "Неможливо видалити цю позицію, оскільки вона ще активна" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "Неможливо видалити цю позицію, бо вона використовується у збірці" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Назва позиції" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Це шаблон" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Ця позиція є шаблоном?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Опис позиції (опціонально)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Ревізія" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "Ревізія" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Мінімальний запас" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Мінімально дозволений рівень запасів" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Одиниці виміру для цієї позиції" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Чи можна побудувати цю позицію з інших компонентів?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Дата" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Тестова назва" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Позиція 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Позиція 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "Результати" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Виробничий номер позиції" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Початковий запас" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Наявне зображення" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Мінімальна ціна" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Максимальна ціна" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "" msgid "No matching action found" msgstr "" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "" @@ -7055,51 +7495,67 @@ msgstr "" msgid "Multiple matching supplier parts found" msgstr "" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "" @@ -7108,23 +7564,23 @@ msgstr "" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "" @@ -7753,77 +8217,85 @@ msgstr "" msgid "The Supplier which acts as 'TME'" msgstr "" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "" @@ -8291,23 +8771,23 @@ msgstr "" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Зображення позиції" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "" @@ -8380,8 +8857,8 @@ msgstr "" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "" @@ -8405,7 +8882,7 @@ msgstr "" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "" @@ -8438,810 +8915,922 @@ msgstr "" msgid "No result" msgstr "" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "" #: stock/status_codes.py:79 -msgid "Converted to variant" +msgid "Disassembled into components" msgstr "" -#: stock/status_codes.py:82 -msgid "Build order output created" +#: stock/status_codes.py:80 +msgid "Created from disassembly" msgstr "" #: stock/status_codes.py:83 +msgid "Converted to variant" +msgstr "" + +#: stock/status_codes.py:86 +msgid "Build order output created" +msgstr "" + +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "" @@ -9527,19 +10124,19 @@ msgstr "" msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "" @@ -9547,279 +10144,283 @@ msgstr "" msgid "Token has expired" msgstr "" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Ім`я" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Прізвище" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Адреса електронної пошти користувача" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "" diff --git a/src/backend/InvenTree/locale/vi/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/vi/LC_MESSAGES/django.po index 70077038b0..5df58f4ddb 100644 --- a/src/backend/InvenTree/locale/vi/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/vi/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:10\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Vietnamese\n" "Language: vi_VN\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "API endpoint không tồn tại" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "Không có dữ liệu được cung cấp" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "Người dùng không được phân quyền xem mẫu này" @@ -65,150 +69,155 @@ msgstr "Xác nhận địa chỉ email" msgid "You must type the same email each time." msgstr "Bạn phải nhập cùng một email mỗi lần." -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "Địa chỉ email chính đã cung cấp không hợp lệ." -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "Miền email được cung cấp không được phê duyệt." -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "Đơn vị không hợp lệ ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "Chưa cung cấp giá trị" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "Không thể chuyển đổi {original} sang {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "Số lượng cung cấp không hợp lệ" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "Chi tiết lỗi có thể được tìm thấy trong bảng quản trị" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "Nhập ngày" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "Ghi chú" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "Giá trị '{name}' không xuất hiện ở định dạng mẫu" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "Giá trị được cung cấp không khớp với mẫu bắt buộc: " -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "Chuỗi số sê-ri trống" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "Trùng lặp sê-ri" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "Khoảng nhóm {group} vượt cho phép số lượng ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "Không tìm thấy số sê-ri" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "Xóa thẻ HTML từ giá trị này" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "Lỗi kết nối" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "Máy chủ phản hồi với mã trạng thái không hợp lệ" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "Xảy ra Exception" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "Máy chủ đã phản hồi với giá trị Content-Length không hợp lệ" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "Hình ảnh quá lớn" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "Tải xuống hình ảnh vượt quá kích thước tối đa" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "Máy chủ trả về phản hồi trống" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "URL được cung cấp không phải là tệp hình ảnh hợp lệ" @@ -216,159 +225,203 @@ msgstr "URL được cung cấp không phải là tệp hình ảnh hợp lệ" msgid "Log in to the app" msgstr "" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "Email" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "Lỗi xác thực plugin" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Siêu dữ liệu phải là đối tượng từ điển của python" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "Phụ trợ siêu dữ liệu" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "Trường siêu dữ liệu JSON, được sử dụng bởi phụ trợ bên ngoài" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "Mẫu được định dạng không thích hợp" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "Khóa định dạng không rõ ràng đã được chỉ định" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "Thiếu khóa định dạng cần thiết" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "Trường tham chiếu không thể rỗng" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "Tham chiếu phải phù hợp với mẫu yêu cầu" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "Số tham chiếu quá lớn" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "Lựa chọn sai" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "Tên" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "Mô tả" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "Mô tả (tùy chọn)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "Đường dẫn" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "Tên trùng lặp không thể tồn tại trong cùng cấp thư mục" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Ghi chú markdown (không bắt buộc)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "Dữ liệu mã vạch" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "Dữ liệu mã vạch của bên thứ ba" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "Dữ liệu băm mã vạch" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "Chuỗi băm duy nhất của dữ liệu mã vạch" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "Mã vạch đã tồn tại" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "Lỗi máy chủ" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "Lỗi đã được ghi lại bởi máy chủ." -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "Hình ảnh" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "Phải là một số hợp lệ" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "Tiền tệ" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "Chọn tiền tệ trong các tùy chọn đang có" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "Giá trị không hợp lệ" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "Sao chép thông số" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "Arabic" @@ -521,46 +574,48 @@ msgstr "Tiếng Trung (Giản thể)" msgid "Chinese (Traditional)" msgstr "Tiếng Trung (Phồn thể)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "Đơn vị vật lý không hợp lệ" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "Mã tiền tệ không hợp lệ" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "Trạng thái đặt hàng" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "Phiên bản cha" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "" msgid "Part" msgstr "Nguyên liệu" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "Danh mục" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "Xây dựng nguồn gốc" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "Đã gán cho tôi" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "Đã gán cho" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "Bạn dựng phải được hủy bỏ trước khi có thể xóa được" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "Vật tư tiêu hao" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "Tuỳ chọn" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "Lắp ráp" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "Đã theo dõi" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "Có thể kiểm tra" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "Đã cấp phát" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "Đã dùng" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "Có sẵn" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "Bật đơn hàng" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "Tạo đơn hàng" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "Địa điểm" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "Tạo đơn hàng" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "Dây chuyền BOM chưa được xác thực" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "Không thể tạo đơn hàng cho hàng hoá đang không hoạt động" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "Không thể tạo đơn hàng cho hàng hoá đang mở khoá" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "Phải chọn người dùng hoặc nhóm" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "Sản phẩm đơn đặt bản dựng không thể thay đổi được" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "Tham chiếu đơn đặt bản dựng" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "Tham chiếu" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "Mô tả ngắn về phiên bạn (Tùy chọn)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "Chọn sản phẩm để xây dựng" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "Tham chiếu đơn đặt bản dựng" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "Địa điểm nguồn" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "Chọn địa điểm để lấy trong kho cho bản dựng này (để trống để lấy từ bất kỳ vị trí kho nào)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "Địa điểm đích" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "Chọn địa điểm nơi hàng hóa hoàn thiện sẽ được lưu kho" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "Xây dựng số lượng" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "Số kho hàng để dựng" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "Những mục hoàn thành" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "Số sản phẩm trong kho đã được hoàn thiện" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "Trnạg thái bản dựng" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "Mã trạng thái bản dựng" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "Mã lô hàng" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "Mã lô cho đầu ra bản dựng này" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "Ngày tạo" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "Ngày hoàn thành mục tiêu" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "Ngày mục tiêu để hoàn thành bản dựng. Bản dựng sẽ bị quá hạn sau ngày này." -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "Ngày hoàn thành" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "hoàn thành bởi" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "Cấp bởi" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "Người dùng người đã được phân công cho đơn đặt bản dựng này" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "Chịu trách nhiệm" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "Người dùng hoặc nhóm có trách nhiệm với đơn đặt bản dựng này" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "Liên kết bên ngoài" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "Liên kết đến URL bên ngoài" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "Độ ưu tiên" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "Độ quan trọng của đơn đặt bản dựng" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "Mã dự án" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "Mã dự án cho đơn đặt bản dựng này" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "Không thể dỡ bỏ tác vụ để hoàn tất phân bổ" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "Đơn đặt bản dựng {build} đã được hoàn thành" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "Một đơn đặt bản dựng đã được hoàn thành" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "Số sê-ri phải được cung cấp cho hàng hoá có thể theo dõi" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "Không có đầu ra bản dựng đã được chỉ ra" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "Đầu ra bản dựng đã được hoàn thiện" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "Đầu ra bản dựng không phù hợp với đơn đặt bản dựng" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "Số lượng phải lớn hơn 0" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "Số lượng không thể lớn hơn số lượng đầu ra" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "Tạo đầu ra {serial} chưa vượt qua tất cả các bài kiểm tra" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "Số lượng có sẵn ({q}) đã bị vượt quá" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "Tạo mục đơn hàng" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "Dựng đối tượng" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "Dựng đối tượng" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "Số lượng" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "Yêu cầu số lượng để dựng đơn đặt" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "Xây dựng mục phải xác định đầu ra, bởi vì sản phẩm chủ được đánh dấu là có thể theo dõi" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "Hàng trong kho đã chọn không phù hợp với đường BOM" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "Số lượng phải là 1 cho kho sê ri" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "Số lượng được phân bổ ({q}) không thể vượt quá số lượng có trong kho ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "Kho hàng đã bị phân bổ quá đà" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "Kho hàng" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "Kho hàng gốc" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "Số lượng kho hàng cần chỉ định để xây dựng" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "Cài đặt vào" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "Kho hàng đích" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "Tạo cấp" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "Tên sản phẩm" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "Đầu ra bản dựng" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "Đầu ra xây dựng không hợp với bản dựng cha" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "Đầu ra sản phẩm không phù hợp với bản dựng đơn đặt hàng" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "Đầu ra bản dựng này đã được hoàn thành" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "Đầu ra bản dựng này chưa được phân bổ đầy đủ" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "Điền số lượng cho đầu ra bản dựng" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "Số lượng nguyên dương cần phải điền cho sản phẩm có thể theo dõi" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "Cần nhập số lượng nguyên dương, bởi vì hóa đơn vật liệu chứa sản phẩm có thể theo dõi" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "Số sê-ri" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "Nhập vào số sêri cho đầu ra bản dựng" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "Vị trí tồn kho cho sản phẩm" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "Số sêri tự cấp" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "Tự động cấp số seri phù hợp cho hàng hóa được yêu cầu" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "Số sêri sau đây đã tồn tại hoặc không hợp lệ" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "Danh sách đầu ra bản dựng phải được cung cấp" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "Vị trí kho cho đầu ra phế phẩm" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "Hủy phân bổ" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "Hủy bất kỳ phân kho nào cho đầu ra phế phẩm" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "Lý do loại bỏ đầu ra bản dựng" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "Vị trí cho đầu ra bản dựng hoàn thiện" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "Chấp nhận phân kho dang dở" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "Hoàn hiện đầu ra nếu kho chưa được phân bổ hết chỗ trống" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "Xử lý phân bổ kho hàng" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "Tiêu thụ bất kỳ hàng tồn kho nào đã được phân bổ cho dự án này." -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "Xóa toàn bộ đầu ra chưa hoàn thành" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "Xóa bất kỳ đầu ra bản dựng nào chưa được hoàn thành" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "Chưa được cấp phép" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "Chấp nhận trạng thái tiêu hao bởi đơn đặt bản dựng này" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "Phân bổ trước khi hoàn thiện đơn đặt bản dựng này" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "Kho quá tải" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "Bạn muốn thế nào để xử lý hàng trong kho được gán thừa cho đơn đặt bản dựng" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "Một vài hàng hóa đã được phân bổ quá thừa" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "Chấp nhận chưa phân bổ được" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "Chấp nhận hàng hóa không được phân bổ đầy đủ vào đơn đặt bản dựng này" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "Kho được yêu cầu chưa được phân bổ hết không gian" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "Chấp nhận không hoàn thành" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "Chấp nhận số yêu cầu của đầu ra bản dựng chưa được hoàn thành" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "Số lượng bản dựng được yêu cầu chưa được hoàn thành" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "Tạo đơn hàng có các đơn hàng đang mở" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "Tạo đơn hàng phải ở trạng thái sản xuất." -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "Đơn đặt bản dựng có đầu ra chưa hoàn thiện" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "Lộ giới" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "Đầu ra bản dựng" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "Đầu ra bản dựng phải chỉ đến bản dựng tương ứng" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "Mục chi tiết bản dựng" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part phải trỏ đến phần tương tự của đơn đặt bản dựng" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "Hàng hóa phải trong kho" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "Số lượng có sẵn ({q}) đã bị vượt quá" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "Đầu ra bản dựng phải được xác định cho việc phân sản phẩm được theo dõi" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "Đầu ra bản dựng không thể chỉ định cho việc phân sản phẩm chưa được theo dõi" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "Hàng hóa phân bổ phải được cung cấp" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "Vị trí kho nơi sản phẩm được lấy ra (để trống để lấy từ bất kỳ vị trí nào)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "Ngoại trừ vị trí" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "Không bao gồm hàng trong kho từ vị trí đã chọn này" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "Kho trao đổi" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "Hàng trong kho thuộc nhiều vị trí có thể dùng thay thế được cho nhau" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "Kho thay thế" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "Cho phép phân kho sản phẩm thay thế" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "Mục tùy chọn" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "Phân bổ các mục hóa đơn vật liệu tùy chọn đến đơn đặt bản dựng" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "BOM liên quan" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "ID hàng hoá BOM" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "Tên hàng hoá BOM" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "Sản phẩm nhà cung cấp" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "Số lượng đã phân bổ" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "Tạo liên quan" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "Tên danh mục hàng hoá" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "Có thể theo dõi" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "Được kế thừa" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "Cho phép biến thể" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "Mục BOM" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "Đang sản xuất" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "Kho ngoài" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "Số hàng tồn" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "Kho hàng thay thế" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "Hàng tồn kho có sẵn" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "Đợi duyệt" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "Sản xuất" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "Chờ" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "Đã hủy" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "Hoàn thành" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "Đơn đặt bản dựng {build} đã được hoàn thành" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "Một đơn đặt bản dựng đã được hoàn thành" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "Kho được yêu cầu cho đặt hàng bản dựng" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "Đơn đặt bản dựng quá hạn" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "Đặt hàng bản dựng {bo} đang quá hạn" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "Đường dẫn" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "File" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "Không có quyền xoá file đính kèm" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "Không có quyền xoá file đính kèm" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "Sai mã tiền tệ" @@ -1539,15 +1641,20 @@ msgstr "Mã tiền tệ không đúng" msgid "No plugin" msgstr "Không phần mở rộng" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "Nhãn mã dự án" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "Đã cập nhật" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "Nhãn thời gian của lần cập cuối cùng" @@ -1567,794 +1674,844 @@ msgstr "Mã dự án duy nhất" msgid "Project description" msgstr "Mô tả dự án" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "Người dùng hoặc nhóm có trách nhiệm với dự án này" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "" - -#: common/models.py:793 -msgid "Settings value" -msgstr "Giá trị cài đặt" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "Giá trị đã chọn không hợp lệ" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "Giá trị phải là kiểu boolean" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "Giá trị phải là một số nguyên dương" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "Chuỗi khóa phải duy nhất" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "Người dùng" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "Số lượng giá phá vỡ" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "Giá" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "Đơn vị giá theo số lượng cụ thể" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "Đầu mối" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "Đầu mối tại điểm webhook được nhận" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "Tên của webhook này" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "Hoạt động" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "Người dùng hoặc nhóm có trách nhiệm với dự án này" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "" + +#: common/models.py:799 +msgid "Settings value" +msgstr "Giá trị cài đặt" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "Giá trị đã chọn không hợp lệ" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "Giá trị phải là kiểu boolean" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "Giá trị phải là một số nguyên dương" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "Chuỗi khóa phải duy nhất" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "Người dùng" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "Số lượng giá phá vỡ" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "Giá" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "Đơn vị giá theo số lượng cụ thể" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "Đầu mối" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "Đầu mối tại điểm webhook được nhận" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "Tên của webhook này" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "Webhook có hoạt động không" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "Chữ ký số" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "Chữ ký số để truy cập" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "Bí mật" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "Mã bí mật dùng chung cho HMAC" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "Mã Tin nhắn" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "Định danh duy nhất cho tin nhắn này" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "Máy chủ" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "Mãy chủ từ tin nhắn này đã được nhận" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "Đầu mục" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "Đầu mục tin nhắn" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "Thân" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "Thân tin nhắn này" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "Đầu mối của tin nhắn này đã nhận được" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "Làm việc vào" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "Công việc trong tin nhắn này đã kết thúc?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "Mã" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "Tiêu đề" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "Liên kết" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "Đã công bố" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "Tác giả" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "Tóm tắt" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "Đọc" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "Tin này đã được đọc?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "Tệp ảnh" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "Tên đơn vị phải là một định danh hợp lệ" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "Tên đơn vị" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "Biểu tượng" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "Biểu tượng đơn vị tùy chọn" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "Định nghĩa" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "Định nghĩa đơn vị" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "Đính kèm" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "Tập tin bị thiếu" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "Thiếu liên kết bên ngoài" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "Chọn file đính kèm" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "Bình luận" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "" -#: common/models.py:2118 -msgid "File size" -msgstr "" - -#: common/models.py:2118 -msgid "File size in bytes" -msgstr "" - -#: common/models.py:2156 common/serializers.py:796 -msgid "Invalid model type specified for attachment" -msgstr "" - -#: common/models.py:2177 -msgid "Custom State" -msgstr "" - #: common/models.py:2178 -msgid "Custom States" +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" msgstr "" #: common/models.py:2183 +msgid "File size" +msgstr "" + +#: common/models.py:2183 +msgid "File size in bytes" +msgstr "" + +#: common/models.py:2219 common/serializers.py:843 +msgid "Invalid model type specified for attachment" +msgstr "" + +#: common/models.py:2303 +msgid "Custom State" +msgstr "" + +#: common/models.py:2304 +msgid "Custom States" +msgstr "" + +#: common/models.py:2309 msgid "Reference Status Set" msgstr "" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "Giá trị" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "Đã tạo" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "Cập nhật lần cuối" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "Mẫu tham số" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "Tham số hộp kiểm tra không thể có đơn vị" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "Tham số hộp kiểm tra không thể có lựa chọn" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "Lựa chọn phải duy nhất" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "Tên tham số mẫu phải là duy nhất" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "Tên tham số" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "Đơn vị" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "Đơn vị vật lý cho tham số này" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "Mô tả tham số" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "Ô lựa chọn" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "Tham số này có phải là hộp kiểm tra?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "Lựa chọn" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "Lựa chọn hợp lệ từ tham số này (ngăn cách bằng dấu phẩy)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "Đã bật" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "Lựa chọn sai cho giá trị tham số" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "Mẫu" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "Dữ liệu" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "Giá trị tham số" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "Ghi chú" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "Trường ghi chú tùy chọn" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "Ngữ cảnh" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "Kết quả" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "Khóa" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} đã bị hủy" msgid "A order that is assigned to you was canceled" msgstr "Một đơn đặt từng được phân công cho bạn đã bị hủy bỏ" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "Mục đã nhận" @@ -2388,104 +2545,100 @@ msgstr "Hàng đã được nhận theo đơn đặt mua" msgid "Items have been received against a return order" msgstr "Hàng đã nhận theo đơn hàng trả lại" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "Đang chạy" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "Công việc chờ xử lý" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "Tác vụ theo lịch" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "Tác vụ thất bại" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "ID tác vụ" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "ID tác vụ duy nhất" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "Khoá" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "Thời gian khóa" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "Tên công việc" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "Chức năng" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "Tên chức năng" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "Đối số" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "Đối số công việc" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "Đối số từ khóa" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "Đối số từ khóa công việc" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "Tên tập tin" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "" - #: common/setting/system.py:97 msgid "No group" msgstr "Không có nhóm" @@ -2614,13 +2767,13 @@ msgstr "Tần suất cập nhật tiền tệ" msgid "How often to update exchange rates (set to zero to disable)" msgstr "Mức độ thường xuyên để cập nhật tỉ giá hối đoái (điền 0 để tắt)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "ngày" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "Phần mở rộng cập nhật tiền tệ được sử dụng" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "" @@ -2760,947 +2921,1017 @@ msgstr "" msgid "Plugin to use for internal barcode data generation" msgstr "" -#: common/setting/system.py:399 -msgid "Part Revisions" -msgstr "Phiên bản Sản phẩm" - -#: common/setting/system.py:400 -msgid "Enable revision field for Part" -msgstr "Bật trường phiên bản cho sản phẩm" - -#: common/setting/system.py:405 -msgid "Assembly Revision Only" -msgstr "" - #: common/setting/system.py:406 -msgid "Only allow revisions for assembly parts" +msgid "Part Locking" msgstr "" -#: common/setting/system.py:411 -msgid "Allow Deletion from Assembly" +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" msgstr "" #: common/setting/system.py:412 +msgid "Part Revisions" +msgstr "Phiên bản Sản phẩm" + +#: common/setting/system.py:413 +msgid "Enable revision field for Part" +msgstr "Bật trường phiên bản cho sản phẩm" + +#: common/setting/system.py:418 +msgid "Assembly Revision Only" +msgstr "" + +#: common/setting/system.py:419 +msgid "Only allow revisions for assembly parts" +msgstr "" + +#: common/setting/system.py:424 +msgid "Allow Deletion from Assembly" +msgstr "" + +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "Mẫu IPN" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "Mẫu dùng nhanh phổ biến dành cho tìm IPN sản phẩm" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "Cho phép trùng IPN" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "Cho phép nhiều sản phẩm dùng IPN giống nhau" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "Cho phép sửa IPN" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "Cho phép đổi giá trị IPN khi sửa một sản phẩm" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "Sao chép dữ liệu BOM của sản phẩm" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "Sao chép dữ liệu BOM mặc định khi nhân bản 1 sản phẩm" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "Sao chép dữ liệu tham số sản phẩm" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "Sao chép dữ liệu tham số mặc định khi nhân bản 1 sản phẩm" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "Chép thông tin kiểm thử sản phẩm" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "Sao chép dữ liệu kiểm thử mặc định khi nhân bản 1 sản phẩm" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "Sao chéo mẫu tham số danh mục" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "Sao chéo mẫu tham số danh mục khi tạo 1 sản phẩm" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "Sản phẩm là mẫu bởi mặc định" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "Sản phẩm có thể lắp giáp từ thành phần khác theo mặc định" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "Thành phần" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "Sản phẩm có thể được sử dụng mặc định như thành phần phụ" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "Có thể mua" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "Sản phẩm mặc định có thể mua được" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "Có thể bán" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "Sản phẩm mặc định có thể bán được" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "Sản phẩm mặc định có thể theo dõi được" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "Ảo" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "Sản phẩm mặc định là số hóa" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "Hiển thị sản phẩm liên quan" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "Hiện sản phẩm liên quan cho 1 sản phẩm" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "Số liệu tồn kho ban đầu" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "Cho phép tạo tồn kho ban đầu khi thêm 1 sản phẩm mới" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "Dữ liệu nhà cung cấp ban đầu" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "Cho phép tạo dữ liệu nhà cung cấp ban đầu khi thêm 1 sản phẩm mới" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "Định dạng tên sản phẩm hiển thị" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "Định dạng để hiển thị tên sản phẩm" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "Biểu tượng mặc định của danh mục sản phẩm" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "Biểu tượng mặc định của danh mục sản phẩm (để trống nghĩa là không có biểu tượng)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "Vị trí phần thập phân giá bán tối thiểu" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "Số vị trí thập phân tối thiểu cần hiển thị khi tạo dữ liệu giá" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "Vị trí phần thập phân giá bán tối đa" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "Số vị trí thập phân tối đa cần hiển thị khi tạo dữ liệu giá" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "Sử dụng giá bán nhà cung cấp" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "Bao gồm giá phá vỡ cả nhà cung cấp trong tính toán giá tổng thể" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "Ghi đè lịch sử mua hàng" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "Giá đơn hàng đặt mua trước đó ghi đè giá phá vỡ của nhà cung cấp" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "Sử dụng giá hàng hóa trong kho" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "Dùng giá bán từ dữ liệu kho nhập vào thủ công đối với bộ tính toán giá bán" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "Tuổi giá kho hàng" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "Loại trừ hàng hóa trong kho cũ hơn số ngày ngày từ bảng tính giá bán" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "Sử dụng giá biến thể" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "Bao gồm giá biến thể trong bộ tính toán giá tổng thể" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "Chỉ các biến thể hoạt động" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "Chỉ sử dụng sản phẩm biến thể hoạt động để tính toán giá bán biến thể" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "Tần suất tạo lại giá" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "Số ngày trước khi giá sản phẩm được tự động cập nhật" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "Giá nội bộ" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "Bật giá nội bộ cho sản phẩm" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "Ghi đè giá nội bộ" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "Nếu khả dụng, giá nội bộ ghi đè tính toán khoảng giá" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "Bật in tem nhãn" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "Bật chức năng in tem nhãn từ giao diện web" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "DPI hỉnh ảnh tem nhãn" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "Độ phân giải DPI khi tạo tệp hình ảnh để cung cấp cho plugin in ấn tem nhãn" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "Bật báo cáo" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "Cho phép tạo báo cáo" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "Chế độ gỡ lỗi" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "Tạo báo cáo trong chế độ gỡ lỗi (đầu ra HTML)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "Khổ giấy" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "Kích thước trang mặc định cho báo cáo PDF" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "Bắt buộc đơn vị tham số" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "Nếu đơn vị được cung cấp, giá trị tham số phải phù hợp với các đơn vị xác định" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "Sê ri toàn cục duy nhất" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "Số sê ri cho hàng trong kho phải là duy nhất trong toàn hệ thống" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "Xóa kho đã hết hàng" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "Mẫu sinh mã theo lô" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "Mẫu tạo mã theo lô mặc định cho hàng trong kho" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "Quá hạn trong kho" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "Bật chức năng quá hạn tồn kho" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "Bán kho quá hạn" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "Cho phép bán hàng kho quá hạn" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "Thời gian hàng cũ trong kho" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "Số ngày hàng trong kho được xác định là cũ trước khi quá hạn" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "Dựng kho quá hạn" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "Cho phép xây dựng với kho hàng quá hạn" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "Kiểm soát sở hữu kho" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "Bật chức năng kiểm soát sở hữu kho với địa điểm và hàng trong kho" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "Biểu tượng địa điểm kho mặc định" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "Biểu tượng địa điểm kho hàng mặc định (trống nghĩa là không có biểu tượng)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "Hiển thị hàng hóa đã lắp đặt" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "Hiển thị hàng trong kho đã được lắp đặt trên bảng kho" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "Mã tham chiếu đơn đặt bản dựng" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "Mẫu bắt buộc cho để trường tham chiếu đơn đặt bản dựng" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "Bật đơn hàng trả lại" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "Bật chức năng đơn hàng trả lại trong giao diện người dùng" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "Mẫu tham chiếu đơn hàng trả lại" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "Sửa đơn hàng trả lại đã hoàn thành" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "Cho phép sửa đơn hàng trả lại sau khi đã hoàn thành rồi" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "Mẫu tham chiếu đơn đặt hàng" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "Mẫu bắt buộc để tạo trường tham chiếu đơn đặt hàng" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "Vận chuyển mặc định đơn đặt hàng" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "Cho phép tạo vận chuyển mặc định với đơn đặt hàng" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "Sửa đơn đặt hàng đã hoàn thành" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "Cho phép sửa đơn đặt hàng sau khi đã vận chuyển hoặc hoàn thành" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "Mẫu tham chiếu đơn đặt mua" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "Mẫu bắt buộc cho để trường tham chiếu đơn đặt mua" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "Sửa đơn đặt mua đã hoàn thành" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "Cho phép sửa đơn đặt mua sau khi đã vận chuyển hoặc hoàn thành" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "Tự động hoàn thành đơn đặt mua" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "" -#: common/setting/system.py:953 -msgid "Enable password forgot" -msgstr "Bật quên mật khẩu" - -#: common/setting/system.py:954 -msgid "Enable password forgot function on the login pages" -msgstr "Bật chức năng quên mật khẩu trong trang đăng nhập" - -#: common/setting/system.py:959 -msgid "Enable registration" -msgstr "Bật đăng ký" - -#: common/setting/system.py:960 -msgid "Enable self-registration for users on the login pages" -msgstr "Cho phép người dùng tự đăng ký tại trang đăng nhập" - -#: common/setting/system.py:965 -msgid "Enable SSO" -msgstr "Bật SSO" - -#: common/setting/system.py:966 -msgid "Enable SSO on the login pages" -msgstr "Cho phép SSO tại trang đăng nhập" - -#: common/setting/system.py:971 -msgid "Enable SSO registration" -msgstr "Bật đăng ký SSO" - -#: common/setting/system.py:973 -msgid "Enable self-registration via SSO for users on the login pages" -msgstr "Cho phép người dùng tự đăng ký SSO tại trang đăng nhập" - -#: common/setting/system.py:979 -msgid "Enable SSO group sync" -msgstr "" - -#: common/setting/system.py:981 -msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" -msgstr "" - -#: common/setting/system.py:987 -msgid "SSO group key" -msgstr "" - -#: common/setting/system.py:988 -msgid "The name of the groups claim attribute provided by the IdP" -msgstr "" - -#: common/setting/system.py:993 -msgid "SSO group map" -msgstr "" - -#: common/setting/system.py:995 -msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." -msgstr "" - -#: common/setting/system.py:1001 -msgid "Remove groups outside of SSO" -msgstr "" - -#: common/setting/system.py:1003 -msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" msgstr "" #: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 +msgid "Enable password forgot" +msgstr "Bật quên mật khẩu" + +#: common/setting/system.py:1017 +msgid "Enable password forgot function on the login pages" +msgstr "Bật chức năng quên mật khẩu trong trang đăng nhập" + +#: common/setting/system.py:1022 +msgid "Enable registration" +msgstr "Bật đăng ký" + +#: common/setting/system.py:1023 +msgid "Enable self-registration for users on the login pages" +msgstr "Cho phép người dùng tự đăng ký tại trang đăng nhập" + +#: common/setting/system.py:1028 +msgid "Enable SSO" +msgstr "Bật SSO" + +#: common/setting/system.py:1029 +msgid "Enable SSO on the login pages" +msgstr "Cho phép SSO tại trang đăng nhập" + +#: common/setting/system.py:1034 +msgid "Enable SSO registration" +msgstr "Bật đăng ký SSO" + +#: common/setting/system.py:1036 +msgid "Enable self-registration via SSO for users on the login pages" +msgstr "Cho phép người dùng tự đăng ký SSO tại trang đăng nhập" + +#: common/setting/system.py:1042 +msgid "Enable SSO group sync" +msgstr "" + +#: common/setting/system.py:1044 +msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" +msgstr "" + +#: common/setting/system.py:1050 +msgid "SSO group key" +msgstr "" + +#: common/setting/system.py:1051 +msgid "The name of the groups claim attribute provided by the IdP" +msgstr "" + +#: common/setting/system.py:1056 +msgid "SSO group map" +msgstr "" + +#: common/setting/system.py:1058 +msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." +msgstr "" + +#: common/setting/system.py:1064 +msgid "Remove groups outside of SSO" +msgstr "" + +#: common/setting/system.py:1066 +msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" +msgstr "" + +#: common/setting/system.py:1072 msgid "Email required" msgstr "Yêu cầu email" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "Yêu cầu người dùng cung cấp email để đăng ký" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "Người dùng tự động điền SSO" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "Tự động điền thông tin chi tiết từ dữ liệu tài khoản SSO" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "Thư 2 lần" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "Khi đăng ký sẽ hỏi người dùng hai lần thư điện tử của họ" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "Mật khẩu 2 lần" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "Khi đăng ký sẽ hỏi người dùng hai lần mật khẩu của họ" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "Các tên miền được phép" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "Cấm đăng ký với 1 số tên miền cụ thể (dấu phẩy ngăn cách, bắt đầu với dấu @)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "Nhóm khi đăng ký" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "Bắt buộc MFA" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "Người dùng phải sử dụng bảo mật đa nhân tố." -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "Kiểm tra phần mở rộng khi khởi động" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "Kiểm tra toàn bộ phần mở rộng đã được cài đặt khi khởi dộng - bật trong môi trường ảo hóa" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "Kiểm tra cập nhật plugin" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "Bật tích hợp URL" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "Bật phần mở rộng để thêm định tuyến URL" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "Bật tích hợp điều hướng" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "Bật phần mở rộng để tích hợp thanh định hướng" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "Bật tích hợp ứng dụng" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "Bật phần mở rộng để thêm ứng dụng" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "Cho phép tích hợp lập lịch" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "Bật phẩn mở rộng để chạy các tác vụ theo lịch" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "Bật tích hợp nguồn cấp sự kiện" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "Bật phần mở rộng để trả lời sự kiện bên trong" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "Ngoại trừ vị trí bên ngoài" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "Giai đoạn kiểm kê tự động" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "Hiển thị tên đầy đủ của người dùng" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "Hiển thị tên đầy đủ thay vì tên đăng nhập" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "Số kết quả cần hiển thị trong từng phần của cửa sổ xem trước tìm kiếm" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "Tìm kiếm biểu thức" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "Bật tìm kiếm biểu thức chính quy trong câu truy vấn tìm kiếm" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "Tìm phù hợp toàn bộ chữ" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "Truy vấn tìm trả về kết quả phù hợp toàn bộ chữ" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Phím escape để đóng mẫu biểu" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "Sử dụng phím escape để đóng mẫu biểu hộp thoại" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "Cố định điều hướng" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "Vị trí thành điều hướng là cố định trên cùng màn hình" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "Định dạng ngày" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "Định dạng ưa chuộng khi hiển thị ngày" -#: common/setting/user.py:227 -msgid "Show Stock History" +#: common/setting/user.py:235 +msgid "Table Preview Panel" msgstr "" -#: common/setting/user.py:228 -msgid "Display stock history information in the part detail page" -msgstr "" - -#: common/setting/user.py:233 -msgid "Show Last Breadcrumb" -msgstr "" - -#: common/setting/user.py:234 -msgid "Show the current page in breadcrumbs" -msgstr "" - -#: common/setting/user.py:239 -msgid "Show full stock location in tables" +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" msgstr "" #: common/setting/user.py:241 -msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgid "Show Stock History" +msgstr "" + +#: common/setting/user.py:242 +msgid "Display stock history information in the part detail page" msgstr "" #: common/setting/user.py:247 -msgid "Show full part categories in tables" +msgid "Show Last Breadcrumb" msgstr "" -#: common/setting/user.py:249 -msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +#: common/setting/user.py:248 +msgid "Show the current page in breadcrumbs" msgstr "" -#: common/setting/user.py:255 -msgid "Show Subassemblies in BOM table" +#: common/setting/user.py:253 +msgid "Show Extra Model Information" msgstr "" -#: common/setting/user.py:256 -msgid "Enable display of subassemblies in the BOM table" +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 +msgid "Show full stock location in tables" msgstr "" #: common/setting/user.py:261 +msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:267 +msgid "Show full part categories in tables" +msgstr "" + +#: common/setting/user.py:269 +msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." +msgstr "" + +#: common/setting/user.py:275 +msgid "Show Subassemblies in BOM table" +msgstr "" + +#: common/setting/user.py:276 +msgid "Enable display of subassemblies in the BOM table" +msgstr "" + +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "Nhận báo cáo lỗi" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "Nhận thông báo khi có lỗi hệ thống" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "Tên miền rỗng là không được phép." -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "Tên miền không hợp lệ: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "Nhà sản xuất" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "Doanh nghiêp" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "" @@ -4123,8 +4387,8 @@ msgstr "Số điện thoại liên hệ" msgid "Contact email address" msgstr "Địa chỉ email liên hệ" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "Liên hệ" @@ -4176,283 +4440,283 @@ msgstr "" msgid "Company Tax ID" msgstr "" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "Địa chỉ" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "Địa chỉ" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "Chọn doanh nghiệp" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "Tiêu đề địa chỉ" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "Tiêu đề mô tả mục địa chỉ" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "Địa chỉ chính" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "Đặt làm địa chỉ chính" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "Dòng 1" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "Địa chỉ dòng 1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "Dòng 2" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "Địa chỉ dòng 2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "Mã bưu chính" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "Thành phố/Vùng" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "Mã bưu chính thành phố/vùng" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "Bang/Tỉnh" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "Bang hay tỉnh" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "Quốc gia" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "Địa chỉ quốc gia" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "Ghi chú vận chuyển" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "Ghi chú dành cho chuyển phát nhanh" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "Ghi chú nội bọ chuyển phát nhanh" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "Ghi chú nội bộ sử dụng cho chuyển phát nhanh" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "Liên kết thông tin địa chỉ (bên ngoài)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "Sản phẩm nhà sản xuất" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "Sản phẩm cơ bản" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "Chọn sản phẩm" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "Chọn nhà sản xuất" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "Mã số nhà sản xuất" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "URL cho liên kết sản phẩm của nhà sản xuất bên ngoài" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "Mô tả sản phẩm của nhà sản xuất" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "Đơn vị đóng gói phải tương thích với đơn vị sản phẩm cơ bản" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "Đơn vị đóng gói phải lớn hơn không" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "Sản phẩm nhà sản xuất đã liên kết phải tham chiếu với sản phẩm cơ bản tương tự" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "Nhà cung cấp" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "Chọn nhà cung cấp" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "Đơn vị quản lý kho nhà cung cấp" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "Chọn sản phẩm của nhà sản xuất" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "URL cho liên kết sản phẩm của nhà cung cấp bên ngoài" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "Mô tả sản phẩm nhà cung cấp" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "chi phí cơ sở" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "Thu phí tối thiểu (vd: phí kho bãi)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "Đóng gói" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "Đóng gói sản phẩm" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "Số lượng gói" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "Tổng số lượng được cung cấp trong một gói đơn. Để trống cho các hàng hóa riêng lẻ." -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "nhiều" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "Đặt hàng nhiều" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "Số lượng có sẵn từ nhà cung cấp" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "Sẵn hàng đã được cập nhật" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "Ngày cập nhật cuối thông tin tồn kho" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "Tiền tệ mặc định được sử dụng cho nhà cung cấp này" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "Còn hàng" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "" @@ -4476,123 +4740,152 @@ msgstr "Đã đặt" msgid "Invalid status code" msgstr "" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "Tập tin dữ liệu" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "Hợp lệ" -#: importer/models.py:846 -msgid "ID is required for updating existing records." +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "" @@ -4600,43 +4893,47 @@ msgstr "" msgid "Failed to open data file" msgstr "" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "" @@ -4672,115 +4969,115 @@ msgstr "" msgid "Data file contains too many rows" msgstr "" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "Không rõ" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "" @@ -4792,7 +5089,7 @@ msgstr "" msgid "Value of the property" msgstr "" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "Nhóm" @@ -4816,117 +5113,118 @@ msgstr "" msgid "Maximum value for progress type, required if type=progress" msgstr "" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "Tham chiếu đơn đặt" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "Tạo bởi" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "Đặt hàng" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "Sản phẩm nội bộ" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "Đã hoàn thành" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "Đơn hàng" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "Đơn hàng" msgid "Sales Order" msgstr "Đơn đặt hàng" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "Đơn hàng trả lại" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "Tổng tiền" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "Tổng tiền cho đơn hàng hàng" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "Tiền tệ đơn đặt hàng" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "Tiền tệ cho đơn đặt này (để trống để sử dụng tiền mặc định)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "Liên hệ không phù hợp với doanh nghiệp đã chọn" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "Mô tả đơn đặt (tùy chọn)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "Mã dự án đã chọn cho đơn đặt hàng này" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "Liên kết đến trang bên ngoài" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "Ngày mục tiêu" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "Ngày mong muốn giao được hàng. Đơn đặt sẽ quá hạn sau ngày này." -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "Ngày phát hành" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "Ngày đặt hàng đã phát hành" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "Người dùng hoặc nhóm có trách nhiệm với đơn đặt này" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "Đầu mối liên hệ của đơn đặt này" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "Địa chỉ công ty cho đơn đặt này" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "Mã đặt hàng" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "Trạng thái" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "Trạng thái đơn đặt mua" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "Doanh nghiệp từ những hàng hóa đang được đặt mua" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "Tham chiếu nhà cung cấp" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "Mã tham chiếu đơn đặt nhà cung cấp" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "nhận bởi" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "Ngày đặt hàng đã được hoàn thiện" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "Đích đến" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "Nhà cung cấp sản phẩm phải trùng với nhà cung cấp PO" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "Mục dòng không phù hợp với đơn đặt mua" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "Số lượng phải là số dương" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "Khách hàng" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "Doanh nghiệp từ những hàng hóa đang được bán" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "Tham chiếu khách hàng " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "Mã tham chiếu đơn đặt của khách hàng" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "Ngày giao hàng" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "vận chuyển bằng" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "Dòng hàng hóa chưa được gắn với đơn đặt này" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "Không tìm thấy số sê ri sau đây" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "Những đơn hàng đang mở thì sẽ được đánh dấu là hoàn thành" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "Đơn hàng không thể hoàn thành được vì vận chuyển chưa xong" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "Đơn hàng không thể hoàn thành được vì những khoản riêng chưa xong" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "Số lượng mặt hàng" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "Tham chiếu khoản riêng" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "Ghi chú khoản riêng" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "Ngày mục tiêu cho khoản riêng này (để trống để sử dụng ngày mục tiêu từ đơn đặt)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "Mô tả khoản riêng (tùy chọn)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "Ngữ cảnh bổ sung" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "Đơn giá" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "Sản phẩm nhà cung cấp phải phù hợp với nhà cung cung cấp" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "Sản phẩm nhà cung cấp" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "Đã nhận" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "Số mục đã nhận" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "Giá mua" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "Giá đơn vị mua" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "Chỉ có thể gán sản phẩm có thể bán vào đơn đặt bán hàng" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "Giá bán" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "Giá bán đơn vị" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "Đã chuyển" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "Số lượng đã vận chuyển" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "Ngày vận chuyển" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "Ngày giao hàng" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "Ngày giao hàng của vận chuyển" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "Kiểm tra bởi" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "Người dùng đã kiểm tra vận chuyển này" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "Vận chuyển" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "Mã vận chuyển" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "Số theo dõi" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "Thông tin theo dõi vận chuyển" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "Mã hóa đơn" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "Số tham chiếu liên kết với hóa đơn" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "Vận đơn đã được gửi đi" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "Vận đơn chưa có hàng hóa được phân bổ" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "Hàng trong kho chưa được giao" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "Không thể phân bổ hàng hóa vào cùng với dòng với sản phẩm khác" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "Không thể phân bổ hàng hóa vào một dòng mà không có sản phẩm nào" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "Số lượng phân bổ không thể vượt quá số lượng của kho" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "Số lượng phân bổ phải lớn hơn 0" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "Số lượng phải là 1 cho hàng hóa sêri" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "Đơn bán hàng không phù hợp với vận đơn" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "Vận đơn không phù hợp với đơn bán hàng" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "Dòng" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "Tham chiếu vận đơn của đơn hàng bán" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "Hàng hóa" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "Chọn hàng trong kho để phân bổ" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "Nhập số lượng phân kho" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "Tham chiếu đơn hàng trả lại" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "Công ty có hàng hóa sẽ được trả lại" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "Trạng thái đơn hàng trả lại" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "Chọn hàng hóa để trả lại từ khách hàng" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "Ngày nhận được" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "Kết quả" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "Kết quả cho hàng hóa dòng này" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "Chi phí gắn với hàng trả lại hoặc sửa chữa cho dòng hàng hóa này" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "" -#: order/serializers.py:76 -msgid "Order ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" +#: order/models.py:3746 +msgid "Transfer order status" msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" +#: order/models.py:3761 +msgid "Source for transferred items" msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" +#: order/models.py:3771 +msgid "Destination for transferred items" msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" +#: order/models.py:3776 +msgid "Consume Stock" msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "Sao chép thông số" - -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" msgstr "" -#: order/serializers.py:112 +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" + +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "Mục dòng" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "" -#: order/serializers.py:185 -msgid "Duplicate Order" +#: order/serializers.py:103 +msgid "Custom Status Key" msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "Tên nhà cung cấp" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "Đơn đặt không thể bị hủy" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "Cho phép đơn đặt phải đóng lại cùng với các mục dòng hàng hóa chưa hoàn thành" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "Đơn đặt có dòng hàng hóa chưa hoàn thành" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "Đơn đặt là không được mở" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "Tiền tệ giá mua" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "Mã sản phẩm nội bộ" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "Sản phẩm nhà cung cấp phải được chỉ định" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "Đơn đặt mua phải được chỉ định" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "Nhà cung cấp phải phù hợp với đơn đặt mua" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "Đơn đặt mua phải phù hợp với nhà cung cấp" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "Mục dòng" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "Chọn vị trí đích cho hàng hóa đã nhận" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "Nhập mã lô cho hàng trong kho đang đến" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "Ngày hết hạn" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "Nhập số sê ri cho hàng trong kho đang đến" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "Mã vạch" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "Mã vạch đã quét" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "Mã vạch đã được dùng" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "Dòng hàng hóa phải được cung cấp" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "Vị trí đích phải được chỉ ra" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "Giá trị mã vạch đã cung cấp phải duy nhất" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "Vận đơn đã hoàn thành" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "Tiền tệ giá bán" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "Chưa cung cấp thông tin vận chuyển" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "Dòng hàng hóa chưa được gắn với đơn đặt này" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "Số lượng phải là số dương" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "Nhập số sê ri để phân bổ" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "Vận đơn đã được chuyển đi" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "Vận đơn không được gắn với đơn đặt này" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "Không tìm thấy số sê ri sau đây" - -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" + +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "Dòng riêng biệt đơn hàng trả lại" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "Line item không phù hợp với đơn hàng trả lại" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "Line item đã nhận được" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "Hàng hóa chỉ có thể được nhận theo đơn hàng đang trong tiến trình" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "Tiền tệ giá đồng hạng" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "Mất" @@ -5718,1279 +6125,1312 @@ msgstr "Mất" msgid "Returned" msgstr "Đã trả lại" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "Đang tiến hành" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "Trả lại" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "Sửa chữa" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "Thay thế" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "Hoàn tiền" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "Từ chối" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "Đã cấp" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "Đơn đặt mua quá hạn" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "Đơn đặt mua {po} quá hạn" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "Đơn bán hàng quá hạn" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "Đơn bán hàng {so} đã quá hạn" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "Danh mục sản phẩm" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "Danh mục sản phẩm" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "Điểm bán mặc định" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "Vị trí mặc định cho sản phẩm trong danh mục này" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "Cấu trúc" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "Hàng hóa không được gán trực tiếp vào danh mục có cấu trúc nhưng có thể được gán vào danh mục con." -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "Từ khóa mặc định" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "Từ khóa mặc định cho sản phẩm trong danh mục này" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "Biểu tượng" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "Biểu tượng (tùy chọn)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "Bạn không thể thay đổi cấu trúc nhóm sản phẩm này vì một số sản phẩm đã được gắn với nó rồi!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "Giá trị mặc định" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "Giá trị tham số mặc định" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "Nguyên liệu" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "Không thể dùng sản phẩm '{self}' trong BOM cho '{parent}' (đệ quy)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "Sản phẩm '{parent}' được dùng trong BOM cho '{self}' (đệ quy)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "IPN phải phù hợp mẫu biểu thức chính quy {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "Hàng trong kho với số sê ri này đã tồn tại" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "IPN trùng lặp không được cho phép trong thiết lập sản phẩm" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "Sản phẩm với Tên, IPN và Duyệt lại đã tồn tại." -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "Sản phẩm không thể được phân vào danh mục sản phẩm có cấu trúc!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "Tên sản phẩm" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "Là Mẫu" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "Sản phẩm này có phải là sản phẩm mẫu?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "Đây có phải là 1 biến thể của sản phẩm khác?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "Biến thể của" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "Mô tả (không bắt buộc)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "Từ khóa" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "Từ khóa sản phẩm để cải thiện sự hiện diện trong kết quả tìm kiếm" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "Danh mục sản phẩm" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "Số phiên bản hoặc bản duyệt lại sản phẩm" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "Phiên bản" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "Hàng hóa này sẽ được cất vào đâu?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "Hết hạn mặc định" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "Thời gian hết hạn (theo ngày) để nhập kho hàng hóa cho sản phẩm này" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "Kho tối thiểu" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "Cấp độ kho tối thiểu được phép" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "Đơn vị đo cho sản phẩm này" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "Sản phẩm này có thể được dựng từ sản phẩm khác?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "Sản phẩm này có thể dùng để dựng các sản phẩm khác?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "Sản phẩm này có đang theo dõi cho hàng hóa duy nhất?" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "Sản phẩm này có thể mua được từ nhà cung ứng bên ngoài?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "Sản phẩm này có thể được bán cho khách hàng?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "Sản phẩm này đang hoạt động?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "Đây là sản phẩm ảo, ví dụ như sản phẩm phần mềm hay bản quyền?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "Giá trị tổng kiểm BOM" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "Giá trị tổng kiểm BOM đã được lưu" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "BOM kiểm tra bởi" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "Ngày kiểm tra BOM" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "Tạo người dùng" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "Trách nhiệm chủ sở hữu cho sản phẩm này" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "Bán nhiều" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "Tiền được dùng để làm đệm tính toán giá bán" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "Chi phí BOM tối thiểu" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "Chi phí thành phần sản phẩm tối thiểu" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "Chi phí BOM tối đa" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "Chi phí thành phần sản phẩm tối đa" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "Chi phí mua vào tối thiểu" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "Chi phí mua vào tối thiểu trong lịch sử" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "Chi phí mua tối đa" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "Chi phí thành phần sản phẩm tối đa trong lịch sử" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "Giá nội bộ tối thiểu" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "Chi phí tối thiểu dựa trên phá vỡ giá nội bộ" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "Giá nội bộ tối đa" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "Chi phí tối đa dựa trên phá vỡ giá nội bộ" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "Giá nhà cung ứng tối thiểu" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "Giá sản phẩm tối thiểu từ nhà cung ứng bên ngoài" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "Giá nhà cung ứng tối đa" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "Giá sản phẩm tối đã từ nhà cung ứng bên ngoài" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "Giá trị biến thể tối thiểu" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "Chi phí tối thiểu của sản phẩm biến thể đã tính" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "Chi phí biến thể tối đa" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "Chi phí tối đa của sản phẩm biến thể đã tính" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "Chi phí tối thiểu" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "Ghi đề chi phí tối thiểu" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "Chi phí tối đa" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "Ghi đề chi phí tối đa" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "Chi phí tối thiểu tính toán tổng thể" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "Chi phí tối đa tính toán tổng thể" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "Giá bán thấp nhất" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "Giá bán tối thiểu dựa trên phá giá" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "Giá bán cao nhất" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "Giá bán cao nhất dựa trên phá giá" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "Chi phí bán hàng tối thiểu" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "Giá bán hàng tối thiểu trong lịch sử" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "Giá bán hàng tối đa" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "Giá bán hàng tối đa trong lịch sử" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "Sản phẩm dành cho kiểm kê" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "Tổng số hàng" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "Số mục kho độc lậo tại thời điểm kiểm kê" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "Tống số kho tại thời điểm kiểm kê" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "Ngày" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "Kiểm kê đã thực hiện" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "Chi phí kho tối thiểu" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "Chi phí kho tối thiểu ước tính của kho đang có" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "Chi phí kho tối đa" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "Chi phí kho tối đa ước tính của kho đang có" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "Tên kiểm thử" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "Nhập tên cho kiểm thử" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "Mô tả kiểm thử" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "Nhập mô tả cho kiểm thử này" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "Bắt buộc" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "Kiểm thử này bắt buộc phải đạt?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "Giá trị bắt buộc" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "Kiểm thử này yêu cầu 1 giá trị khi thêm một kết quả kiểm thử?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "Yêu cầu đính kèm" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "Kiểm thử này yêu cầu tệp đính kèm khi thêm một kết quả kiểm thử?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "Chọn sản phẩm cha" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "Sản phẩm phụ" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "Chọn sản phẩm được dùng trong BOM" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "Số lượng BOM cho mục BOM này" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "Mục BOM này là tùy chọn" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "Mục BOM này bị tiêu hao (không được theo dõi trong đơn đặt bản dựng)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "Tham chiếu mục BOM" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "Ghi chú mục BOM" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "Giá trị tổng kiểm" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "Giá trị tổng kiểm dòng BOM" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "Đã xác minh" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "Mục BOM này là hợp lệ" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "Nhận thừa hưởng" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "Mục BOM này được thừa kế bởi BOM cho sản phẩm biến thể" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "Hàng trong kho cho sản phẩm biến thể có thể được dùng bởi mục BOM này" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "Số lượng phải là giá trị nguyên dùng cho sản phẩm có thể theo dõi được" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "Sản phẩm phụ phải được chỉ định" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "Sảm phẩm thay thế mục BOM" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "Sản phẩm thay thế không thể giống sản phẩm chủ đạo" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "Hàng hóa BOM cha" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "Sản phẩm thay thế" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "Sản phẩm 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "Sản phẩm 2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "Chọn sản phẩm liên quan" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "Không thể tạo mối quan hệ giữa một sản phẩm và chính nó" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "Đã tồn tại mối quan hệ trùng lặp" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "Phụ mục" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "Loại tiền mua hàng của hàng hóa này" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "Sản phẩm gốc" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "Chọn sản phẩm gốc để nhân bản" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "Sao chép ảnh" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "Sao chép hình ảnh từ sản phẩm gốc" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "Sao chép BOM" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "Sao chép định mức nguyên vật liệu từ sản phẩm gốc" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "Sao chép thông tin tham số từ sản phẩm gốc" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "Sao chép ghi chú" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "Sao chép ghi chú từ sản phẩm gốc" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "Số liệu tồn kho ban đầu" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "Chỉ ra số lượng tồn kho ban đầu cho sản phẩm. Nếu điền là không, không thêm kho nào." -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "Vị trí kho ban đầu" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "Chỉ định vị trí kho ban đầu cho sản phẩm này" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "Chọn nhà cung cấp (hoặc để trống để bỏ qua)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "Chọn nhà sản xuất (hoặc để trống để bỏ qua)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "Mã số nhà sản xuất" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "Công ty đã chọn không phải là nhà cung ứng hợp lệ" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "Công ty đã chọn không phải là nhà sản xuất hợp lệ" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "Mã số nhà sản xuất khớp với MPN này đã tồn tại" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "Mã số nhà cung cấp khớp với SKU này đã tồn tại" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "Tên danh mục" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "Đang dựng" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "Hàng trong kho" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "Tổng số lượng" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "Nhân bản sản phẩm" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "Sao chép dữ liệu ban đầu từ sản phẩm khác" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "Sao chép ảnh" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "Sao chép hình ảnh từ sản phẩm gốc" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "Sao chép BOM" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "Sao chép định mức nguyên vật liệu từ sản phẩm gốc" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "Sao chép ghi chú" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "Sao chép ghi chú từ sản phẩm gốc" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "Số liệu kho ban đầu" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "Tạo sản phẩm với số lượng tồn kho ban đầu" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "Thông tin nhà cung cấp" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "Thêm thông tin nhà cung cấp ban đầu cho sản phẩm này" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "Sao chép thông số nhóm hàng" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "Sao chép mẫu tham số từ nhóm sản phẩm được chọn" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "Ảnh hiện có" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "Tên tệp của ảnh sản phẩm hiện hữu" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "Tệp hình ảnh không tồn tại" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "Xác minh toàn bộ hóa đơn vật liệu" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "Có thể dựng" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "Giá thấp nhất" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "Giá trị tính toán ghi đè cho giá tối thiểu" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "Tiền tế giá tối thiểu" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "Giá cao nhất" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "Giá trị tính toán ghi đè cho giá tối đa" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "Tiền tế giá tối đa" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "Cập nhật" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "Cập nhật giá cho sản phẩm này" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "Không thể chuyển đổi từ tiền tệ đã cung cấp cho {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "Giá tối thiểu không được lớn hơn giá tối đa" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "Giá tối đa không được nhỏ hơn giá tối thiểu" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "Chọn sản phẩm để sao chép định mức nguyên vật liệu" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "Xóa dữ liệu đã tồn tại" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "Xóa mục BOM đã tồn tại trước khi sao chép" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "Bao gồm thừa hưởng" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "Bao gồm mục BOM được thừa hưởng từ sản phẩm mẫu" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "Bỏ qua dòng không hợp lệ" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "Bật tùy chọn này để bỏ qua dòng không hợp lệ" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "Sao chép sản phẩm thay thế" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "Sao chép sản phẩm thay thế khi nhân bản hàng hóa BOM" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "Thông báo sắp hết hàng" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "Kho có sẵn cho {part.name} đã mất dưới mức cấu hình tối thiểu" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "" @@ -7011,7 +7451,7 @@ msgstr "" msgid "Installed" msgstr "Đã cài đặt" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "" @@ -7023,23 +7463,23 @@ msgstr "Chưa chỉ ra hành động cụ thể" msgid "No matching action found" msgstr "Không tìm thấy chức năng phù hợp" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "Không tìm thấy dữ liệu mã vạch phù hợp" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "Đã tìm thấy dữ liệu mã vạch phù hợp" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "Mã vạch phù hợp với hàng hóa hiện có" @@ -7055,51 +7495,67 @@ msgstr "Không tìm thấy sản phẩm nhà cung cấp phù hợp" msgid "Multiple matching supplier parts found" msgstr "Tìm thấy nhiều sản phẩm nhà cung cấp phù hợp" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "Sản phẩm nhà cung cấp phù hợp" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "Hàng hóa này đã được nhận" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "Kho không đủ hạn mức khả dụng" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "Không đủ thông tin" @@ -7108,23 +7564,23 @@ msgstr "Không đủ thông tin" msgid "Found matching item" msgstr "" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "Buộc phải nhập thông tin khác để nhận mục dòng này" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "Mục dòng đơn đặt mua đã nhận" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "Cung cấp hỗ trợ gốc cho mã vạch" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" +msgid "Include part variant stock in stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "URL dùng để gửi tin nhắn đến một kênh của Slack" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "Mở liên kết" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "Cung cấp hỗ trợ gốc để in nhãn PDF" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Chế độ gỡ lỗi" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "Bật chế độ gỡ lỗi - trả về mã HTML thuần thay vì PDF" @@ -7653,55 +8117,55 @@ msgstr "" msgid "Options" msgstr "" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "Khổ giấy cho tờ nhãn" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "Bỏ qua nhãn" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "Bỏ qua số nhãn này khi in tờ nhãn" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "Viền" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "In một viền xung quanh từng nhãn" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "Ngang" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "In tờ viền theo khổ giấy nằm ngang" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "Máy in tờ nhãn InvenTree" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "Sắp xếp nhiều nhãn trong một tờ đơn" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "Nhãn quá lớn so với khổ giấy" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "Chưa tạo nhãn nào" @@ -7753,77 +8217,85 @@ msgstr "Cung cấp khả năng quét mã vạch TME" msgid "The Supplier which acts as 'TME'" msgstr "Nhà cung cấp hoạt động như 'TME'" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "Cài đặt phần mở rộng thành công" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "Cài đặt phần bổ sung đến {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "" @@ -7871,25 +8343,25 @@ msgstr "" msgid "Package Plugin" msgstr "" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "Phần bổ sung" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "Không tìm thấy tác giả" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "Phần bổ sung '{p}' không tương thích với phiên bản InvenTree hiện tại {v}" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "Phần bổ sung yêu cầu ít nhất phiên bản {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "Phần bổ sung yêu cầu tối đa phiên bản {v}" @@ -8114,176 +8586,184 @@ msgstr "" msgid "Delete the plugin configuration from the database" msgstr "" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "Pháp lý" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "Thư" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "Tên mẫu" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "Mẫu tên tệp" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "Bộ lọc" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "Khổ giấy cho báo cáo PDF" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "Tạo báo cáo theo hướng ngang" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "Chiều rộng [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "Chiều rộng nhãn, tính theo mm" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "Chiều cao [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "Chiều cao nhãn, tính theo mm" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "Mẫu trích" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "Tệp báo cáo mẫu" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "Mô tả tệp báo cáo mẫu" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "Tài sản" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "Tệp báo cáo tài sản" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "Mô tả tệp báo cáo tài sản" @@ -8291,23 +8771,23 @@ msgstr "Mô tả tệp báo cáo tài sản" msgid "User must be authenticated to save report templates" msgstr "" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "" @@ -8338,13 +8818,10 @@ msgstr "Vật liệu cần có" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "Ảnh sản phẩm" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "Đã cấp" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "Bắt buộc cho" @@ -8380,8 +8857,8 @@ msgstr "Tổng cộng" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "Số sê-ri" @@ -8405,7 +8882,7 @@ msgstr "Báo cáo kiểm thử mặt hàng" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "Mục đã cài đặt" @@ -8438,810 +8915,922 @@ msgstr "Không có kết quả (bắt buộc)" msgid "No result" msgstr "Không có kết quả" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "Không tìm thấy tệp hình ảnh" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "thẻ part_image yêu cầu 1 thực thể sản phẩm" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "thẻ company_image yêu cầu một thực thể doanh nghiệp" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "Mã trạng thái" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "Địa điểm bên ngoài" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "Cây sản phẩm" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "Ngày hết hạn trước đó" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "Ngày hết hạn sau đó" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "Ế" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "Bắt buộc nhập số lượng" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "Phải cung cấp sản phẩm hợp lệ" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "Sản phẩm nhà cung cấp đã đưa không tồn tại" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "Sản phẩm nhà cung cấp có kích thước đóng gói được định nghĩa nhưng cờ use_pack_size chưa được thiết lập" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "Số sê-ri không thê được cung cấp cho sản phẩm không thể theo dõi" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "Loại vị trí kho hàng" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "Loại vị trí kho hàng" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "Biểu tượng mặc định cho vị trí không được đặt biểu tượng (tùy chọn)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "Kho hàng" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "Vị trí kho hàng" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "Chủ sở hữu" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "Chọn chủ sở hữu" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "Không thể đưa trực tiếp hàng trong kho vào bên trong vị trí kho hàng có cấu trúc, nhưng có thể đặt vào kho con." -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "Bên ngoài" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "Đây là vị trí kho bên ngoài" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "Loại vị trí" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "Loại vị trí kho hàng của địa điểm này" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "Bạn không thể chuyển đổi vị trí kho hàng này thành cấu trúc vì đã có hàng hóa trong kho được đặt vào bên trong nó!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "Không thể đặt hàng trong kho vào trong địa điểm kho có cấu trúc!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "Không thể tạo hàng hóa trong kho cho sản phẩm ảo" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "Loại sản phẩm ('{self.supplier_part.part}') phải là {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "Số lượng phải là 1 cho hàng hóa với số sê ri" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "Số sê ri không thể đặt được nếu số lượng lớn hơn 1" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "Hàng hóa không thể thuộc về chính nó" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "Hàng hóa phải có 1 tham chiếu bản dựng nếu is_building=True" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "Tham chiếu bản dựng không thể trỏ vào cùng một đối tượng sản phẩm" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "Hàng trong kho cha" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "Sản phẩm cơ bản" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "Chọn sản phẩm nhà cung cấp khớp với hàng hóa trong kho này" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "Hàng trong kho này được đặt ở đâu?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "Đóng gói hàng hóa này được lưu trữ lại" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "Đã cài đặt trong" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "Mục này đã được cài đặt trong mục khác?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "Số sê ri cho mục này" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "Mã lô cho hàng trong kho này" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "Số lượng tồn kho" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "Bản dựng nguồn" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "Bản dựng cho hàng hóa này" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "Tiêu thụ bởi" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "Đơn đặt bản dựng đã dùng hàng hóa này" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "Đơn đặt mua nguồn" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "Đơn đặt mua cho hàng hóa này" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "Đơn hàng bán đích" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "Ngày hết hạn của hàng hóa này. Kho sẽ được nhắc tình trạng hết hạn sau ngày này" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "Xóa khi thiếu hụt" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "Xóa hàng trong kho này khi kho hàng bị thiếu hụt" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "Giá mua riêng lẻ tại thời điểm mua" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "Đã chuyển đổi sang sản phẩm" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "Chưa đặt sản phẩm thành có thể theo dõi" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "Số lượng phải là số nguyên" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "Số lượng không thể vượt quá số lượng trong kho đang có ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "Số lượng không khớp với số sêri" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "Hàng trong kho đã được gán vào đơn hàng bán" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "Hàng trong kho đã được cài đặt vào hàng hóa khác" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "Hàng trong kho chứa hàng hóa khác" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "Hàng trong kho đã được gắn với một khách hàng" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "Hàng trong kho hiện đang sản xuất" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "Không thể hợp nhất kho nối tiếp" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "Mặt hàng trùng lặp" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "Mặt hàng phải tham chiếu đến sản phẩm tương tự" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "Mặt hàng phải tham chiếu đến sản phẩm nhà cung cấp tương tự" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "Mã trạng thái kho phải phù hợp" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "Không thể xóa mặt hàng không ở trong kho" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "Ghi chú đầu vào" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "Phải cung cấp giá trị cho kiểm thử này" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "Phải tải liên đính kèm cho kiểm thử này" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "Kết quả kiểm thử" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "Giá trị đầu ra kiểm thử" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "Đính kèm kết quả kiểm thử" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "Ghi chú kiểm thử" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "Mục cha" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "Sử dụng kích thước đóng gói khi thêm: Số lượng được định nghĩa là số của gói" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "Điền số sêri cho hàng hóa mới" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "Số hiệu hàng hoá nhà cung cấp" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "Đã hết hạn" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "Mục con" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "Giá mua của mặt hàng, theo đơn vị hoặc gói" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "Nhập số của mặt hàng cần tạo số nối tiếp" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "Số lượng phải không vượt quá số lượng trong kho đang có ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "Vị trí kho đích" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "Không thể gán số sêri cho sản phẩm này" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "Số sêri đã tồn tại" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "Chọn mặt hàng để lắp đặt" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "Số lượng để cài đặt" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "Nhập số lượng hàng hóa để cài đặt" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "Thêm ghi chú giao dịch (tùy chọn)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "Số lượng cần cài đặt phải ít nhất là 1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "Mặt hàng không khả dụng" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "Sản phẩm đã chọn không có trong hóa đơn vật liệu" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "Số lượng cần lắp đặt phải không vượt quá số lượng đang có" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "Vị trí đích cho hàng hóa bị gỡ bỏ" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "Chọn sản phẩm để chuyển đổi mặt hàng vào bên trong" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "Sản phẩm đã chọn không phải là tùy chọn hợp lệ để chuyển đổi" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "Không thể chuyển đổi hàng hóa với sản phẩm nhà cung cấp đã gán" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "Mã trạng thái mặt hàng" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "Chọn sản phẩm để chuyển đổi mặt hàng vào bên trong" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "Sản phẩm đã chọn không phải là tùy chọn hợp lệ để chuyển đổi" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "Không thể chuyển đổi hàng hóa với sản phẩm nhà cung cấp đã gán" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "Chọn mặt hàng để đổi trạng thái" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "Không có mặt hàng nào được chọn" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "Kho phụ" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "Sản phẩm phải có thể bán được" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "Hàng hóa được phân bổ đến một đơn hàng bán" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "Hàng hóa được phân bổ đến một đơn đặt bản dựng" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "Khách hàng được gán vào các mặt hàng" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "Công ty đã chọn không phải là khách hàng" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "Ghi chú phân bổ kho" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "Phải cung cấp danh sách mặt hàng" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "Ghi chú gộp kho" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "Cho phép nhiều nhà cung không khớp" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "Cho phép mặt hàng cùng sản phẩm nhà cung cấp khác phải được gộp" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "Cho phép trạng thái không khớp" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "Cho phép mặt hàng với mã trạng thái khác nhau để gộp lại" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "Cần cung cấp ít nhất hai mặt hàng" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "Giá trị khóa chính mặt hàng" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "Ghi chú giao dịch kho" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "Ghi chú giao dịch kho" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "Kho hàng đã được gộp" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "Đã chuyển đổi sang biến thể" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "Đầu ra đơn đặt bản dựng đã được tạo" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "Đầu ra đơn đặt bản dựng đã hoàn thành" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "Đầu ra đơn đặt bản dựng bị từ chối" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "Tiêu hao bởi đơn đặt bản dựng" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "Vận chyển dựa vào đơn đặt bản dựng" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "Đã nhận dựa vào đơn đặt hàng mua" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "Trả hành dựa vào đơn hàng trả lại" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "Gửi đến khách hàng" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "Bị trả lại từ khách hàng" @@ -9527,19 +10124,19 @@ msgstr "Người dùng" msgid "Select which users are assigned to this group" msgstr "Chọn người dùng được chỉ định cho nhóm này" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "Thông tin cá nhân" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "Quyền" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "Ngày quan trọng" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "Mã thông báo đã bị thu hồi" @@ -9547,279 +10144,283 @@ msgstr "Mã thông báo đã bị thu hồi" msgid "Token has expired" msgstr "Mã thông báo đã hết hạn" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "Mã thông báo API" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "Mã thông báo API" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "Tên mã thông báo" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "Tên tùy chỉnh mã thông báo" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "Ngày hết hạn mã thông báo" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "Xem lần cuối" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "Lần cuối mã thông báo được sử dụng" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "Đã thu hồi" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "Quyền hạn đã đặt" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "Xem" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "Quyền để xem mục" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "Thêm" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "Quyền để thêm mục" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "Đổi" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "Quyển để sửa mục" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "Xóa" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "Quyền để xóa mục" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "Quản trị" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "Đơn mua hàng" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "Đơn hàng bán" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "Đơn hàng trả lại" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "Tên người dùng" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "Tên" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "Họ người dùng" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "Họ" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "Tên người dùng" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "Địa chỉ email của người dùng" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "Superuser" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "Người dùng này là superuser" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "Tài khoản người dùng đang hoạt động" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "Tài khoản của bạn đã được tạo." -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "Xin hãy sử dụng chức năng tạo lại mật khẩu để đăng nhập" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "Chào mừng đến với InvenTree" diff --git a/src/backend/InvenTree/locale/zh_Hans/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/zh_Hans/LC_MESSAGES/django.po index e0f83e84cb..48162b060a 100644 --- a/src/backend/InvenTree/locale/zh_Hans/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/zh_Hans/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "未找到 API 端点" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "批量操作必须提供物料清单" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "必须以列表形式提供项目" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "提供了无效的单位" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "所有过滤器只能使用true" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "没有符合所供条件的项目" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "未提供数据" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "此字段的值必须是唯一的。" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "用户没有权限查阅当前模型。" @@ -65,150 +69,155 @@ msgstr "邮箱地址已确认" msgid "You must type the same email each time." msgstr "您必须每次输入相同的电子邮件。" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "提供的主电子邮件地址无效。" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "提供的邮箱域名未被批准。" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "提供了无效的单位 ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "没有提供数值" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "不能将 {original} 转换到 {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "提供的数量无效" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "在管理面板中可以找到错误详细信息" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "输入日期" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "无效的数值" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "备注" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "值' {name}' 未出现在模式格式中" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "提供的值与所需模式不匹配:" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "无法一次序列化超过 1000 个项目" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "序列号为空白" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "重复的序列号" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "无效群组: {group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "组范围 {group} 超出了允许的数量 ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "未找到序列号" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "唯一序列号 ({n}) 必须匹配数量 ({q})" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "从这个值中删除 HTML 标签" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "数据包含禁止的 markdown 内容" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "无效URL:没有主机名" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "无效URL:无法解析的主机名" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "URL指向私有或保留IP地址" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "太多重定向" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "连接错误" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "服务器响应状态码无效" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "发生异常" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "服务器响应的内容长度值无效" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "图片尺寸过大" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "图片下载超出最大尺寸" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "远程服务器返回了空响应" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "提供的 URL 不是一个有效的图片文件" @@ -216,159 +225,203 @@ msgstr "提供的 URL 不是一个有效的图片文件" msgid "Log in to the app" msgstr "登录应用程序" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "电子邮件" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "CSRF 校验失败。请正确配置 INVENTREE_SITE_URL 与 INVENTREE_TRUSTED_ORIGINS 参数。" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "您必须启用双重身份验证才能进行后续操作。" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "运行插件验证时出错" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "元数据必须是 Python dict 对象" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "插件元数据" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "供外部插件使用的JSON元数据字段" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "格式错误" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "使用了未知的格式键值" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "缺少必需的格式键值" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "参考字段不能为空" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "参考字段必须符合指定格式" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "参考编号过大" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "无效选项" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "名称" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "描述" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "描述(选填)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "路径" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "同一父级下不能存在重复名称" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown备注(选填)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "条码数据" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "第三方条码数据" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "条码哈希值" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "条码数据的唯一哈希值" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "检测到已存在条码" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "服务器错误" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "服务器记录了一个错误。" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "图像" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "必须是有效数字" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "货币" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "从可用选项中选择货币" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "此字段不能为空。" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "无效值" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "无效的内容类型格式" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "未找到内容类型" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "内容类型不匹配所需的 mixin 类" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "复制参数" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "从原始条目复制参数" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "复制行" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "从原始订单复制行项目" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "复制额外行" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "从原始订单复制额外的行项目" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "复制选项" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "指定该条目的克隆选项" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "原始条目" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "选择要克隆的实例" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "阿拉伯语" @@ -521,46 +574,48 @@ msgstr "中文 (简体)" msgid "Chinese (Traditional)" msgstr "中文 (繁体)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "有可用更新" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "InvenTree有可用更新" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "无效的物理单位" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "无效的货币代码" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "订单状态" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "父级生产订单" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "包含变体" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "包含变体" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "包含变体" msgid "Part" msgstr "零件" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "类别" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "可测试部分" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "分配给我" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "负责人" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "创建时间早于" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "创建时间晚于" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "有开始日期" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "开始日期早于" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "开始日期晚于" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "有目标日期" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "目标日期早于" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "目标日期晚于" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "完成日期早于" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "完成日期晚于" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "最小日期" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "最大日期" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "排除树" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "生产订单必须取消后才能删除" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "耗材" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "可选项" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "装配件" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "可追溯" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "需检测" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "未结算订单" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "已分配" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "已消耗" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "可用数量" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "已订购" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "未找到版本" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "生产订单" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "库存位置" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "产出" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "按产出库存项ID筛选,使用“null”查找未安装的生产项。" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "生产订单" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "装配物料清单尚未验证" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "无法为未激活的零件创建生产订单" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "无法为已解锁的零件创建生产订单" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "生产订单仅能通过外部采购可购买零件来完成" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "必须指定负责的用户或组" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "生产订单关联零件不可变更" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "目标日期必须在开始日期之后" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "生产订单编号" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "编号" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "生产订单的简要说明(可选)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "该生产订单所属的上级生产订单" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "选择要生产的零件" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "销售订单编号" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "该生产订单关联的销售订单" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "源库位" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "指定本次生产领料的来源库位(留空可从任意库位调拨)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "外协生产" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "该生产订单由外部供应商完成" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "目标库位" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "选择生产完成品的存放库位" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "生产数量" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "需要生产的库存品数量" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "已完成项目" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "已完成并入库的库存物品数量" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "生产状态" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "生产状态代码" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "批号" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "本批产出的批次编号" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "建立日期" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "生产开始日期" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "此生产订单的计划开始日期" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "计划完成日期" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "生产订单的计划完成时间,逾期后系统将标记为超期。" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "完成日期" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "完成人" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "发起人" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "创建该生产订单的用户" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "责任方" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "该生产订单的责任人或责任团队" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "外部链接" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "指向外部资源的URL链接" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "生产优先级" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "此生产订单的优先级" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "项目编号" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "该生产订单归属的项目编号" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "无法完成生产订单,存在未关闭的子生产订单" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "无法完成生产订单,存在未完成的产出项" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "生产分配任务卸载失败" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "生产订单 {build} 已完成" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "生产订单已完成" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "可追溯零件必须填写序列号" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "未指定产出" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "产出已完成" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "产出与生产订单不匹配" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "数量必须大于零" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "数量不能大于产出数量" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "产出未通过所有必要测试" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "产出 {serial} 未通过所有必要测试" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "已分配的库存物料仍在生产中" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "存在已分配物料时无法部分完成生产输出" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "可用量 ({q}) 超出限制" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "生产订单行项目" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "生产对象" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "生产对象" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "数量" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "生产订单所需数量" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "库存消耗量" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "生产项必须指定产出,因为主零件已经被标记为可追踪的" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "所选库存项与物料清单行项不匹配" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "分配的数量必须大于零" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "序列化物料的数量必须为1" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "分配数量 ({q}) 不得超过可用库存数量 ({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "库存品项超额分配" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "库存项" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "源库存项" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "分配给该生产任务的库存量" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "安裝到" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "目标库存项" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "生产等级" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "零件名称" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "产出" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "生产产出与上级订单不匹配" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "产出零件与生产订单零件不匹配" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "此产出已经完成" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "此产出尚未完全分配" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "输入产出数量" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "可追踪的零件数量必须为整数" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "因为物料清单包含可追踪的零件,所以数量必须为整数" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "序列号" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "输入产出的序列号" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "生产产出的库存地点" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "自动分配序列号" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "自动为所需项目分配对应的序列号" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "以下序列号已存在或无效" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "必须提供产出清单" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "报废品库存地点" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "放弃分配" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "取消对报废产品的库存分配" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "废品产出的原因" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "完工产出存放库位" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "结构型库位不允许存放库存物料" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "接受不完整的分配" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "如果库存尚未全部分配,则完成产出" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "消耗已分配库存" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "立即扣除已分配给该生产任务的库存" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "移除未完成的产出" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "删除所有未完成的产出" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "禁止操作" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "标记为当前生产订单消耗" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "完成此生产订单前取消分配" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "超额分配库存" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "如何处理分配给生产订单的超额库存" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "存在超额分配的库存项" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "接受未分配" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "接受库存项未被完全分配至生产订单" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "必需库存未完成全量分配" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "接受未完工" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "允许所需数量的产出未完成" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "生产需求数量未完成" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "生产订单有打开的子生产订单" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "生产订单必须处于生产状态" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "生产订单有未完成的产出" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "生产行" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "产出" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "生产产出必须指向相同的生产" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "生产行项目" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part 必须与生产订单零件相同" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "项目必须在库存中" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "可用量 ({q}) 超出限制" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "对于被追踪的零件的分配,必须指定生产产出" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "对于未被追踪的零件,无法指定生产产出" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "必须提供分配项目" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "零件来源的库存地点(留空则可来源于任何库存地点)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "排除位置" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "从该选定的库存地点排除库存项" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "可互换库存" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "在多个位置的库存项目可以互换使用" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "替代品库存" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "允许分配可替换的零件" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "可选项目" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "分配可选的物料清单给生产订单" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "所有物料" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "未跟踪的物品" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "已跟踪的物品" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "物品类型" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "选择要自动分配的条目类型" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "库存优先级" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "匹配库存物料的优先消耗顺序" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "产线" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "仅分配物料至指定产线(留空则允许分配至全部产线)" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "物料清单参考" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "物料清单零件识别号码" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "物料清单零件名称" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "安裝到" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "生产" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "供应商零件" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "已分配数量" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "生产订单编号" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "零件类别名称" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "可追踪" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "已继承的" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "允许变体" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "物料清单项" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "生产中" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "生产计划" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "外部库存" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "可用库存" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "可用的替代品库存" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "可用的变体库存" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "消耗数量超过分配数量" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "库存消耗可选备注" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "生产物料项必须关联到正确的生产订单" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "重复的生产物料项分配" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "订单行项目必须关联到正确的生产订单" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "重复的订单行项目分配" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "必须提供至少一个物料项或行项目" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "待生产" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "生产中" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "已暂停" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "已取消" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "完成" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "生产订单 {build} 已完成" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "生产订单已完成" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "生产订单所需库存" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "生产订单{build}需补充库存" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "逾期的生产订单" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "生产订单 {bo} 现已逾期" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "存在缩略图" + +#: common/api.py:773 msgid "Is Link" msgstr "是否链接" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "是否为文件" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "用户没有权限删除此附件" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "用户没有编辑此附件的权限" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "用户没有权限删除此附件" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "选择列表已锁定" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "无效的货币代码" @@ -1539,15 +1641,20 @@ msgstr "未提供有效的货币代码" msgid "No plugin" msgstr "暂无插件" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "标签" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "项目编号标签" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "已是最新" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "最后更新时间戳" @@ -1567,794 +1674,844 @@ msgstr "唯一项目编码" msgid "Project description" msgstr "项目描述" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "负责此项目的用户或团队" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "设置密钥" - -#: common/models.py:793 -msgid "Settings value" -msgstr "设定值" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "所选值不是一个有效的选项" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "该值必须是布尔值" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "该值必须为整数" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "必须是有效数字" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "值未通过验证检查" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "键字符串必须是唯一的" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "使用者" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "批发价数量" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "价格" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "指定数量的单位价格" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "端点" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "接收此网络钩子的端点" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "此网络钩子的名称" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "激活" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "此项目编码是否启用?" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "负责此项目的用户或团队" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "设置密钥" + +#: common/models.py:799 +msgid "Settings value" +msgstr "设定值" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "所选值不是一个有效的选项" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "该值必须是布尔值" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "该值必须为整数" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "必须是有效数字" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "值未通过验证检查" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "键字符串必须是唯一的" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "使用者" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "批发价数量" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "价格" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "指定数量的单位价格" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "端点" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "接收此网络钩子的端点" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "此网络钩子的名称" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "网络钩子是否已启用" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "令牌" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "访问令牌" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "密钥" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "HMAC共享密钥" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "消息ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "此邮件的唯一标识符" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "主机" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "接收此消息的主机" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "标题" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "此消息的标题" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "正文" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "此消息的正文" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "接收此消息的终点" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "工作于" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "这条消息的工作完成了吗?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "标识" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "标题" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "链接" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "已发布" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "作者" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "摘要" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "阅读" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "这条新闻被阅读了吗?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "图像文件" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "此图像的目标模型类型" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "此图像的目标型号ID" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "自定义单位" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "单位符号必须唯一" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "单位名称必须是有效的标识符" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "单位名称" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "符号" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "可选单位符号" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "定义" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "单位定义" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "附件" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "缺少文件" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "缺少外部链接" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "没有要重命名的文件" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "文件名不能为空" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "无效的文件名" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "无法更改文件扩展名" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "已存在同名文件" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "重命名文件保存失败" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "模型类型" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "图片的目标模型类型" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "选择附件" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "缩略图" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "该附件对应的缩略预览图" + +#: common/models.py:2155 msgid "Comment" msgstr "备注" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "附件备注" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "上传日期" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "上传文件的日期" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "是否为图片文件" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "若该附件是合法图片文件,则值为 True(是)" + +#: common/models.py:2183 msgid "File size" msgstr "文件大小" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "文件大小,以字节为单位" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "为附件指定的模型类型无效" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "自定状态" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "定制状态" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "参考状态设置" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "使用此自定义状态扩展状态的状态集" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "逻辑密钥" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "等同于商业逻辑中自定义状态的状态逻辑键" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "值" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "将保存至模型数据库的数值" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "状态名" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "标签" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "将在前端显示的标签" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "颜色" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "将在前端显示颜色" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "型号" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "该状态关联的模型" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "必须选定模型" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "必须选取密钥" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "必须选中逻辑密钥" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "密钥必须不同于逻辑密钥" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "必须提供有效的参考状态类" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "密钥必须不同于参考状态的逻辑密钥" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "逻辑密钥必须在参考状态的逻辑键中" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "名称必须不同于参考状态的名称" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "选择列表" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "选择列表" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "选择列表的名称" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "选择列表的描述" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "已锁定" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "此选择列表是否已锁定?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "能否使用此选择列表?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "源插件" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "提供选择列表的插件" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "源字符串" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "可选字符串,用于标识本列表的数据来源" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "缺省项" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "本选择列表的默认选项" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "已创建" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "选择列表的创建日期和时间" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "最近更新" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "选择列表的最后更新时间" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "选择列表项" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "选择列表项" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "此选项归属的选择列表" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "选择列表项的值" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "选择列表项的标签" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "选择列表项的描述" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "该选择列表项是否处于激活状态?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "参数模板" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "参数模板" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "勾选框参数不能有单位" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "复选框参数不能有选项" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "选择必须是唯一的" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "参数模板名称必须是唯一的" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "此参数模板的目标模型类型" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "参数名称" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "单位" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "此参数的物理单位" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "参数说明" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "勾选框" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "此参数是否为勾选框?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "选项" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "此参数的有效选择 (逗号分隔)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "此参数的选择列表" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "已启用" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "此参数模板是否启用?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "参数" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "参数" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "无效的参数值选择" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "为附件指定的模型类型无效" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "型号ID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "此参数的目标模型的 ID" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "模板" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "参数模板" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "数据" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "参数值" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "备注" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "可选注释字段" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "扫描条码" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "条码数据" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "扫描条码的用户" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "时间戳" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "扫描条形码的日期和时间" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "处理条码的 URL 端点" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "上下文" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "扫描条形码的上下文数据" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "响应" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "扫描条形码的响应数据" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "结果" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "条码扫描成功吗?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "发生错误" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8:邮件日志删除受保护。需设置 INVENTREE_PROTECT_EMAIL_LOG 为 False 以允许删除。" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "电子邮件信息" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "电子邮箱信息" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "已发布" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "已发送" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "失败" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "已送达" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "已确认" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "入站" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "出站" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "暂无回复消息" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "跟踪交付" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "已读追踪" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "点击追踪" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "全局ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "此消息的标识符 (可能由外部系统提供)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "主题 ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "此消息主题的标识符 (可能由外部系统提供)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "主题" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "链接到此消息的主题" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "优先" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "邮件主题" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "邮件主题" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "键" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "此主题的唯一密钥 (用于识别主题)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "此主题的唯一标识符" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "内部服务已启动" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "该线程是否为内部启动的?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "创建主题的日期和时间" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "主题最后更新的日期和时间" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} 已取消" msgid "A order that is assigned to you was canceled" msgstr "分配给您的订单已取消" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "收到的物品" @@ -2388,104 +2545,100 @@ msgstr "已根据采购订单收到物品" msgid "Items have been received against a return order" msgstr "已收到退货订单中的物品" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "指示是否更改此设置需要确认" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "此设置需要确认后才能更改。请确认更改。" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "表示设置是否被环境变量覆盖" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "覆盖" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "正在运行" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "等待完成的任务" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "预定的任务" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "失败的任务" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "任务ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "唯一任务ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "锁定" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "锁定时间" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "任务名称" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "功能" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "功能名称" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "参数" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "任务参数" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "关键字参数" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "任务关键词参数" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "文件名" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "模型类型" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "用户无权为此模式创建或编辑附件" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "用户没有权限为此模型创建或编辑参数" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "选择列表已锁定" - #: common/setting/system.py:97 msgid "No group" msgstr "无分组" @@ -2614,13 +2767,13 @@ msgstr "货币更新间隔时间" msgid "How often to update exchange rates (set to zero to disable)" msgstr "检查更新的频率(设置为零以禁用)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "天" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "使用货币更新插件" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "上传文件大小限制" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "图片与各类文件允许上传的最大容量" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "严格的 URL 验证" @@ -2760,947 +2921,1017 @@ msgstr "条形码生成插件" msgid "Plugin to use for internal barcode data generation" msgstr "用于内部条形码数据生成的插件" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "零件锁定" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "启动零件锁定功能,禁止对零件信息进行修改" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "零件修订" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "启用零件修订字段" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "仅限装配修订版本" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "仅允许对装配零件进行修订" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "允许从装配中删除" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "允许删除已在装配中使用的零件" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN(内部零件号)正则规则" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "用于匹配IPN(内部零件号)格式的正则表达式" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "允许重复的 IPN(内部零件号)" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "允许多个零件共享相同的 IPN(内部零件号)" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "允许编辑 IPN(内部零件号)" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "允许编辑零件时更改IPN(内部零件号)" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "复制零件物料清单数据" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "复制零件时默认复制物料清单数据" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "复制零件参数数据" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "复制零件时默认复制参数数据" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "复制零件测试数据" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "复制零件时默认复制测试数据" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "复制类别参数模板" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "创建零件时复制类别参数模板" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "零件默认为模板" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "默认情况下,元件可由其他零件组装而成" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "组件" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "默认情况下,零件可用作子部件" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "可购买" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "默认情况下可购买零件" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "可销售" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "零件默认为可销售" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "默认情况下可跟踪零件" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "虚拟的" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "默认情况下,零件是虚拟的" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "显示关联零件" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "显示零件的关联零件" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "允许创建初始库存" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "允许在添加新零件时创建初始库存数据" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "允许创建供应商数据" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "允许在添加新零件时创建初始供应商数据" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "零件名称显示格式" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "显示零件名称的格式" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "零件类别默认图标" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "零件类别默认图标 (空表示没有图标)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "最小定价小数位数" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "呈现定价数据时显示的最小小数位数" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "最大定价小数位数" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "呈现定价数据时显示的最大小数位数" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "使用供应商定价" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "将供应商的批发价纳入整体价格计算" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "采购历史价优先" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "当存在历史采购订单价格时,将忽略供应商的批发价" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "使用库存项定价" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "使用手动输入的库存数据进行定价计算" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "库存项目定价时间" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "从定价计算中排除超过此天数的库存项目" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "使用变体定价" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "将产品变体的特殊定价纳入整体价格计算" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "仅限活跃变体" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "仅使用活跃变体零件计算变体价格" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "自动更新定价" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "当内部数据变化时自动更新零件价格" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "价格重建间隔" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "零件价格自动更新前的天数" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "内部价格" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "为零件启用内部核算价格功能" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "内部价格优先" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "若存在内部价格,将覆盖BOM价格区间计算结果" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "允许BOM数量为零" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "允许 BOM 物料项的数量为零。启用后可使用装配 / 设置数量定义单次构建所需用量,与构建总数量无关" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "启用标签打印功能" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "启用从网络界面打印标签" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "标签图片 DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "生成图像文件以供标签打印插件使用时的 DPI 分辨率" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "启用报告" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "启用报告生成" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "调试模式" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "以调试模式生成报告(HTML 输出)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "报表URL地址拉取" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "生成报表时允许拉取远程链接资源" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "日志错误报告" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "记录生成报告时出现的错误" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "页面大小" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "PDF 报告默认页面大小" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "强制参数单位" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "如果提供了单位,参数值必须与指定的单位匹配" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "全局唯一序列号" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "库存项的序列号必须全局唯一" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "删除已耗尽的库存" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "设置库存耗尽时的默认行为" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" -msgstr "" +msgstr "允许编辑序列号" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" -msgstr "" +msgstr "允许编辑库存货品的序列号" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "删除序列化库存" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "允许删除带有序列号的库存商品" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "批号模板" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "为库存项生成默认批号的模板" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "库存过期" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "启用库存过期功能" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "销售过期库存" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "允许销售过期库存" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "库存临期预警天数" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "库存项过期前被标记为\"临期\"的天数" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "允许使用过期库存" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "允许在生产中使用已过期的库存" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "库存所有权管控" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "启用对库存地点和库存物品的归属权管理" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "库存地点默认图标" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "库存地点默认图标 (空表示没有图标)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "显示已安装的库存项" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "在库存列表中显示已被安装到设备中的库存项" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "在安装项目时检查物料清单" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "已安装的库存项目必须存在于上级零件的物料清单中" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "允许零库存调拨" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "允许对当前库存量为零的物品执行库位间调拨操作" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "调拨库存时,默认将货品合并至现有同批次库存" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "调拨库存合并功能的默认状态。(如需,可在单次调拨操作时单独修改)" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "生产订单参考模式" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "生成生产订单参考字段所需的模式" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "要求负责人" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "必须为每个订单分配一个负责人" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "需要活动零件" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "防止为非活动零件创建生产订单" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "需要锁定零件" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "防止为未锁定的零件创建生产订单" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "需要有效的物料清单" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "除非物料清单已验证,否则禁止创建生产订单" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "需要关闭子订单" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "在所有子订单关闭之前,阻止生产订单的完成" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "外部生产订单" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "启用外部生产订单功能" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "需要外部生产订单" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "从外部供应商订购组装好的零件时,需要外部生产订单" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "阻止直到测试通过" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "在所有必要的测试通过之前,阻止产出完成" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "启用订单退货" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "在用户界面中启用订单退货功能" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "退货订单参考模式" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "生成退货订单参考字段所需的模式" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "编辑已完成的退货订单" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "允许编辑已完成的退货订单" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "销售订单参考模式" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "生成销售订单参考字段所需参照模式" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "销售订单默认配送方式" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "启用创建销售订单的默认配送功能" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "编辑已完成的销售订单" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "允许在订单配送或完成后编辑销售订单" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "货件需核对" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "只有所有物品均经核对,才能确认发货完成" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "标记该订单为已完成?" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "标记为已发货的销售订单将自动完成,绕过“已发货”状态" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "启用库存调拨单" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "在操作界面中启用库存调拨单功能" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "调拨单号编码规则" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "生成调拨单编号字段所需的编码格式模板" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "阻止未完成项目测试" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "如果所需的物料测试未完成,则阻止将库存物料分配给销售订单" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "采购订单参考模式" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "生成采购订单参考字段所需的模式" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "编辑已完成的采购订单" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "允许在采购订单已配送或完成后编辑订单" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "货币转换" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "收货时将物料价值折算为基准货币" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "自动完成采购订单" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "当收到所有行项目时,自动将采购订单标记为完成" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "忘记启用密码" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "在登录页面上启用忘记密码功能" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "启用注册" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "在登录页面为用户启用自行注册功能" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "启用SSO登录" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "在登录页面启用单点登录(SSO)功能" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "启用SSO注册" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "允许用户通过登录页面的SSO系统注册账号" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "启用SSO组同步" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "启用后,将自动同步InvenTree用户组与身份提供商(IdP)提供的用户组" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "SSO组属性键" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "身份提供商(IdP)返回的组信息声明属性名称" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "SSO组映射关系" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "将SSO用户组映射到本地InvenTree用户组的对应关系表。如果本地组不存在,系统会自动创建对应的用户组。" -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "移除非SSO来源的用户组" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "当用户组未被身份提供商(IdP)支持时,是否移除该用户组。禁用此选项可能导致安全风险" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "必须提供邮箱" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "用户注册时必须提供邮箱" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "自动填充SSO用户信息" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "自动从SSO账户数据中填充用户详细信息" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "发两次邮件" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "注册时询问用户他们的电子邮件两次" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "两次输入密码" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "当注册时请用户输入密码两次" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "域名白名单" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "限制注册到某些域名 (逗号分隔,以 @ 开头)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "注册默认分组" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "新用户注册时被分配的默认用户组。 如果启用了SSO组同步功能,当无法从身份提供商(IdP)分配组时才会应用此分组。" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "强制启用多因素安全认证" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "用户必须使用多因素安全认证。" -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "启用此设置将要求所有用户设置多元素认证。所有会话将立即断开连接。" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "启动时检查插件" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "启动时检查全部插件是否已安装 - 在容器环境中启用" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "检查插件更新" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "启用定期检查已安装插件的更新" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "启用统一资源定位符集成" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "启用插件以添加统一资源定位符路由" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "启用导航集成" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "启用插件以集成到导航中" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "启用应用集成" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "启用插件添加应用" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "启用调度集成" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "启用插件来运行预定任务" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "启用事件集成" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "启用插件响应内部事件" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "启用界面集成" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "启用插件集成到用户界面" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "启用邮件集成" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "启用插件来处理发送/接收邮件" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "启用项目编码" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "启用项目编码来跟踪项目" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "启用盘点" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "启用历史库存水平及价值记录功能" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "排除外部地点" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "将外部库位的库存物料排除在盘点计算之外" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "自动盘点周期" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "自动库存盘点记录的间隔天数" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "删除旧的盘点记录条目" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "删除超过指定天数的库存盘点记录" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "库存盘点记录删除周期" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "库存盘点记录将在指定天数后自动删除" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "删除旧的库存跟踪记录" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "删除超过指定天数的库存跟踪记录" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "库存跟踪记录删除周期" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "库存跟踪记录将在指定天数后自动删除" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "显示用户全名" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "显示用户全名而不是用户名" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "显示用户配置" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "在用户个人资料页展示其档案信息" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "一周从……开始" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "星期几的起始日,用于在日历视图中显示" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "星期天" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "星期一" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "星期二" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "星期三" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "星期四" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "星期五" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "星期六" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "日历时间跨度" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "日历视图中需展示的未来月份数量" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "个月" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "启用测试站数据" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "启用测试站数据收集以获取测试结果" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "启用设备状态检测" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "启用定期 Ping 检测,确认注册设备的运行状态" @@ -3881,215 +4112,248 @@ msgid "Number of results to show in each section of the search preview window" msgstr "在搜索预览窗口的每个部分中显示的结果数" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "正则表达式搜索" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "在搜索查询中启用正则表达式" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "整词搜索" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "搜索查询返回整词匹配的结果" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "搜索注释" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "搜索查询返回匹配结果的项目注释" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Esc键关闭窗体" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "使用ESC键关闭模态窗体" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "固定导航栏" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "导航栏位置固定在屏幕顶部" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "固定表格表头" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "表格表头固定于表格顶部" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "显示Spotlight(聚焦搜索)" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "启用聚焦导航功能" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "导航图标" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "在导航栏中显示图标" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "时间格式" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "显示时间的首选格式" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "表格预览面板" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "在表格中选中条目时显示预览面板" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "显示库存历史" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "在零件详情页显示库存历史信息" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "仅展示末尾导航项" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "在导航栏中显示当前页面" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "显示模型扩展信息" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "在模型选择下拉框中展示扩展附加信息" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "在表格中显示完整库存位置信息" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "禁用时:完整路径以悬停提示框形式显示。\n" "启用时:完整路径以纯文本形式显示。" -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "在表格中显示完整的零件类别" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "禁用时:完整分类路径以悬停提示框形式显示。\n" "启用时:完整分类路径以纯文本形式显示。" -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "在物料清单表中显示子装配" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "启用物料清单表中的子装配显示" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "接收错误报告" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "接收系统错误通知" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "上次使用的打印设备" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "为用户保存上次使用的打印设备" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "最终级别的展示项目" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "对于没有子项的位置或类别,自动默认显示项目/零件,而不是子级别" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "全部型号" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "未提供附件型号" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "附件模型类型无效" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "文件大小超出最大上传限制,上限为 {max_size} MB" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "文件名无效" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "最小位置不能大于最大位置" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "最大名额不能小于最小名额" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "不允许空域。" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "无效的域名: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "值必须大写" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "值必须是一个有效的变量标识符" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "零件已激活" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "制造商处于活动状态" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "供应商零件处于激活状态" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "主供应商部件" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "内部零件已激活" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "供应商已激活" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "制造商" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "公司" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "有库存" @@ -4125,8 +4389,8 @@ msgstr "联系电话" msgid "Contact email address" msgstr "联系人电子邮箱地址" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "联系人" @@ -4178,283 +4442,283 @@ msgstr "税号" msgid "Company Tax ID" msgstr "公司税号" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "地址" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "地址" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "选择公司" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "地址标题" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "描述地址条目的标题" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "主要地址" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "设置主要地址" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "第1行" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "地址行1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "第2行" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "地址行2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "邮政编码" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "城市/地区" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "邮政编码城市/地区" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "省/市/自治区" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "省、自治区或直辖市" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "国家/地区" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "地址所在国家" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "快递运单" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "运输快递注意事项" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "内部装运通知单" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "内部使用的装运通知单" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "链接地址信息 (外部)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "制造商零件" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "基础零件" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "选择零件" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "选择制造商" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "制造商零件编号" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "制造商零件编号" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "外部制造商零件链接的URL" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "制造商零件说明" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "包装单位必须与基础零件单位兼容" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "包装单位必须大于零" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "链接的制造商零件必须引用相同的基础零件" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "供应商" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "选择供应商" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "供应商库存管理单位" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "此供应商零件是否处于活动状态?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "主要的" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "这是否为关联物料的主供应商物料?" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "选择制造商零件" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "外部供应商零件链接的URL" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "供应商零件说明" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "基本费用" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "最低费用(例如库存费)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "打包" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "零件打包" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "包装数量" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "单包供应的总数量。为单个项目留空。" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "多个" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "订购多个" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "供应商提供的数量" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "可用性已更新" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "上次更新可用性数据的日期" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "供应商批发价" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "此供应商使用的默认货币" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "公司名称" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "有库存" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "批发价" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "美化名称" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "数据导出过程中发生错误" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "数据导出插件返回的数据格式不正确" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "导出格式" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "选择导出文件格式" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "导出插件" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "选择导出插件" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "此项目的附加状态信息" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "自定义状态密钥" @@ -4478,123 +4742,152 @@ msgstr "放置" msgid "Invalid status code" msgstr "无效状态码" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "数据文件" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "要导入的数据文件" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "列" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "本次导入会话的目标模型类型" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "导入状态" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "字段默认值" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "字段覆盖" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "字段筛选器" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "更新现有记录" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "若启用,现有记录将被新数据更新" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "某些必填字段尚未映射" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "已完成条目数量历史记录" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "条目数量历史记录" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "记录的现有数据库标识符" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "列已映射到数据库字段" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "字段已映射到数据列" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "列映射必须链接到有效的导入会话" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "数据文件中不存在列" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "目标模型中不存在字段" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "所选字段为只读" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "查找字段仅支持设置关联(外键)字段" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "查找字段无效,可用选项:{options}" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "导入会话" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "字段" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "列" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "查找字段" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "用于外键检索的数据库字段,留空则自动检索。" + +#: importer/models.py:674 msgid "Row Index" msgstr "行索引" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "原始行数据" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "错误" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "有效" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "更新现有记录需要提供ID。" +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "匹配到多条结果,请确保该值唯一,或指定专用查找字段" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "没有找到与提供的ID相关的记录" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "提供的ID格式无效" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "更新现有记录需要提供ID。" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "不支持的数据文件格式" @@ -4602,43 +4895,47 @@ msgstr "不支持的数据文件格式" msgid "Failed to open data file" msgstr "打开数据文件失败" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "数据文件维度无效" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "字段默认值无效" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "无效的字段覆盖" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "字段筛选器无效" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "行" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "要接受的行ID列表" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "未提供行" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "行不属于此会话" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "行包含无效数据" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "行已完成" @@ -4674,115 +4971,115 @@ msgstr "数据文件包含的列太多" msgid "Data file contains too many rows" msgstr "数据文件包含的行太多" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "值必须是有效的字典对象" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "拷贝" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "每个标签要打印的份数" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "已连接" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "未知" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "正在打印" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "警告" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "无媒体" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "卡纸" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "已断开连接" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "错误" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "标签打印机" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "直接打印各种物品的标签。" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "打印机位置" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "将打印机定位到特定位置" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "设备名称" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "设备类型" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "设备类型" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "驱动" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "设备使用的驱动器" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "可以禁用设备" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "可用驱动" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "无错误" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "已初始化" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "设备状态" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "设备" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "设备配置" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "配置类型" @@ -4794,7 +5091,7 @@ msgstr "属性键" msgid "Value of the property" msgstr "属性值" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "组" @@ -4818,117 +5115,118 @@ msgstr "最大进度" msgid "Maximum value for progress type, required if type=progress" msgstr "进度类型的最大值。当 type=progress 时为必填项" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "订单参考" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "未完成" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "有项目编码" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "创建人" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "创建时间早于" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "创建时间晚于" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "有开始日期" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "开始日期早于" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "开始日期晚于" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "有目标日期" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "目标日期早于" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "目标日期晚于" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "更新时间早于" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "更新时间晚于" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "有定价" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "完成时间早于" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "完成时间晚于" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "外部生产订单" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "订单" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "订单完成" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "内部零件" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "订单待定" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "已完成" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "有配送" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "未找到发货记录" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "采购订单" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4936,782 +5234,891 @@ msgstr "采购订单" msgid "Sales Order" msgstr "销售订单" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "退货订单" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "调拨单" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "总价格" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "此订单的总价" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "订单货币" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "此订单的货币 (留空以使用公司默认值)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "该订单已锁定,不可修改" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "联系人与所选公司不匹配" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "开始日期必须早于目标日期" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "地址与所选公司不匹配" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "订单描述 (可选)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "为此订单选择项目编码" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "链接到外部页面" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "开始日期" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "本订单的预定开始日期" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "预计日期" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "订单交付的预期日期。订单将在此日期后过期。" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "签发日期" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "订单发出日期" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "更新时间" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "负责此订单的用户或组" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "此订单的联系人" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "此订单的公司地址" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "订单参考" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "狀態" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "采购订单状态" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "订购物品的公司" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "供应商参考" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "供应商订单参考代码" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "接收人" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "订单完成日期" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "目的地" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "接收物品的目标" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "零件供应商必须与采购订单供应商匹配" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "行项目与采购订单不匹配" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "行项目缺少关联零件" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "数量必须是正数" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "序列号不能分配给虚拟件" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "允许选用所有库存(含序列号物料与无序列号物料)" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "仅序列号库存" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "仅无序列号库存" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "客户" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "出售物品的公司" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "销售订单状态" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "客户参考 " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "客户订单参考代码" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "发货日期" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "发货人" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "行项目与此订单不关联" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "未找到以下序列号的匹配项" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "以下序列号不可用" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "订单已完成" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "订单已取消" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "只有未结订单才能标记为已完成" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "由于发货不完整,订单无法完成" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "由于缺货,订单无法完成" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "订单无法完成,因为行项目不完整" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "订单已锁定,不可修改" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "项目数量" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "行号" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "此项目的行号(可选)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "行项目参考" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "行项目注释" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "此行项目的目标日期 (留空以使用订单中的目标日期)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "行项目描述 (可选)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "此行的附加上下文" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "单位价格" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "采购订单行项目" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "供应商零件必须与供应商匹配" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "生产订单必须标记为外部" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "生产订单仅可关联至装配零件" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "生产订单零件必须与行项目零件一致" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "装配零件需要外部生产订单" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "供应商零件" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "已接收" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "收到的物品数量" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "采购价格" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "每单位的采购价格" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "外部生产订单需由此行项目履行" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "采购订单附加行" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "销售订单行项目" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "只有可销售的零件才能分配给销售订单" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "售出价格" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "单位售出价格" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "已配送" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "发货数量" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "销售订单发货" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "收货地址必须与该客户的资料一致" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "本次发货的收货地址" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "发货日期" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "送达日期" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "装运交货日期" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "审核人" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "检查此装运的用户" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "配送" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "配送单号" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "跟踪单号" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "配送跟踪信息" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "发票编号" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "相关发票的参考号" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "货物已发出" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "发货没有分配库存项目" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "货件必须先经核对,方可标记为完成" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "销售订单加行" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "销售订单分配" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "库存项目尚未分配" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "无法将库存项目分配给具有不同零件的行" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "无法将库存分配给没有零件的生产线" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "分配数量不能超过库存数量" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "分配的数量必须大于零" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "序列化库存项目的数量必须为1" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "销售订单与发货不匹配" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "发货与销售订单不匹配" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "行" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "销售订单发货参考" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "项目" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "选择要分配的库存项目" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "输入库存分配数量" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "退货订单参考" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "退回物品的公司" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "退货订单状态" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "退货订单行项目" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "必须指定库存项" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "退回数量超过库存数量" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "退回数量必须大于零" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "序列化库存项的数量无效" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "选择要从客户处退回的商品" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "接收日期" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "收到此退货的日期" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "结果" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "该行项目的结果" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "与此行项目的退货或维修相关的成本" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "退货订单附加行" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "订单ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "调拨单号" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "要复制的订单ID" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "调拨单状态" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "复制行" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "转出物料来源仓库" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "从原始订单复制行项目" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "物料转入目标仓库" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "复制额外行" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "消耗库存" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "从原始订单复制额外的行项目" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "不将库存调拨至目标仓库,而是直接消耗库存:从分配库存中扣减调拨数量" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "复制参数" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "需设置目标库位后方可完成该单据" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" -msgstr "从原始订单复制订单参数" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "单据需完成全部库存分配后方可办结" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "调拨单行项目" + +#: order/models.py:4027 +msgid "transferred" +msgstr "已调拨" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "已调拨数量" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "调拨单分配" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "调拨单扣减库存物件失败" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "无法依据调拨单转移库存物件" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "行项目" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "已完成行项目" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "复制订单" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "自定义状态键" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "指定复制此订单的选项" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "将此逻辑值对应的单据状态更新为自定义值" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "订单ID不正确" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "自定义状态键必须为整数" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "自定义状态键无效" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "该单据状态对应的自定义状态键无效" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "供应商名称" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "订单不能取消" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "允许关闭行项目不完整的订单" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "订单中的行项目不完整" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "订单未打开" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "自动定价" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "根据供应商零件数据自动计算采购价格" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "购买价格货币" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "合并项目" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "将具有相同零件、目的地和目标日期的项目合并到一个行项目中" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "库存量单位" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "内部零件编号" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "内部零件名称" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "必须指定供应商零件" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "必须指定采购订单" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "供应商必须匹配采购订单" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "采购订单必须与供应商匹配" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "行项目" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "为收到的物品选择目的地位置" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "输入入库项目的批号" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "有效期至" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "输入入库库存项的有效期" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "输入入库库存项目的序列号" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "覆盖传入库存项目的包装资料" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "传入库存项目的附加说明" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "条形码" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "扫描条形码" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "条形码已被使用" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "必须提供行项目" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "必须指定目标位置" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "提供的条形码值必须是唯一的" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "配送" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "完成配送" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "已分配的行" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "售出价格货币" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "已分配的项目" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "未提供装运详细信息" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "行项目与此订单不关联" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "数量必须为正" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "该库存项未通过所有必要的测试" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "输入要分配的序列号" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "货物已发出" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "发货与此订单无关" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "未找到以下序列号的匹配项" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "物料出库库存库位(留空则不限库位)" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "以下序列号不可用" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "排除该库位库存" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "将分配明细分配至本次发货单" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "允许从多个库位取货以满足单行物料需求" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "序列化物料" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "控制序列化物料是否参与自动库存分配" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "仅对指定物料行执行库存分配(留空则分配全部物料行)" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "该物料行不属于此单据" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "退货订单行项目" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "行项目与退货订单不匹配" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "行项目已收到" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "只能根据正在进行的订单接收物品" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "退货数量" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "行价格货币" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "允许单据在库存未完全分配完成时结案" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "单据存在未完成分配的物料" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "丢失" @@ -5720,1279 +6127,1312 @@ msgstr "丢失" msgid "Returned" msgstr "已退回" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "正在进行" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "退回" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "维修" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "替換" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "退款" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "拒绝" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "已派发" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "逾期采购订单" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "采购订单 {po} 已逾期" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "逾期销售订单" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "销售订单 {so} 已逾期" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "逾期退货订单" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "退货订单 {ro} 现已逾期" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "已加星标" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "按星标类别筛选" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "深度" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "按类别深度筛选" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "顶级" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "按顶级类别筛选" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "级联" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "在筛选结果中包含子类别" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "父类" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "按父类别筛选" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "排除指定类别下的子类别" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "最大层级" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "限制物料分类树层级深度" + +#: part/api.py:442 msgid "Has Results" msgstr "有结果" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "是变体" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "是修订版本" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "有修订版本" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "物料清单合规" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "级联分类" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "如果为真,则包含给定分类下的所有子分类中的项目" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "按数字分类ID或字面值 \"null\" 进行筛选" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "装配零件已启用" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "装配零件可追踪" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "装配部份是可测试的" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "装配零件已锁定" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "元器件已激活" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "该零部件可追溯" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "组件部份是可测试的" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "该零部件是一个装配件" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "该零部件为虚拟件" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "有可用库存" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "使用" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "零件类别" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "零件类别" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "默认位置" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "此类别零件的默认库存地点" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "结构性" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "零件可能无法直接分配到结构类别,但可以分配到子类别。" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "默认关键字" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "此类别零件的默认关键字" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "图标" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "图标(可选)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "您不能使这个零件类别结构化,因为有些零件已经分配给了它!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "零件类别参数模板" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "默认值" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "默认参数值" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "零件" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "无法删除已锁定零件的参数" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "无法修改已锁定零件的参数" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "无法删除这个零件,因为它已被锁定" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "无法删除这个零件,因为它仍然处于活动状态" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "无法删除这个零件,因为它被使用在了装配中" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "零件 \"{self}\" 不能用在 \"{parent}\" 的物料清单 (递归)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "零件 \"{parent}\" 被使用在了 \"{self}\" 的物料清单 (递归)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "内部零件号必须匹配正则表达式 {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "零件不能是对自身的修订" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "标记为带版本管理的物料必须指定版本代码" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "修订仅对装配零件允许" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "无法对模版零件进行修订" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "上级零件必须指向相同的模版" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "该序列号库存项己存在" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "在零件设置中不允许重复的内部零件号" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "重复的零件修订版本已经存在。" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "有这个名字,内部零件号,和修订版本的零件已经存在" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "零件不能分配到结构性零件类别!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "零件名称" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "是模板" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "这个零件是一个模版零件吗?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "这个零件是另一零件的变体吗?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "变体" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "零件描述(可选)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "关键词" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "提高搜索结果可见性的零件关键字" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "零件类别" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "内部零件号 IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "零件修订版本或版本号" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "版本" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "这零件是另一零件的修订版本吗?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "修订版本" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "该物品通常存放在哪里?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "默认到期" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "此零件库存项的过期时间 (天)" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "最低库存" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "允许的最小库存量" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "最大库存" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "最大允许库存水平" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "此零件的计量单位" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "这个零件可由其他零件加工而成吗?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "这个零件可用于创建其他零件吗?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "此零件是否有唯一物品的追踪功能" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "这一部件能否记录到测试结果?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "这个零件可从外部供应商购买吗?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "此零件可以销售给客户吗?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "这个零件是否已激活?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "无法编辑锁定的零件" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "这是一个虚拟零件,例如一个软件产品或许可证吗?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "该零件是否为消耗品(例如胶水、紧固件)?" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "物料清单已验证" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "该零件的物料清单是否通过验证?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "物料清单校验和" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "保存的物料清单校验和" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "物料清单检查人" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "物料清单检查日期" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "新建用户" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "此零件的负责人" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "出售多个" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "用于缓存定价计算的货币" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "最低物料清单成本" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "元件的最低成本" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "物料清单的最高成本" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "元件的最高成本" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "最低购买成本" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "最高历史购买成本" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "最大购买成本" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "最高历史购买成本" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "最低内部价格" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "基于内部批发价的最低成本" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "最大内部价格" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "基于内部批发价的最高成本" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "供应商最低价格" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "外部供应商零件的最低价格" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "供应商最高价格" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "来自外部供应商的商零件的最高价格" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "最小变体成本" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "计算出的变体零件的最低成本" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "最大变体成本" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "计算出的变体零件的最大成本" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "最低成本" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "覆盖最低成本" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "最高成本" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "覆盖最大成本" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "计算总最低成本" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "计算总最大成本" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "最低售出价格" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "基于批发价的最低售出价格" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "最高售出价格" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "基于批发价的最大售出价格" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "最低销售成本" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "历史最低售出价格" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "最高销售成本" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "历史最高售出价格" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "用于盘点的零件" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "物品数量" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "盘点时的个别库存条目数" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "盘点时可用库存总额" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "日期" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "进行盘点的日期" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "最低库存成本" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "现有存库存最低成本估算" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "最高库存成本" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "目前库存最高成本估算" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "零件售出价格折扣" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "零件内部批发价" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "零件测试模板" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "模板名称无效 - 必须包含至少一个字母或者数字" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "测试模板只能为可拆分的部件创建" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "零件已存在具有相同主键的测试模板" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "测试名" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "输入测试的名称" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "测试主键" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "简化测试主键" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "测试说明" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "输入测试的描述" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "此测试是否已启用?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "必须的" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "需要此测试才能通过吗?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "需要值" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "添加测试结果时是否需要一个值?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "需要附件" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "添加测试结果时是否需要文件附件?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "此测试的有效选择 (逗号分隔)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "数量无效 - 未指定零件的单位" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "数量必须大于或等于零" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "物料清单项目不能被修改 - 装配已锁定" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "物料清单项目不能修改 - 变体装配已锁定" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "选择父零件" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "子零件" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "选择要用于物料清单的零件" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "数量" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "生产一个部件所消耗的子零件数量" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "此物料清单项目的数量" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "此物料清单项目是可选的" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "这个物料清单项目是耗材 (它没有在生产订单中被追踪)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "设置数量" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "为补偿生产准备损耗所需的额外数量" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "损耗" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "生产预估损耗率(百分比,0-100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "舍入倍数" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "将所需生产数量向上舍入至该值的最接近倍数" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "物料清单项目引用" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "物料清单项目注释" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "校验和" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "物料清单行校验和" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "已验证" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "此物料清单项目已验证" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "获取继承的" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "此物料清单项目是由物料清单继承的变体零件" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "变体零件的库存项可以用于此物料清单项目" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "可追踪零件的数量必须是整数" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "必须指定子零件" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "物料清单项目替代品" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "替代品零件不能与主零件相同" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "上级物料清单项目" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "替代品零件" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "零件 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "零件2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "选择相关的零件" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "此关系的注释" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "零件关系不能在零件和自身之间创建" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "复制关系已经存在" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "删除所有子分类" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "删除当前分类下包含的所有子分类" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "删除零件" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "删除该分类下包含的全部零件" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "上级类别" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "上级零件类别" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "子类别" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "结果" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "根据该模板记录的结果数量" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "购买此库存项的货币" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "文件不是一个图片" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "原始零件" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "选择要复制的原始零件" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "复制图片" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "从原零件复制图片" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "复制物料清单" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "从原始零件复制材料清单" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "从原始零件复制参数数据" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "复制备注" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "从原始零件复制备注" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "复制测试" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "从原始零件复制测试模板" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "初始化库存数量" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "指定此零件的初始库存数量。如果数量为零,则不添加任何库存。" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "初始化库存地点" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "初始化指定此零件的库存地点" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "选择供应商(或为空以跳过)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "选择制造商(或为空)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "制造商零件号" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "所选公司不是一个有效的供应商" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "所选公司不是一个有效的制造商" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "与此制造商零件编号 (MPN) 的相匹配的制造商零件已存在" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "匹配此库存单位 (SKU) 的供应商零件已存在" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "类别名称" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "正在生产" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "目前正在生产的零件数量" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "此零件计划待产数量" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "库存项" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "修订" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "库存总量" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "未分配的库存" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "变体库存" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "重复零件" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "从另一个零件复制初始数据" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "复制图片" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "从原零件复制图片" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "复制物料清单" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "从原始零件复制材料清单" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "复制备注" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "从原始零件复制备注" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "复制测试" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "从原始零件复制测试模板" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "初始库存" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "创建具有初始库存数量的零件" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "供应商信息" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "添加此零件的初始供应商信息" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "复制类别参数" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "从选择的零件复制参数模版" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "现有的图片" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "现有零件图片的文件名" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "图片不存在" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "验证整个物料清单" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "可以创建" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "生产订单必填项" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "分配到生产订单" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "销售订单必填项" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "分配到销售订单" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "内部零件号" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "零件描述" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "选择一个物料,以生成该物料(及其所有变型物料)的盘点信息" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "选择一个分类,以包含该分类(及其子分类)下的所有物料" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "选择一个库位,以包含该库位(含子库位)中有库存的所有物料" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "生成盘点条目" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "保存所选物料的盘点条目" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "生成报告" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "为所选物料生成盘点报告" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "最低价格" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "覆盖已计算的最低价格值" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "最低价格货币" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "最高价格" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "覆盖已计算的最高价格值" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "最高价格货币" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "更新" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "更新这个零件的价格" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "无法将所提供的货币转换为 {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "最低价格不能高于最高价格。" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "最高价格不能低于最低价格" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "此商品所需数量(可包含单位)" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "选择父装配" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "选择零部件" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "无效的数量格式" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "选择要复制物料清单的零件" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "移除现有数据" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "复制前删除现有的物料清单项目" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "包含继承的" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "包含从模板零件继承的物料清单项目" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "跳过无效行" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "启用此选项以跳过无效行" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "复制替代品零件" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "复制物料清单项目时复制替代品零件" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "低库存通知" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "可用的 {part.name}库存已经跌到设置的最低值" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "到期库存通知" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "您有1个库存项即将到期" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "您有{item_count}个库存项即将到期" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "永久有效" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "已过期 {abs(days_diff)} 天" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "今天到期" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "{days_until_expiry}天" @@ -7013,7 +7453,7 @@ msgstr "示例" msgid "Installed" msgstr "已安装" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "插件不能被删除,因为它当前处于激活状态" @@ -7025,23 +7465,23 @@ msgstr "未指定操作" msgid "No matching action found" msgstr "未找到指定操作" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "未找到匹配条形码数据" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "找到匹配条形码数据" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "不支持模型" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "找不到模型实例" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "条形码匹配现有项目" @@ -7057,51 +7497,67 @@ msgstr "没有找到匹配的供应商零件" msgid "Multiple matching supplier parts found" msgstr "找到多个匹配的供应商零件" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "没有找到匹配条形码数据的插件" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "匹配的供应商零件" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "项目已被接收" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "已找到采购订单\\r但无匹配供应商零件" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "已匹配到供应商零件\\r但未找到对应采购订单" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "没有匹配供应商条形码的插件" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "找到多个匹配的行项目" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "未找到匹配的行项目" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "未提供销售订单" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "条形码与现有的库存项不匹配" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "库存项与行项目不匹配" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "可用库存不足" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "库存项已分配到销售订单" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "没有足够的信息" @@ -7110,23 +7566,23 @@ msgstr "没有足够的信息" msgid "Found matching item" msgstr "找到匹配的项目" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "供应商零件与行项目不匹配" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "行项目已完成" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "需要更多信息以接收行项目" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "已收到采购订单行项目" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "接收行项目失败" @@ -7263,21 +7719,21 @@ msgid "Provides native support for barcodes" msgstr "提供条形码本地支持" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7307,11 +7763,11 @@ msgstr "短条形码前缀" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "自定义用于短条形码的前缀,可能对有多个InvenTree实例的环境有用。" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "自动创建生产单" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "为装配件自动创建生产订单" @@ -7509,74 +7965,82 @@ msgid "Include Variant Items" msgstr "包含变体项" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "在价格计算中包含零件变体库存" +msgid "Include part variant stock in stocktake data" +msgstr "盘点数据包含零件变体库存" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "排除零库存条目" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "导出数据集中剔除库存为零的零件" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "零件库存盘点导出工具" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "零件库存盘点数据导出工具" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "最低单位成本" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "最高单位成本" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "最低总成本" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "最高总成本" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "InvenTree 用户界面通知" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "已集成用户界面通知方法" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree电子邮件通知" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "已集成电子邮件通知方法" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "允许电子邮件通知" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "允许向该用户发送电子邮件通知" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree Slack通知" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "已集成Slack通知方法" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "Slack传入Webhook url" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "用于发送消息到slack频道的 URL" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "打开链接" @@ -7630,12 +8094,12 @@ msgid "Provides native support for printing PDF labels" msgstr "为打印 PDF 标签提供本机支持" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Debug模式" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "启用Debug模式 - 返回原始的 HTML 而不是 PDF" @@ -7655,55 +8119,55 @@ msgstr "最近使用" msgid "Options" msgstr "选项" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "标签页大小" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "跳过标签" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "打印标签页时跳过标签的数量" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "边框" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "打印每个标签的边框" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "横屏模式" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "在横屏模式下打印标签表" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "页边距" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "页面外边距(毫米)" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "库存树标签工作表" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "单张纸上的组合多个标签" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "标签大过页面" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "没有生成标签" @@ -7755,77 +8219,85 @@ msgstr "为扫描 TME 条形码提供支持" msgid "The Supplier which acts as 'TME'" msgstr "作为‘TME’的供应商" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "只有超级用户帐户可以管理插件" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "插件安装已禁用" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "没有为安装提供软件包名称或URL" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "包名或 URL 中有无效字符" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "插件安装成功" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "插件安装到 {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "在插件仓库中找不到插件" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "插件不是一个打包的插件" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "找不到插件包名称" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "只有员工用户可以管理插件" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "插件卸载已禁用" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "插件无法卸载,因为它目前处于激活状态" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "该插件为系统必需组件,无法卸载" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "该插件为示例插件,无法卸载" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "该插件为系统内置组件,无法卸载" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "插件未安装" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "未找到插件安装记录" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "插件卸载成功" @@ -7873,25 +8345,25 @@ msgstr "强制插件" msgid "Package Plugin" msgstr "软件包插件" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "插件" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "未找到作者" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "插件 '{p}' 与当前 InvenTree 版本{v} 不兼容" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "插件所需最低版本 {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "插件所需最高版本 {v}" @@ -8116,176 +8588,184 @@ msgstr "删除配置" msgid "Delete the plugin configuration from the database" msgstr "从数据库中删除插件配置" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "标识该配置项是否被外部配置覆盖" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "该设置项适用的目标用户" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "项目" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "插件未找到" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "插件不支持标签打印" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "你暂无查看该数据模型类型的权限" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "无效的标签尺寸" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "没有有效的项目提供到模板" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "法律" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "字母" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "已存在具有此名称的模板" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "模版名称" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "模板说明" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "修订编号 (自动增量)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "打印时附加到模型" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "打印时将报告输出保存为附件与链接模型实例" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "文件名样式" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "生成文件名模式" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "模板已启用" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "模版的目标模型类型" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "筛选器" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "模版查询筛选器 (逗号分隔的键值对列表)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "模板包文件" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "PDF 报告的页面大小" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "横向渲染报告" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "合并" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "针对选定项目生成独立报" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "基于模板 {self.name} 生成的报告" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "模板语法错误" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "报告渲染错误" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "报告生成错误" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "报告合并输出错误" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "宽度 [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "标签宽度,以毫米为单位。" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "高度 [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "标签高度,以毫米为单位。" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "标签打印错误" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "代码片段" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "报告代码片段文件" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "代码片段文件描述" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "资产" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "报告资产文件" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "资产文件描述" @@ -8293,23 +8773,23 @@ msgstr "资产文件描述" msgid "User must be authenticated to save report templates" msgstr "用户必须通过身份验证才能保存报告模板" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "选择报表模板" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "要包含在报告中的项目主键列表" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "选择标签模板" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "打印插件" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "选择用于标签打印的插件" @@ -8340,13 +8820,10 @@ msgstr "所需材料" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "零件图像" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "已派发" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "需要给" @@ -8382,8 +8859,8 @@ msgstr "总计" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "序列号" @@ -8407,7 +8884,7 @@ msgstr "库存项测试报告" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "已安装的项目" @@ -8440,810 +8917,922 @@ msgstr "无结果 (必填)" msgid "No result" msgstr "没有结果" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "已调拨" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "无效的媒体文件路径" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "无效的静态文件路径" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "未找到资源文件" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "找不到图片文件" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "未指定图片文件" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "parpart_image 标签需要一个零件实例" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "公司_图片标签需要一个公司实例" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "按位置深度筛选" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "按顶级位置筛选" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "在筛选结果中包含子地点" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "上级地点" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "按上级位置筛选" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "零件名称 (不区分大小写)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "零件名称包含 (不区分大小写)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "零件名称 (正则表达式)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "内部零件号 (不区分大小写)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "内部零件号 (不区分大小写)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "内部零件号 (正则表达式)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "最低库存" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "最大库存" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "状态代码" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "外部地点" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "被生产订单消耗" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "安装于其他库存项中" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "零件树" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "更新时间早于" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "更新时间晚于" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "盘点时间早于" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "盘点时间晚于" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "存在盘点日期" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "过期日期前" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "过期日期后" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "过期" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "提供库存项的主键(PK)以排除该项及其所有子项" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "级联位置" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "若为真,则包含给定位置的所有子位置中的项目" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "按数字位置ID或字母“null”筛选" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "请先输入数量" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "必须提供有效的零件" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "给定的供应商零件不存在" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "供应商零件有定义的包装大小,但 use_pack_size 标志未设置" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "不能为不可跟踪的零件提供序列号" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "包含已安装项" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "如果为真,则包含给定库存项下已安装组件的测试结果" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "按数字库存项ID进行筛选" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "ID 为 {id} 的库存项不存在" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "包含零件变体" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "日期晚于" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "日期早于" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "库存地点类型" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "库存地点类型" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "为所有没有图标的位置设置默认图标(可选)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "库存地点" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "库存地点" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "所有者" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "选择所有者" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "库存项可能不直接位于结构库存地点,但可能位于其子地点。" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "外部" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "这是一个外部库存地点" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "位置类型" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "该位置的库存地点类型" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "您不能将此库存地点设置为结构性,因为某些库存项已经位于它!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "先进先出(优先取用最早入库库存)" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "后进先出(优先取用最新入库库存)" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "优先取用数量最少的库存批次" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "优先取用数量最多的库存批次" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "优先取用最早过期批次" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "序列化库存商品无法删除" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field} 不存在" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "必须指定零件" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "库存项不能存放在结构性库存地点!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" -msgstr "" +msgstr "不允许编辑序列号:该物料条目已分配序列号" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "无法为虚拟零件创建库存项" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "零件类型 ('{self.supplier_part.part}') 必须为 {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "有序列号的项目的数量必须是1" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "如果数量大于1,则不能设置序列号" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "项目不能属于其自身" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "如果is_building=True,则项必须具有构建引用" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "构建引用未指向同一零件对象" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "父级库存项" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "基础零件" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "为此库存项目选择匹配的供应商零件" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "这个库存物品在哪里?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "包装此库存物品存储在" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "安装于" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "此项目是否安装在另一个项目中?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "此项目的序列号" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "此库存项的批号" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "库存数量" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "源代码构建" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "为此库存项目构建" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "消费者" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "构建消耗此库存项的生产订单" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "采购订单来源" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "此库存商品的采购订单" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "目的地销售订单" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "库存物品的到期日。在此日期之后,库存将被视为过期" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "该库存条目创建日期" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "耗尽时删除" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "当库存耗尽时删除此库存项" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "购买时一个单位的价格" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "转换为零件" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "数量超过可用库存" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "无效的数量值" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "无法将库存分配到结构位置" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "数量不得超过现有库存数量" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "序列号管控库存条目必须完整拆解" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "未提供 BOM 明细" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "包含预装子项的库存条目必须整体拆解" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "零件未设置为可跟踪" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "数量必须是整数" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "数量不得超过现有库存量 ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "必须以列表形式提供序列号" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "数量不匹配序列号" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "无法将库存分配到结构位置" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "测试模板不存在" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "库存项已分配到销售订单" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "库存项已安装在另一个项目中" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "库存项包含其他项目" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "库存项已分配给客户" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "库存项目前正在生产" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "序列化的库存不能合并" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "复制库存项" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "库存项必须指相同零件" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "库存项必须是同一供应商的零件" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "库存状态码必须匹配" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "库存项不能移动,因为它没有库存" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "库存项跟踪" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "条目注释" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "库存项测试结果" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "必须为此测试提供值" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "测试附件必须上传" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "此测试的值无效" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "测试结果" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "测试输出值" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "测验结果附件" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "测试备注" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "测试站" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "进行测试的测试站的标识符" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "已开始" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "测试开始的时间戳" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "已完成" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "测试结束的时间戳" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "生成批量代码" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "选择生产订单" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "选择要生成批量代码的库存项" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "选择要生成批量代码的位置" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "选择要生成批量代码的零件" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "选择采购订单" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "输入批量代码的数量" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "生成的序列号" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "选择要生成序列号的零件" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "要生成的序列号的数量" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "此结果的测试模板" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "未找到适用于此零件的匹配测试" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "必须提供模板 ID 或测试名称" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "测试完成时间不能早于测试开始时间" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "父项" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "父库存项" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "添加时使用包装尺寸:定义的数量是包装的数量" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "包装规格" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "输入新项目的序列号" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "供应商零件编号" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "已过期" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "子项目" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "跟踪项目" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "此库存商品的购买价格,单位或包装" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "输入要序列化的库存项目数量" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "未提供库存项" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "数量不得超过现有库存量 ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "目标库存位置" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "此零件不能分配序列号" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "序列号已存在" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "选择要安装的库存项目" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "安装数量" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "输入要安装的项目数量" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "添加交易记录 (可选)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "安装数量必须至少为1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "库存项不可用" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "所选零件不在物料清单中" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "安装数量不得超过可用数量" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "已卸载项目的目标位置" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "选择要将库存项目转换为的零件" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "所选零件不是有效的转换选项" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "无法转换已分配供应商零件的库存项" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "库存项状态代码" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "用于定义待拆分组件零件的 BOM 行" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "待创建组件零件数量" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "组件物料目标存放位置" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "组件物料状态代码" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "组件物料单位采购价(留空则自动分摊成本)" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "待拆解装配体数量" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "组件物料默认目标库位" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "所选库存条目无法使用该 BOM 项" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "存在重复 BOM 条目" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "选择要将库存项目转换为的零件" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "所选零件不是有效的转换选项" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "无法转换已分配供应商零件的库存项" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "选择要更改状态的库存项目" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "未选择库存商品" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "子位置" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "删除库存条目" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "删除当前库位下全部库存条目" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "删除下级子库位" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "删除当前库位下所有下级子库位" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "上级库存地点" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "零件必须可销售" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "物料已分配到销售订单" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "该物料已分配至库存调拨单" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "项目被分配到生产订单中" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "客户分配库存项目" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "所选公司不是客户" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "库存分配说明" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "必须提供库存物品清单" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "库存合并说明" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "允许不匹配的供应商" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "允许合并具有不同供应商零件的库存项目" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "允许不匹配的状态" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "允许合并具有不同状态代码的库存项目" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "必须提供至少两件库存物品" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "无更改" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "库存项主键值" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "库存项无现货" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "库存项已有现货" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "数量不得为负" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "库存交易记录" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "合并至现有库存" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "条件允许时,将该库存合并至目标库位已有同物料库存" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "库存交易记录" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "为已盘点物料指定库存位置(可选)" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "若可行,将退回项目合并至现有库存项" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "下一个序列号" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "上一个序列号" @@ -9344,42 +9933,50 @@ msgid "Merged stock items" msgstr "合并的库存项" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "已拆解为组件" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "由拆解生成" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "转换为变体" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "已创建生产订单产出" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "生产订单已出产" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "生产订单产出被拒绝" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "被生产订单消耗" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "根据销售订单发货" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "根据采购订单接收" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "根据退货订单退货" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "发往客户" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "客户退回" @@ -9529,19 +10126,19 @@ msgstr "用户" msgid "Select which users are assigned to this group" msgstr "选择分配给此组的用户" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "个人信息" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "权限" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "重要日期" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "令牌已被撤销" @@ -9549,279 +10146,283 @@ msgstr "令牌已被撤销" msgid "Token has expired" msgstr "令牌已过期" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API 令牌" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API 令牌" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "令牌名称" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "自定义令牌名称" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "令牌过期日期" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "最近一次在线" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "最近使用令牌的时间" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "撤销" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "权限设置" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "查看" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "查看项目的权限" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "添加" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "添加项目的权限" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "更改" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "编辑项目的权限" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "删除" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "删除项目的权限" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "机器人" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "内部" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "访客" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "语言" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "用户首选语言" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "主题" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Web界面设置为 JSON - 不要手动编辑!" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "小部件" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "设置面板小部件为 JSON - 不要手动编辑!" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "显示名称" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "用户自定义的显示名称" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "职位" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "主要职务或职位" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "用户状态信息" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "用户地址信息" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "用户正在积极使用系统" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "用户首选联系信息" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "用户类型" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "请选择用户类型?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "组织" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "用户主要组织/附属关系" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "主组" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "用户主组" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "管理员" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "物料清单" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "采购订单" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "销售订单" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "退货订单" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "调拨单" + +#: users/serializers.py:196 msgid "Username" msgstr "用户名" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "名" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "用户的名字(不包括姓氏)" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "姓" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "用户的姓氏" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "用户的电子邮件地址" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "用户必须经过身份验证" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "只有超级用户可以为另一个用户创建令牌" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "管理员" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "该用户是否拥有管理员权限" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "超级用户" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "此用户是否为超级用户" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "此用户帐户是否已激活" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "只有超级用户可以调整此字段" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "密码" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "用户密码" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "覆盖警告" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "覆盖有关密码规则的警告" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "管理员" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "该用户是否拥有管理员权限" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "你没有权限创建用户" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "您的账户已创建。" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "请使用密码重置功能登录" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "欢迎使用 InvenTree" diff --git a/src/backend/InvenTree/locale/zh_Hant/LC_MESSAGES/django.po b/src/backend/InvenTree/locale/zh_Hant/LC_MESSAGES/django.po index 5734842f04..1c09e77808 100644 --- a/src/backend/InvenTree/locale/zh_Hant/LC_MESSAGES/django.po +++ b/src/backend/InvenTree/locale/zh_Hant/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: inventree\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-19 07:07+0000\n" -"PO-Revision-Date: 2026-05-19 07:09\n" +"POT-Creation-Date: 2026-08-16 01:47+0000\n" +"PO-Revision-Date: 2026-08-16 01:50\n" "Last-Translator: \n" "Language-Team: Chinese Traditional\n" "Language: zh_TW\n" @@ -17,39 +17,43 @@ msgstr "" "X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 250\n" -#: InvenTree/api.py:365 +#: InvenTree/api.py:372 msgid "API endpoint not found" msgstr "未找到 API 端點" -#: InvenTree/api.py:438 +#: InvenTree/api.py:445 msgid "List of items must be provided for bulk operation" msgstr "必須提供項目清單以進行大量操作" -#: InvenTree/api.py:445 +#: InvenTree/api.py:452 msgid "Items must be provided as a list" msgstr "項目必須以列表形式提供" -#: InvenTree/api.py:453 +#: InvenTree/api.py:460 msgid "Invalid items list provided" msgstr "提供了無效的單位" -#: InvenTree/api.py:458 +#: InvenTree/api.py:465 msgid "All filter must only be used with true" msgstr "all 篩選器只能在值為 true 時使用" -#: InvenTree/api.py:463 +#: InvenTree/api.py:470 msgid "No items match the provided criteria" msgstr "沒有項目符合所提供的條件" -#: InvenTree/api.py:487 +#: InvenTree/api.py:494 msgid "No data provided" msgstr "未提供資料" -#: InvenTree/api.py:503 +#: InvenTree/api.py:510 msgid "This field must be unique." msgstr "此欄位須唯一值。" -#: InvenTree/api.py:832 +#: InvenTree/api.py:614 +msgid "Item no longer matches the provided criteria" +msgstr "" + +#: InvenTree/api.py:861 InvenTree/models.py:1459 msgid "User does not have permission to view this model" msgstr "用户沒有權限查閲當前模型。" @@ -65,150 +69,155 @@ msgstr "郵箱地址已確認" msgid "You must type the same email each time." msgstr "您必須每次輸入相同的電子郵件。" -#: InvenTree/auth_overrides.py:132 InvenTree/auth_overrides.py:139 +#: InvenTree/auth_overrides.py:135 InvenTree/auth_overrides.py:142 msgid "The provided primary email address is not valid." msgstr "提供的主電子郵件地址無效。" -#: InvenTree/auth_overrides.py:145 +#: InvenTree/auth_overrides.py:148 msgid "The provided email domain is not approved." msgstr "提供的郵箱域名未被批准。" -#: InvenTree/conversion.py:240 +#: InvenTree/conversion.py:243 #, python-brace-format msgid "Invalid unit provided ({unit})" msgstr "提供了無效的單位 ({unit})" -#: InvenTree/conversion.py:257 +#: InvenTree/conversion.py:260 msgid "No value provided" msgstr "沒有提供數值" -#: InvenTree/conversion.py:284 +#: InvenTree/conversion.py:287 #, python-brace-format msgid "Could not convert {original} to {unit}" msgstr "不能將 {original} 轉換到 {unit}" -#: InvenTree/conversion.py:286 InvenTree/conversion.py:300 -#: InvenTree/helpers.py:610 order/models.py:747 order/models.py:1042 -#: part/models.py:3946 +#: InvenTree/conversion.py:289 InvenTree/conversion.py:303 +#: InvenTree/helpers.py:627 order/models.py:822 order/models.py:1107 +#: part/models.py:3847 stock/models.py:2114 msgid "Invalid quantity provided" msgstr "提供的數量無效" -#: InvenTree/exceptions.py:136 +#: InvenTree/exceptions.py:128 +msgid "Server is temporarily reloading, please retry the request" +msgstr "" + +#: InvenTree/exceptions.py:161 msgid "Error details can be found in the admin panel" msgstr "在管理面板中可以找到錯誤詳細信息" -#: InvenTree/fields.py:146 +#: InvenTree/fields.py:214 msgid "Enter date" msgstr "輸入日期" -#: InvenTree/fields.py:169 +#: InvenTree/fields.py:237 msgid "Invalid decimal value" msgstr "無效的十進位數值" -#: InvenTree/fields.py:218 InvenTree/models.py:1235 build/serializers.py:505 -#: build/serializers.py:576 build/serializers.py:1789 company/models.py:827 -#: order/models.py:1845 +#: InvenTree/fields.py:286 InvenTree/models.py:1365 build/serializers.py:530 +#: build/serializers.py:591 build/serializers.py:1775 company/models.py:828 +#: order/models.py:2154 #: report/templates/report/inventree_build_order_report.html:172 -#: stock/models.py:2978 stock/models.py:3102 stock/serializers.py:746 -#: stock/serializers.py:922 stock/serializers.py:1064 stock/serializers.py:1411 -#: stock/serializers.py:1500 stock/serializers.py:1699 +#: stock/models.py:3780 stock/models.py:3906 stock/serializers.py:753 +#: stock/serializers.py:935 stock/serializers.py:1114 stock/serializers.py:1280 +#: stock/serializers.py:1664 stock/serializers.py:1753 +#: stock/serializers.py:1962 msgid "Notes" msgstr "備註" -#: InvenTree/format.py:166 +#: InvenTree/format.py:159 #, python-brace-format msgid "Value '{name}' does not appear in pattern format" msgstr "值' {name}' 未出現在模式格式中" -#: InvenTree/format.py:177 +#: InvenTree/format.py:170 msgid "Provided value does not match required pattern: " msgstr "提供的值與所需模式不匹配:" -#: InvenTree/helpers.py:614 +#: InvenTree/helpers.py:631 msgid "Cannot serialize more than 1000 items at once" msgstr "一次不能序列化超過 1000 個項目" -#: InvenTree/helpers.py:620 +#: InvenTree/helpers.py:637 msgid "Empty serial number string" msgstr "序號為空白" -#: InvenTree/helpers.py:649 +#: InvenTree/helpers.py:666 msgid "Duplicate serial" msgstr "複製序列號" -#: InvenTree/helpers.py:681 InvenTree/helpers.py:724 InvenTree/helpers.py:742 -#: InvenTree/helpers.py:749 InvenTree/helpers.py:768 +#: InvenTree/helpers.py:698 InvenTree/helpers.py:741 InvenTree/helpers.py:759 +#: InvenTree/helpers.py:766 InvenTree/helpers.py:785 #, python-brace-format msgid "Invalid group: {group}" msgstr "無效的群組:{group}" -#: InvenTree/helpers.py:712 +#: InvenTree/helpers.py:729 #, python-brace-format msgid "Group range {group} exceeds allowed quantity ({expected_quantity})" msgstr "組範圍 {group} 超出了允許的數量 ({expected_quantity})" -#: InvenTree/helpers.py:778 +#: InvenTree/helpers.py:795 msgid "No serial numbers found" msgstr "未找到序列號" -#: InvenTree/helpers.py:785 +#: InvenTree/helpers.py:802 #, python-brace-format msgid "Number of unique serial numbers ({n}) must match quantity ({q})" msgstr "唯一序列號數量 ({n}) 必須與數量 ({q}) 相符" -#: InvenTree/helpers.py:915 +#: InvenTree/helpers.py:932 msgid "Remove HTML tags from this value" msgstr "從這個值中刪除 HTML 標籤" -#: InvenTree/helpers.py:992 +#: InvenTree/helpers.py:1009 msgid "Data contains prohibited markdown content" msgstr "資料包含被禁止的 Markdown 內容" -#: InvenTree/helpers_model.py:109 +#: InvenTree/helpers_model.py:166 msgid "Invalid URL: no hostname" msgstr "無效的 URL:沒有主機名稱" -#: InvenTree/helpers_model.py:114 +#: InvenTree/helpers_model.py:171 msgid "Invalid URL: hostname could not be resolved" msgstr "無效的 URL:無法解析主機名稱" -#: InvenTree/helpers_model.py:120 +#: InvenTree/helpers_model.py:175 msgid "URL points to a private or reserved IP address" msgstr "URL 指向私有或保留的 IP 地址" -#: InvenTree/helpers_model.py:197 +#: InvenTree/helpers_model.py:256 msgid "Too many redirects" msgstr "重新導向次數過多" -#: InvenTree/helpers_model.py:202 +#: InvenTree/helpers_model.py:261 msgid "Connection error" msgstr "連接錯誤" -#: InvenTree/helpers_model.py:207 InvenTree/helpers_model.py:216 +#: InvenTree/helpers_model.py:266 InvenTree/helpers_model.py:275 msgid "Server responded with invalid status code" msgstr "服務器響應狀態碼無效" -#: InvenTree/helpers_model.py:212 +#: InvenTree/helpers_model.py:271 msgid "Exception occurred" msgstr "發生異常" -#: InvenTree/helpers_model.py:222 +#: InvenTree/helpers_model.py:281 msgid "Server responded with invalid Content-Length value" msgstr "服務器響應的內容長度值無效" -#: InvenTree/helpers_model.py:225 +#: InvenTree/helpers_model.py:284 msgid "Image size is too large" msgstr "圖片尺寸過大" -#: InvenTree/helpers_model.py:237 +#: InvenTree/helpers_model.py:296 msgid "Image download exceeded maximum size" msgstr "圖片下載超出最大尺寸" -#: InvenTree/helpers_model.py:242 +#: InvenTree/helpers_model.py:301 msgid "Remote server returned empty response" msgstr "遠程服務器返回了空響應" -#: InvenTree/helpers_model.py:250 +#: InvenTree/helpers_model.py:309 msgid "Supplied URL is not a valid image file" msgstr "提供的 URL 不是一個有效的圖片文件" @@ -216,159 +225,203 @@ msgstr "提供的 URL 不是一個有效的圖片文件" msgid "Log in to the app" msgstr "登入此應用程式" -#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:197 +#: InvenTree/magic_login.py:41 company/models.py:175 users/serializers.py:207 msgid "Email" msgstr "電子郵件" -#: InvenTree/middleware.py:192 +#: InvenTree/middleware.py:126 +msgid "CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly." +msgstr "" + +#: InvenTree/middleware.py:218 msgid "You must enable two-factor authentication before doing anything else." msgstr "在進行任何其他操作前,必須先啟用雙因素驗證。" -#: InvenTree/models.py:114 +#: InvenTree/models.py:138 msgid "Error running plugin validation" msgstr "驗證外掛程式時發生錯誤" -#: InvenTree/models.py:195 +#: InvenTree/models.py:220 msgid "Metadata must be a python dict object" msgstr "Metadata必須是一個Python Dictionary物件" -#: InvenTree/models.py:201 +#: InvenTree/models.py:226 msgid "Plugin Metadata" msgstr "外掛程式Metadata" -#: InvenTree/models.py:202 +#: InvenTree/models.py:227 msgid "JSON metadata field, for use by external plugins" msgstr "外掛程式使用的JSON Metadata欄位" -#: InvenTree/models.py:385 +#: InvenTree/models.py:410 msgid "Improperly formatted pattern" msgstr "格式錯誤" -#: InvenTree/models.py:392 +#: InvenTree/models.py:417 msgid "Unknown format key specified" msgstr "指定了不明的格式鍵值" -#: InvenTree/models.py:398 +#: InvenTree/models.py:423 msgid "Missing required format key" msgstr "缺少必須的格式鍵值" -#: InvenTree/models.py:409 +#: InvenTree/models.py:434 msgid "Reference field cannot be empty" msgstr "參考欄位不能空白" -#: InvenTree/models.py:417 +#: InvenTree/models.py:442 msgid "Reference must match required pattern" msgstr "參考欄位並須符合格式" -#: InvenTree/models.py:448 +#: InvenTree/models.py:473 msgid "Reference number is too large" msgstr "參考編號過大" -#: InvenTree/models.py:903 +#: InvenTree/models.py:929 msgid "Invalid choice" msgstr "無效的選項" -#: InvenTree/models.py:1024 common/models.py:1443 common/models.py:1870 -#: common/models.py:2201 common/models.py:2326 common/models.py:2623 -#: common/serializers.py:647 generic/states/serializers.py:20 -#: machine/models.py:25 part/models.py:1102 plugin/models.py:54 -#: report/models.py:219 stock/models.py:86 +#: InvenTree/models.py:1099 common/models.py:1455 common/models.py:1891 +#: common/models.py:2327 common/models.py:2452 common/models.py:2762 +#: common/serializers.py:681 generic/states/serializers.py:20 +#: machine/models.py:28 part/models.py:1119 plugin/models.py:54 +#: report/models.py:222 stock/models.py:89 msgid "Name" msgstr "名稱" -#: InvenTree/models.py:1030 build/models.py:265 common/models.py:180 -#: common/models.py:2333 common/models.py:2474 common/models.py:2638 -#: company/models.py:558 company/models.py:818 order/models.py:447 -#: order/models.py:1890 part/models.py:1125 report/models.py:225 -#: report/models.py:854 report/models.py:880 +#: InvenTree/models.py:1105 build/models.py:273 common/models.py:180 +#: common/models.py:2459 common/models.py:2600 common/models.py:2777 +#: company/models.py:563 company/models.py:819 order/models.py:508 +#: order/models.py:2199 part/models.py:1142 report/models.py:228 +#: report/models.py:872 report/models.py:898 #: report/templates/report/inventree_build_order_report.html:117 -#: stock/models.py:92 +#: stock/models.py:95 msgid "Description" msgstr "描述" -#: InvenTree/models.py:1031 stock/models.py:93 +#: InvenTree/models.py:1106 stock/models.py:96 msgid "Description (optional)" msgstr "描述(選填)" -#: InvenTree/models.py:1046 common/models.py:2944 +#: InvenTree/models.py:1121 common/models.py:3135 msgid "Path" msgstr "路徑" -#: InvenTree/models.py:1151 +#: InvenTree/models.py:1279 msgid "Duplicate names cannot exist under the same parent" msgstr "同一個上層元件下不能有重複的名字" -#: InvenTree/models.py:1235 +#: InvenTree/models.py:1365 msgid "Markdown notes (optional)" msgstr "Markdown 註記(選填)" -#: InvenTree/models.py:1266 +#: InvenTree/models.py:1415 msgid "Barcode Data" msgstr "條碼資料" -#: InvenTree/models.py:1267 +#: InvenTree/models.py:1416 msgid "Third party barcode data" msgstr "第三方條碼資料" -#: InvenTree/models.py:1273 +#: InvenTree/models.py:1422 msgid "Barcode Hash" msgstr "條碼雜湊值" -#: InvenTree/models.py:1274 +#: InvenTree/models.py:1423 msgid "Unique hash of barcode data" msgstr "條碼資料的唯一雜湊值" -#: InvenTree/models.py:1355 +#: InvenTree/models.py:1513 msgid "Existing barcode found" msgstr "發現現有條碼" -#: InvenTree/models.py:1455 +#: InvenTree/models.py:1617 msgid "Server Error" msgstr "伺服器錯誤" -#: InvenTree/models.py:1456 +#: InvenTree/models.py:1618 msgid "An error has been logged by the server." msgstr "伺服器紀錄了一個錯誤。" -#: InvenTree/models.py:1498 common/models.py:1781 +#: InvenTree/models.py:1660 common/models.py:1802 #: report/templates/report/inventree_bill_of_materials_report.html:126 #: report/templates/report/inventree_bill_of_materials_report.html:148 #: report/templates/report/inventree_return_order_report.html:35 msgid "Image" msgstr "圖像" -#: InvenTree/serializers.py:363 +#: InvenTree/serializers.py:554 msgid "Must be a valid number" msgstr "必須是有效的數字" -#: InvenTree/serializers.py:405 company/models.py:217 part/models.py:3326 +#: InvenTree/serializers.py:596 company/models.py:217 part/models.py:3215 msgid "Currency" msgstr "貨幣" -#: InvenTree/serializers.py:408 part/serializers.py:1376 +#: InvenTree/serializers.py:599 part/serializers.py:1389 msgid "Select currency from available options" msgstr "從可用選項中選擇貨幣" -#: InvenTree/serializers.py:758 +#: InvenTree/serializers.py:945 msgid "This field may not be null." msgstr "此欄位不可為空白。" -#: InvenTree/serializers.py:764 +#: InvenTree/serializers.py:951 msgid "Invalid value" msgstr "無效值" -#: InvenTree/serializers.py:865 +#: InvenTree/serializers.py:1106 msgid "Invalid content type format" msgstr "不合規的內容類型格式" -#: InvenTree/serializers.py:868 +#: InvenTree/serializers.py:1109 msgid "Content type not found" msgstr "內容類型未發現" -#: InvenTree/serializers.py:874 +#: InvenTree/serializers.py:1115 msgid "Content type does not match required mixin class" msgstr "內容類型與所需的 mixin 類別不符" +#: InvenTree/serializers.py:1132 +msgid "Copy Parameters" +msgstr "複製參數" + +#: InvenTree/serializers.py:1133 +msgid "Copy parameters from the original item" +msgstr "" + +#: InvenTree/serializers.py:1138 +msgid "Copy Lines" +msgstr "複製行" + +#: InvenTree/serializers.py:1139 +msgid "Copy line items from the original order" +msgstr "從原始訂單複製行項目" + +#: InvenTree/serializers.py:1144 +msgid "Copy Extra Lines" +msgstr "複製額外行" + +#: InvenTree/serializers.py:1145 +msgid "Copy extra line items from the original order" +msgstr "從原始訂單複製額外的行項目" + +#: InvenTree/serializers.py:1169 +msgid "Duplication Options" +msgstr "" + +#: InvenTree/serializers.py:1171 +msgid "Specify options for duplicating this item" +msgstr "" + +#: InvenTree/serializers.py:1209 +msgid "Original" +msgstr "" + +#: InvenTree/serializers.py:1210 +msgid "Select instance to duplicate" +msgstr "" + #: InvenTree/setting/locales.py:20 msgid "Arabic" msgstr "阿拉伯語" @@ -521,46 +574,48 @@ msgstr "中文 (簡體)" msgid "Chinese (Traditional)" msgstr "中文 (繁體)" -#: InvenTree/tasks.py:677 +#: InvenTree/tasks.py:893 msgid "Update Available" msgstr "有可用更新" -#: InvenTree/tasks.py:678 +#: InvenTree/tasks.py:894 msgid "An update for InvenTree is available" msgstr "有新的 InvenTree 更新可用" -#: InvenTree/validators.py:28 +#: InvenTree/validators.py:36 InvenTree/validators.py:41 msgid "Invalid physical unit" msgstr "無效的物理單位" -#: InvenTree/validators.py:34 +#: InvenTree/validators.py:47 msgid "Not a valid currency code" msgstr "無效的貨幣代碼" -#: build/api.py:55 order/api.py:116 order/api.py:283 order/api.py:1386 -#: order/serializers.py:124 +#: build/api.py:57 order/api.py:119 order/api.py:288 order/api.py:1467 +#: order/serializers.py:99 msgid "Order Status" msgstr "訂單狀態" -#: build/api.py:81 build/models.py:277 +#: build/api.py:83 build/models.py:285 msgid "Parent Build" msgstr "上層生產工單" -#: build/api.py:85 build/api.py:918 order/api.py:560 order/api.py:785 -#: order/api.py:1187 order/api.py:1488 stock/api.py:572 +#: build/api.py:87 build/api.py:1055 order/api.py:565 order/api.py:804 +#: order/api.py:1259 order/api.py:1571 order/api.py:1868 order/api.py:2058 +#: stock/api.py:632 msgid "Include Variants" msgstr "包含變體" -#: build/api.py:101 build/api.py:475 build/api.py:932 build/models.py:283 -#: build/serializers.py:1214 build/serializers.py:1390 -#: build/serializers.py:1483 company/models.py:1037 company/serializers.py:420 -#: order/api.py:311 order/api.py:315 order/api.py:942 order/api.py:1200 -#: order/api.py:1203 order/models.py:2022 order/models.py:2190 -#: order/models.py:2191 part/api.py:1151 part/api.py:1154 part/api.py:1371 -#: part/models.py:528 part/models.py:3337 part/models.py:3480 -#: part/models.py:3538 part/models.py:3559 part/models.py:3581 -#: part/models.py:3722 part/models.py:4039 part/models.py:4466 -#: part/serializers.py:1325 part/serializers.py:1988 +#: build/api.py:103 build/api.py:490 build/api.py:1069 build/models.py:291 +#: build/serializers.py:1200 build/serializers.py:1376 +#: build/serializers.py:1469 company/models.py:1038 company/serializers.py:473 +#: order/api.py:316 order/api.py:320 order/api.py:961 order/api.py:1272 +#: order/api.py:1275 order/api.py:2071 order/api.py:2074 order/api.py:2228 +#: order/models.py:2331 order/models.py:2499 order/models.py:2500 +#: order/models.py:4021 order/models.py:4022 part/api.py:1179 part/api.py:1182 +#: part/api.py:1399 part/models.py:530 part/models.py:3226 part/models.py:3369 +#: part/models.py:3427 part/models.py:3449 part/models.py:3471 +#: part/models.py:3612 part/models.py:3941 part/models.py:4395 +#: part/serializers.py:1338 part/serializers.py:2015 #: report/templates/report/inventree_bill_of_materials_report.html:110 #: report/templates/report/inventree_bill_of_materials_report.html:137 #: report/templates/report/inventree_build_order_report.html:109 @@ -569,9 +624,10 @@ msgstr "包含變體" #: report/templates/report/inventree_sales_order_report.html:27 #: report/templates/report/inventree_sales_order_shipment_report.html:28 #: report/templates/report/inventree_stock_location_report.html:102 -#: stock/api.py:585 stock/api.py:1529 stock/serializers.py:120 -#: stock/serializers.py:172 stock/serializers.py:419 stock/serializers.py:607 -#: stock/serializers.py:955 templates/email/build_order_completed.html:17 +#: report/templates/report/inventree_transfer_order_report.html:25 +#: stock/api.py:645 stock/api.py:1581 stock/serializers.py:125 +#: stock/serializers.py:177 stock/serializers.py:428 stock/serializers.py:614 +#: stock/serializers.py:1198 templates/email/build_order_completed.html:17 #: templates/email/build_order_required_stock.html:17 #: templates/email/low_stock_notification.html:15 #: templates/email/overdue_build_order.html:16 @@ -580,432 +636,440 @@ msgstr "包含變體" msgid "Part" msgstr "零件" -#: build/api.py:121 build/api.py:124 build/serializers.py:1497 part/api.py:985 -#: part/api.py:1382 part/models.py:412 part/models.py:1143 part/models.py:3609 -#: part/serializers.py:1335 part/serializers.py:1760 stock/api.py:868 +#: build/api.py:123 build/api.py:126 build/serializers.py:1483 part/api.py:1012 +#: part/api.py:1410 part/models.py:414 part/models.py:1160 part/models.py:3499 +#: part/serializers.py:1348 part/serializers.py:1786 stock/api.py:923 msgid "Category" msgstr "類別" -#: build/api.py:132 build/api.py:136 +#: build/api.py:134 build/api.py:138 msgid "Ancestor Build" msgstr "可測試部分" -#: build/api.py:153 order/api.py:134 +#: build/api.py:155 order/api.py:137 msgid "Assigned to me" msgstr "分配給我" -#: build/api.py:168 +#: build/api.py:170 msgid "Assigned To" msgstr "負責人" -#: build/api.py:203 +#: build/api.py:205 stock/api.py:966 msgid "Created before" msgstr "建立於之前" -#: build/api.py:207 +#: build/api.py:209 stock/api.py:970 msgid "Created after" msgstr "建立於之後" -#: build/api.py:211 +#: build/api.py:213 msgid "Has start date" msgstr "有開始日期" -#: build/api.py:219 +#: build/api.py:221 msgid "Start date before" msgstr "開始日期早於" -#: build/api.py:223 +#: build/api.py:225 msgid "Start date after" msgstr "開始日期晚於" -#: build/api.py:227 +#: build/api.py:229 msgid "Has target date" msgstr "有目標日期" -#: build/api.py:235 +#: build/api.py:237 msgid "Target date before" msgstr "目標日期早於" -#: build/api.py:239 +#: build/api.py:241 msgid "Target date after" msgstr "目標日期晚於" -#: build/api.py:243 +#: build/api.py:245 msgid "Completed before" msgstr "完成於之前" -#: build/api.py:247 +#: build/api.py:249 msgid "Completed after" msgstr "完成於之後" -#: build/api.py:250 order/api.py:239 +#: build/api.py:252 order/api.py:242 msgid "Min Date" msgstr "最小日期" -#: build/api.py:273 order/api.py:258 +#: build/api.py:275 order/api.py:261 msgid "Max Date" msgstr "最大日期" -#: build/api.py:298 build/api.py:301 part/api.py:197 stock/api.py:960 +#: build/api.py:300 build/api.py:303 part/api.py:199 msgid "Exclude Tree" msgstr "排除樹" -#: build/api.py:414 +#: build/api.py:416 msgid "Build must be cancelled before it can be deleted" msgstr "工單必須被取消才能被刪除" -#: build/api.py:458 build/serializers.py:1424 part/models.py:4081 +#: build/api.py:460 build/serializers.py:1410 part/models.py:1327 +#: part/models.py:3983 msgid "Consumable" msgstr "耗材" -#: build/api.py:461 build/serializers.py:1427 part/models.py:4075 +#: build/api.py:476 build/serializers.py:1413 part/models.py:3977 msgid "Optional" msgstr "非必須項目" -#: build/api.py:464 build/serializers.py:1469 common/setting/system.py:463 -#: part/models.py:1257 part/serializers.py:1705 part/serializers.py:1731 -#: stock/api.py:638 +#: build/api.py:479 build/serializers.py:1455 common/setting/system.py:476 +#: part/models.py:1275 part/serializers.py:1731 part/serializers.py:1757 +#: stock/api.py:698 msgid "Assembly" msgstr "裝配" -#: build/api.py:467 +#: build/api.py:482 msgid "Tracked" msgstr "追蹤中" -#: build/api.py:470 build/serializers.py:1430 part/models.py:1275 +#: build/api.py:485 build/serializers.py:1416 part/models.py:1293 msgid "Testable" msgstr "可測試" -#: build/api.py:480 order/api.py:1006 order/api.py:1376 +#: build/api.py:495 order/api.py:1025 order/api.py:1457 order/api.py:2292 msgid "Order Outstanding" msgstr "訂單未完成" -#: build/api.py:490 build/serializers.py:1526 order/api.py:965 +#: build/api.py:505 build/serializers.py:1512 order/api.py:984 +#: order/api.py:2251 msgid "Allocated" msgstr "已分配" -#: build/api.py:499 build/models.py:1796 build/serializers.py:1443 +#: build/api.py:530 build/models.py:2213 build/serializers.py:1429 msgid "Consumed" msgstr "已消耗" -#: build/api.py:508 company/models.py:882 company/serializers.py:397 +#: build/api.py:539 company/models.py:883 company/serializers.py:450 #: templates/email/build_order_required_stock.html:19 #: templates/email/low_stock_notification.html:17 #: templates/email/part_event_notification.html:18 msgid "Available" msgstr "可用數量" -#: build/api.py:532 build/serializers.py:1528 company/serializers.py:394 -#: order/serializers.py:1344 part/serializers.py:858 part/serializers.py:1186 -#: part/serializers.py:1769 +#: build/api.py:580 build/serializers.py:1514 company/serializers.py:447 +#: order/serializers.py:1409 order/serializers.py:2727 part/serializers.py:844 +#: part/serializers.py:1199 part/serializers.py:1795 msgid "On Order" msgstr "已訂購" -#: build/api.py:685 +#: build/api.py:733 msgid "Build not found" msgstr "找不到生產記錄" -#: build/api.py:955 build/models.py:120 order/models.py:2055 +#: build/api.py:1092 build/models.py:128 order/models.py:2364 #: report/templates/report/inventree_build_order_report.html:105 -#: stock/serializers.py:93 templates/email/build_order_completed.html:16 +#: stock/serializers.py:98 templates/email/build_order_completed.html:16 #: templates/email/overdue_build_order.html:15 msgid "Build Order" msgstr "生產工單" -#: build/api.py:969 build/api.py:973 build/serializers.py:368 -#: build/serializers.py:493 build/serializers.py:563 build/serializers.py:1264 -#: build/serializers.py:1270 order/api.py:1247 order/api.py:1252 -#: order/serializers.py:846 order/serializers.py:986 order/serializers.py:2159 -#: part/serializers.py:1345 stock/api.py:986 stock/serializers.py:111 -#: stock/serializers.py:619 stock/serializers.py:739 stock/serializers.py:917 -#: stock/serializers.py:1493 stock/serializers.py:1814 -#: stock/serializers.py:1863 templates/email/stale_stock_notification.html:18 -#: users/models.py:547 +#: build/api.py:1106 build/api.py:1110 build/serializers.py:412 +#: build/serializers.py:518 build/serializers.py:569 build/serializers.py:1250 +#: build/serializers.py:1256 order/api.py:1319 order/api.py:1324 +#: order/api.py:2110 order/api.py:2115 order/serializers.py:867 +#: order/serializers.py:1007 order/serializers.py:2294 part/serializers.py:1358 +#: stock/api.py:1038 stock/serializers.py:116 stock/serializers.py:626 +#: stock/serializers.py:746 stock/serializers.py:930 stock/serializers.py:1039 +#: stock/serializers.py:1107 stock/serializers.py:1746 +#: stock/serializers.py:2019 stock/serializers.py:2147 +#: stock/serializers.py:2256 templates/email/stale_stock_notification.html:18 +#: users/models.py:545 msgid "Location" msgstr "地點" -#: build/api.py:981 part/serializers.py:1370 +#: build/api.py:1118 part/serializers.py:1383 msgid "Output" msgstr "產出" -#: build/api.py:983 +#: build/api.py:1120 msgid "Filter by output stock item ID. Use 'null' to find uninstalled build items." msgstr "依產出庫存項目 ID 篩選。使用 'null' 尋找未安裝的生產項目。" -#: build/models.py:121 users/ruleset.py:33 +#: build/models.py:129 users/ruleset.py:34 msgid "Build Orders" msgstr "生產工單" -#: build/models.py:181 +#: build/models.py:189 msgid "Assembly BOM has not been validated" msgstr "裝配物料清單尚未驗證" -#: build/models.py:188 +#: build/models.py:196 msgid "Build order cannot be created for an inactive part" msgstr "無法為未激活的零件創建生產訂單" -#: build/models.py:195 +#: build/models.py:203 msgid "Build order cannot be created for an unlocked part" msgstr "無法為已解鎖的零件創建生產訂單" -#: build/models.py:213 +#: build/models.py:221 msgid "Build orders can only be externally fulfilled for purchaseable parts" msgstr "只有可採購的零件,生產工單才可進行外部履行" -#: build/models.py:220 order/models.py:373 +#: build/models.py:228 order/models.py:422 msgid "Responsible user or group must be specified" msgstr "必須指定負責的用户或組" -#: build/models.py:225 +#: build/models.py:233 msgid "Build order part cannot be changed" msgstr "無法更改生產工單" -#: build/models.py:230 order/models.py:386 +#: build/models.py:238 order/models.py:440 msgid "Target date must be after start date" msgstr "目標日期必須晚於開始日期" -#: build/models.py:258 +#: build/models.py:266 msgid "Build Order Reference" msgstr "生產工單代號" -#: build/models.py:259 build/serializers.py:1421 order/models.py:641 -#: order/models.py:1354 order/models.py:1838 order/models.py:2795 -#: part/models.py:4121 +#: build/models.py:267 build/serializers.py:1407 order/models.py:721 +#: order/models.py:1440 order/models.py:2147 order/models.py:3294 +#: order/models.py:3736 part/models.py:4033 #: report/templates/report/inventree_bill_of_materials_report.html:139 #: report/templates/report/inventree_purchase_order_report.html:35 #: report/templates/report/inventree_return_order_report.html:26 #: report/templates/report/inventree_sales_order_report.html:28 +#: report/templates/report/inventree_transfer_order_report.html:26 msgid "Reference" msgstr "參考代號" -#: build/models.py:268 +#: build/models.py:276 msgid "Brief description of the build (optional)" msgstr "關於生產工單的簡單説明(選填)" -#: build/models.py:278 +#: build/models.py:286 msgid "Build Order to which this build is allocated" msgstr "分配此生產的生產訂單" -#: build/models.py:287 +#: build/models.py:295 msgid "Select part to build" msgstr "選擇要生產的零件" -#: build/models.py:292 +#: build/models.py:300 msgid "Sales Order Reference" msgstr "銷售訂單代號" -#: build/models.py:297 +#: build/models.py:305 msgid "Sales Order to which this build is allocated" msgstr "分配此生產的銷售訂單" -#: build/models.py:302 build/serializers.py:1093 +#: build/models.py:310 build/serializers.py:1061 order/models.py:3756 +#: order/serializers.py:2033 msgid "Source Location" msgstr "來源倉儲地點" -#: build/models.py:308 +#: build/models.py:316 msgid "Select location to take stock from for this build (leave blank to take from any stock location)" msgstr "選擇領取料件的倉儲地點(留白表示可以從任何地點領取)" -#: build/models.py:314 +#: build/models.py:322 msgid "External Build" msgstr "外部生產" -#: build/models.py:315 +#: build/models.py:323 msgid "This build order is fulfilled externally" msgstr "此生產工單由外部履行" -#: build/models.py:320 +#: build/models.py:328 order/models.py:3766 msgid "Destination Location" msgstr "目標倉儲地點" -#: build/models.py:325 +#: build/models.py:333 msgid "Select location where the completed items will be stored" msgstr "選擇已完成項目庫存地點" -#: build/models.py:329 +#: build/models.py:337 msgid "Build Quantity" msgstr "生產數量" -#: build/models.py:332 +#: build/models.py:340 msgid "Number of stock items to build" msgstr "要生產的項目數量" -#: build/models.py:336 +#: build/models.py:344 msgid "Completed items" msgstr "已完成項目" -#: build/models.py:338 +#: build/models.py:346 msgid "Number of stock items which have been completed" msgstr "已經完成的庫存品數量" -#: build/models.py:342 +#: build/models.py:350 msgid "Build Status" msgstr "生產狀態" -#: build/models.py:347 +#: build/models.py:355 msgid "Build status code" msgstr "生產狀態代碼" -#: build/models.py:356 build/serializers.py:355 order/serializers.py:862 -#: stock/models.py:1131 stock/serializers.py:85 stock/serializers.py:1666 +#: build/models.py:364 build/serializers.py:399 order/serializers.py:883 +#: stock/models.py:1239 stock/serializers.py:90 stock/serializers.py:1920 msgid "Batch Code" msgstr "批號" -#: build/models.py:360 build/serializers.py:356 +#: build/models.py:368 build/serializers.py:400 msgid "Batch code for this build output" msgstr "此產出的批號" -#: build/models.py:364 order/models.py:484 order/serializers.py:179 -#: part/models.py:1338 +#: build/models.py:372 order/models.py:545 order/serializers.py:164 +#: part/models.py:1362 stock/models.py:1320 msgid "Creation Date" msgstr "建立日期" -#: build/models.py:370 +#: build/models.py:378 msgid "Build start date" msgstr "生產開始日期" -#: build/models.py:371 +#: build/models.py:379 msgid "Scheduled start date for this build order" msgstr "預計此生產工單的開始日期" -#: build/models.py:377 +#: build/models.py:385 msgid "Target completion date" msgstr "目標完成日期" -#: build/models.py:379 +#: build/models.py:387 msgid "Target date for build completion. Build will be overdue after this date." msgstr "生產的預計完成日期。若超過此日期則工單會逾期。" -#: build/models.py:384 order/models.py:694 order/models.py:2834 +#: build/models.py:392 order/models.py:769 order/models.py:3333 +#: order/models.py:3785 msgid "Completion Date" msgstr "完成日期" -#: build/models.py:392 +#: build/models.py:400 msgid "completed by" msgstr "完成者" -#: build/models.py:401 +#: build/models.py:409 msgid "Issued by" msgstr "發布者" -#: build/models.py:402 +#: build/models.py:410 msgid "User who issued this build order" msgstr "發布此生產工單的使用者" -#: build/models.py:419 common/models.py:189 order/api.py:184 -#: order/models.py:516 part/models.py:1355 +#: build/models.py:427 common/models.py:195 order/api.py:187 +#: order/models.py:577 part/models.py:1379 #: report/templates/report/inventree_build_order_report.html:158 msgid "Responsible" msgstr "負責人" -#: build/models.py:420 +#: build/models.py:428 msgid "User or group responsible for this build order" msgstr "負責此生產工單的使用者或羣組" -#: build/models.py:425 stock/models.py:1124 +#: build/models.py:433 stock/models.py:1232 msgid "External Link" msgstr "外部連結" -#: build/models.py:427 common/models.py:2089 part/models.py:1177 -#: stock/models.py:1126 +#: build/models.py:435 common/models.py:2148 part/models.py:1194 +#: stock/models.py:1234 msgid "Link to external URL" msgstr "外部URL連結" -#: build/models.py:432 +#: build/models.py:440 msgid "Build Priority" msgstr "製造優先度" -#: build/models.py:435 +#: build/models.py:443 msgid "Priority of this build order" msgstr "此生產工單的優先程度" -#: build/models.py:443 common/models.py:159 common/models.py:173 -#: order/api.py:170 order/models.py:456 order/models.py:1870 +#: build/models.py:451 common/models.py:159 common/models.py:173 +#: order/api.py:173 order/models.py:517 order/models.py:2179 msgid "Project Code" msgstr "專案代碼" -#: build/models.py:444 +#: build/models.py:452 msgid "Project code for this build order" msgstr "此生產工單隸屬的專案代碼" -#: build/models.py:697 +#: build/models.py:989 msgid "Cannot complete build order with open child builds" msgstr "無法完成仍有未結束子工單的生產工單" -#: build/models.py:702 +#: build/models.py:994 msgid "Cannot complete build order with incomplete outputs" msgstr "無法完成有未完成產出的生產工單" -#: build/models.py:721 build/models.py:851 -msgid "Failed to offload task to complete build allocations" -msgstr "未能卸載任務以完成生產分配" - -#: build/models.py:744 -#, python-brace-format -msgid "Build order {build} has been completed" -msgstr "生產工單 {build} 已經完成" - -#: build/models.py:750 -msgid "A build order has been completed" -msgstr "一張生產工單已經完成" - -#: build/models.py:932 build/serializers.py:403 +#: build/models.py:1131 msgid "Serial numbers must be provided for trackable parts" msgstr "對於可跟蹤的零件,必須提供序列號" -#: build/models.py:1024 build/models.py:1113 +#: build/models.py:1223 build/models.py:1309 msgid "No build output specified" msgstr "未指定產出" -#: build/models.py:1027 +#: build/models.py:1226 msgid "Build output is already completed" msgstr "產出已完成" -#: build/models.py:1030 +#: build/models.py:1229 build/models.py:1318 build/models.py:1396 msgid "Build output does not match Build Order" msgstr "產出與生產訂單不匹配" -#: build/models.py:1120 build/models.py:1226 build/serializers.py:281 -#: build/serializers.py:331 build/serializers.py:961 build/serializers.py:1740 -#: order/models.py:744 order/serializers.py:632 order/serializers.py:857 -#: part/models.py:3934 stock/models.py:971 stock/models.py:1461 -#: stock/models.py:1926 stock/serializers.py:717 stock/serializers.py:1655 +#: build/models.py:1315 build/models.py:1393 +msgid "Build output has already been completed" +msgstr "" + +#: build/models.py:1325 build/models.py:1426 build/serializers.py:321 +#: build/serializers.py:375 build/serializers.py:918 build/serializers.py:1726 +#: order/models.py:819 order/serializers.py:643 order/serializers.py:878 +#: part/models.py:3831 stock/models.py:1079 stock/models.py:1504 +#: stock/models.py:1588 stock/models.py:1906 stock/models.py:2117 +#: stock/models.py:2440 stock/serializers.py:724 stock/serializers.py:1030 +#: stock/serializers.py:1092 stock/serializers.py:1909 msgid "Quantity must be greater than zero" msgstr "數量必須大於零" -#: build/models.py:1124 build/models.py:1231 build/serializers.py:286 +#: build/models.py:1329 build/models.py:1431 build/serializers.py:326 msgid "Quantity cannot be greater than the output quantity" msgstr "數量不能大於輸出數量" -#: build/models.py:1199 build/serializers.py:602 +#: build/models.py:1405 msgid "Build output has not passed all required tests" msgstr "此產出尚未通過所有必要測試" -#: build/models.py:1202 build/serializers.py:597 -#, python-brace-format -msgid "Build output {serial} has not passed all required tests" -msgstr "產出 {serial} 未通過所有必要測試" - -#: build/models.py:1213 +#: build/models.py:1413 msgid "Allocated stock items are still in production" msgstr "已分配的庫存項目仍在生產中" -#: build/models.py:1221 +#: build/models.py:1420 msgid "Cannot partially complete a build output with allocated items" msgstr "無法部分完成具有已分配項目的生產產出" -#: build/models.py:1750 +#: build/models.py:1603 order/models.py:4208 order/serializers.py:1997 +#: order/serializers.py:2848 stock/models.py:1494 stock/models.py:1898 +#: stock/models.py:2121 stock/models.py:2444 stock/models.py:2738 +msgid "Stock item no longer exists" +msgstr "" + +#: build/models.py:1621 build/serializers.py:966 order/serializers.py:1775 +#: order/serializers.py:2804 +#, python-brace-format +msgid "Available quantity ({q}) exceeded" +msgstr "可用量 ({q}) 超出限制" + +#: build/models.py:2167 msgid "Build Order Line Item" msgstr "生產訂單行項目" -#: build/models.py:1775 +#: build/models.py:2192 msgid "Build object" msgstr "生產對象" -#: build/models.py:1787 build/models.py:2112 build/serializers.py:267 -#: build/serializers.py:316 build/serializers.py:1442 common/models.py:1373 -#: order/models.py:1810 order/models.py:2678 order/serializers.py:1793 -#: order/serializers.py:2252 part/models.py:3494 part/models.py:4069 +#: build/models.py:2204 build/models.py:2484 build/serializers.py:307 +#: build/serializers.py:360 build/serializers.py:1428 common/models.py:1379 +#: order/models.py:2110 order/models.py:3185 order/models.py:4175 +#: order/serializers.py:1884 order/serializers.py:2388 +#: order/serializers.py:2974 part/models.py:3383 part/models.py:3971 #: report/templates/report/inventree_bill_of_materials_report.html:138 #: report/templates/report/inventree_build_order_report.html:113 #: report/templates/report/inventree_purchase_order_report.html:36 @@ -1017,451 +1081,472 @@ msgstr "生產對象" #: report/templates/report/inventree_stock_report_merge.html:113 #: report/templates/report/inventree_test_report.html:90 #: report/templates/report/inventree_test_report.html:169 -#: stock/serializers.py:136 stock/serializers.py:180 stock/serializers.py:705 +#: report/templates/report/inventree_transfer_order_report.html:27 +#: stock/serializers.py:141 stock/serializers.py:185 stock/serializers.py:712 +#: stock/serializers.py:1023 stock/serializers.py:1080 #: templates/email/build_order_completed.html:18 #: templates/email/stale_stock_notification.html:19 msgid "Quantity" msgstr "數量" -#: build/models.py:1788 +#: build/models.py:2205 msgid "Required quantity for build order" msgstr "生產工單所需數量" -#: build/models.py:1797 +#: build/models.py:2214 msgid "Quantity of consumed stock" msgstr "已消耗庫存數量" -#: build/models.py:1898 +#: build/models.py:2315 msgid "Build item must specify a build output, as master part is marked as trackable" msgstr "生產項必須指定產出,因為主零件已經被標記為可追蹤的" -#: build/models.py:1961 +#: build/models.py:2378 build/serializers.py:949 msgid "Selected stock item does not match BOM line" msgstr "選擇的庫存品項和BOM的項目不符" -#: build/models.py:1980 +#: build/models.py:2397 msgid "Allocated quantity must be greater than zero" msgstr "分配數量必須大於零" -#: build/models.py:1986 +#: build/models.py:2403 msgid "Quantity must be 1 for serialized stock" msgstr "有序號的品項數量必須為1" -#: build/models.py:1996 +#: build/models.py:2413 #, python-brace-format msgid "Allocated quantity ({q}) must not exceed available stock quantity ({a})" msgstr "分配的數量({q})不能超過可用的庫存數量({a})" -#: build/models.py:2013 order/models.py:2627 +#: build/models.py:2430 order/models.py:3134 order/models.py:4139 msgid "Stock item is over-allocated" msgstr "庫存品項超額分配" -#: build/models.py:2102 build/serializers.py:944 build/serializers.py:1231 -#: order/serializers.py:1621 order/serializers.py:1642 +#: build/models.py:2474 build/serializers.py:901 build/serializers.py:1217 +#: order/serializers.py:1712 order/serializers.py:1733 +#: order/serializers.py:2750 order/serializers.py:2771 #: report/templates/report/inventree_sales_order_shipment_report.html:29 -#: stock/api.py:1417 stock/models.py:445 stock/serializers.py:102 -#: stock/serializers.py:829 stock/serializers.py:1349 stock/serializers.py:1461 +#: stock/api.py:1472 stock/models.py:470 stock/serializers.py:107 +#: stock/serializers.py:842 stock/serializers.py:1598 stock/serializers.py:1714 msgid "Stock Item" msgstr "庫存品項" -#: build/models.py:2103 +#: build/models.py:2475 msgid "Source stock item" msgstr "來源庫存項目" -#: build/models.py:2113 +#: build/models.py:2485 msgid "Stock quantity to allocate to build" msgstr "要分配的庫存數量" -#: build/models.py:2122 +#: build/models.py:2494 msgid "Install into" msgstr "安裝到" -#: build/models.py:2123 +#: build/models.py:2495 msgid "Destination stock item" msgstr "目的庫存品項" -#: build/serializers.py:116 +#: build/serializers.py:131 msgid "Build Level" msgstr "構建等級" -#: build/serializers.py:130 part/serializers.py:1272 +#: build/serializers.py:145 part/serializers.py:1285 msgid "Part Name" msgstr "零件名稱" -#: build/serializers.py:215 build/serializers.py:970 +#: build/serializers.py:247 build/serializers.py:928 msgid "Build Output" msgstr "產出" -#: build/serializers.py:227 +#: build/serializers.py:259 msgid "Build output does not match the parent build" msgstr "產出與之前的生產不匹配" -#: build/serializers.py:231 +#: build/serializers.py:263 msgid "Output part does not match BuildOrder part" msgstr "產出零件與生產訂單零件不匹配" -#: build/serializers.py:235 +#: build/serializers.py:267 msgid "This build output has already been completed" msgstr "此產出已經完成" -#: build/serializers.py:249 +#: build/serializers.py:281 msgid "This build output is not fully allocated" msgstr "此產出尚未完全分配" -#: build/serializers.py:268 build/serializers.py:317 +#: build/serializers.py:308 build/serializers.py:361 msgid "Enter quantity for build output" msgstr "輸入產出數量" -#: build/serializers.py:339 +#: build/serializers.py:383 msgid "Integer quantity required for trackable parts" msgstr "可追蹤的零件數量必須為整數" -#: build/serializers.py:345 +#: build/serializers.py:389 msgid "Integer quantity required, as the bill of materials contains trackable parts" msgstr "因為BOM包含可追蹤的零件,所以數量必須為整數" -#: build/serializers.py:362 order/serializers.py:878 order/serializers.py:1797 -#: stock/serializers.py:728 +#: build/serializers.py:406 order/serializers.py:899 order/serializers.py:1888 +#: order/serializers.py:2978 stock/serializers.py:735 msgid "Serial Numbers" msgstr "序號" -#: build/serializers.py:363 +#: build/serializers.py:407 msgid "Enter serial numbers for build outputs" msgstr "輸出產出的序列號" -#: build/serializers.py:369 +#: build/serializers.py:413 msgid "Stock location for build output" msgstr "生產輸出的庫存地點" -#: build/serializers.py:384 +#: build/serializers.py:428 msgid "Auto Allocate Serial Numbers" msgstr "自動分配序號" -#: build/serializers.py:386 +#: build/serializers.py:430 msgid "Automatically allocate required items with matching serial numbers" msgstr "自動為需要項目分配對應的序號" -#: build/serializers.py:419 order/serializers.py:964 stock/api.py:1186 -#: stock/models.py:1949 +#: build/serializers.py:456 order/serializers.py:985 stock/api.py:1240 +#: stock/models.py:730 stock/models.py:2467 msgid "The following serial numbers already exist or are invalid" msgstr "序號已存在或無效" -#: build/serializers.py:461 build/serializers.py:517 build/serializers.py:609 +#: build/serializers.py:498 build/serializers.py:542 build/serializers.py:600 msgid "A list of build outputs must be provided" msgstr "必須提供產出清單" -#: build/serializers.py:494 +#: build/serializers.py:519 msgid "Stock location for scrapped outputs" msgstr "廢品產出的庫存位置" -#: build/serializers.py:500 +#: build/serializers.py:525 msgid "Discard Allocations" msgstr "放棄分配" -#: build/serializers.py:501 +#: build/serializers.py:526 msgid "Discard any stock allocations for scrapped outputs" msgstr "取消對廢品產出的任何庫存分配" -#: build/serializers.py:506 +#: build/serializers.py:531 msgid "Reason for scrapping build output(s)" msgstr "廢品產出的原因" -#: build/serializers.py:564 +#: build/serializers.py:570 msgid "Location for completed build outputs" msgstr "已完成刪除的庫存地點" -#: build/serializers.py:572 +#: build/serializers.py:577 stock/serializers.py:945 stock/serializers.py:2027 +#: stock/serializers.py:2155 stock/serializers.py:2264 +msgid "Structural locations cannot be assigned stock items" +msgstr "" + +#: build/serializers.py:587 order/serializers.py:2561 msgid "Accept Incomplete Allocation" msgstr "接受不完整的分配" -#: build/serializers.py:573 +#: build/serializers.py:588 msgid "Complete outputs if stock has not been fully allocated" msgstr "如果庫存尚未全部分配,則完成產出" -#: build/serializers.py:698 +#: build/serializers.py:653 msgid "Consume Allocated Stock" msgstr "消費已分配的庫存" -#: build/serializers.py:699 +#: build/serializers.py:654 msgid "Consume any stock which has already been allocated to this build" msgstr "消耗已分配給此生產的任何庫存" -#: build/serializers.py:705 +#: build/serializers.py:660 msgid "Remove Incomplete Outputs" msgstr "移除未完成的產出" -#: build/serializers.py:706 +#: build/serializers.py:661 msgid "Delete any build outputs which have not been completed" msgstr "刪除所有未完成的產出" -#: build/serializers.py:733 +#: build/serializers.py:688 msgid "Not permitted" msgstr "不允許" -#: build/serializers.py:734 +#: build/serializers.py:689 msgid "Accept as consumed by this build order" msgstr "接受作為此生產訂單的消費" -#: build/serializers.py:735 +#: build/serializers.py:690 msgid "Deallocate before completing this build order" msgstr "完成此生產訂單前取消分配" -#: build/serializers.py:762 +#: build/serializers.py:717 msgid "Overallocated Stock" msgstr "超出分配的庫存" -#: build/serializers.py:765 +#: build/serializers.py:720 msgid "How do you want to handle extra stock items assigned to the build order" msgstr "如何處理分配給生產訂單的額外庫存項" -#: build/serializers.py:776 +#: build/serializers.py:731 msgid "Some stock items have been overallocated" msgstr "有庫存項目已被過度分配" -#: build/serializers.py:781 +#: build/serializers.py:736 msgid "Accept Unallocated" msgstr "接受未分配" -#: build/serializers.py:783 +#: build/serializers.py:738 msgid "Accept that stock items have not been fully allocated to this build order" msgstr "接受庫存項未被完全分配至生產訂單" -#: build/serializers.py:794 +#: build/serializers.py:749 msgid "Required stock has not been fully allocated" msgstr "所需庫存尚未完全分配" -#: build/serializers.py:799 order/serializers.py:508 order/serializers.py:1698 +#: build/serializers.py:754 order/serializers.py:525 order/serializers.py:1789 msgid "Accept Incomplete" msgstr "接受不完整" -#: build/serializers.py:801 +#: build/serializers.py:756 msgid "Accept that the required number of build outputs have not been completed" msgstr "允許所需數量的產出未完成" -#: build/serializers.py:812 +#: build/serializers.py:767 msgid "Required build quantity has not been completed" msgstr "未完成所需生產數量" -#: build/serializers.py:824 +#: build/serializers.py:779 msgid "Build order has open child build orders" msgstr "生產訂單有打開的子生產訂單" -#: build/serializers.py:827 +#: build/serializers.py:782 msgid "Build order must be in production state" msgstr "生產訂單必須處於生產狀態" -#: build/serializers.py:830 +#: build/serializers.py:785 msgid "Build order has incomplete outputs" msgstr "生產訂單有未完成的產出" -#: build/serializers.py:869 +#: build/serializers.py:824 msgid "Build Line" msgstr "生產行" -#: build/serializers.py:877 +#: build/serializers.py:832 msgid "Build output" msgstr "產出" -#: build/serializers.py:885 +#: build/serializers.py:840 msgid "Build output must point to the same build" msgstr "生產產出必須指向相同的生產" -#: build/serializers.py:916 +#: build/serializers.py:872 msgid "Build Line Item" msgstr "生產行項目" -#: build/serializers.py:934 +#: build/serializers.py:890 msgid "bom_item.part must point to the same part as the build order" msgstr "bom_item.part 必須與生產訂單零件相同" -#: build/serializers.py:950 stock/serializers.py:1362 +#: build/serializers.py:907 stock/serializers.py:1611 msgid "Item must be in stock" msgstr "商品必須有庫存" -#: build/serializers.py:993 order/serializers.py:1684 -#, python-brace-format -msgid "Available quantity ({q}) exceeded" -msgstr "可用量 ({q}) 超出限制" - -#: build/serializers.py:999 +#: build/serializers.py:972 msgid "Build output must be specified for allocation of tracked parts" msgstr "對於被追蹤的零件的分配,必須指定生產產出" -#: build/serializers.py:1007 +#: build/serializers.py:980 msgid "Build output cannot be specified for allocation of untracked parts" msgstr "對於未被追蹤的零件,無法指定生產產出" -#: build/serializers.py:1031 order/serializers.py:1967 +#: build/serializers.py:1029 order/serializers.py:1977 +#: order/serializers.py:2829 msgid "Allocation items must be provided" msgstr "必須提供分配項目" -#: build/serializers.py:1095 +#: build/serializers.py:1063 msgid "Stock location where parts are to be sourced (leave blank to take from any location)" msgstr "零件來源的庫存地點(留空則可來源於任何庫存地點)" -#: build/serializers.py:1104 +#: build/serializers.py:1072 order/serializers.py:2044 msgid "Exclude Location" msgstr "排除位置" -#: build/serializers.py:1105 +#: build/serializers.py:1073 msgid "Exclude stock items from this selected location" msgstr "從該選定的庫存地點排除庫存項" -#: build/serializers.py:1110 +#: build/serializers.py:1078 order/serializers.py:2059 msgid "Interchangeable Stock" msgstr "可互換庫存" -#: build/serializers.py:1111 +#: build/serializers.py:1079 msgid "Stock items in multiple locations can be used interchangeably" msgstr "在多個位置的庫存項目可以互換使用" -#: build/serializers.py:1116 +#: build/serializers.py:1084 msgid "Substitute Stock" msgstr "替代品庫存" -#: build/serializers.py:1117 +#: build/serializers.py:1085 msgid "Allow allocation of substitute parts" msgstr "允許分配可替換的零件" -#: build/serializers.py:1122 +#: build/serializers.py:1090 msgid "Optional Items" msgstr "可選項目" -#: build/serializers.py:1123 +#: build/serializers.py:1091 msgid "Allocate optional BOM items to build order" msgstr "分配可選的物料清單給生產訂單" -#: build/serializers.py:1129 +#: build/serializers.py:1097 msgid "All Items" msgstr "全部品項" -#: build/serializers.py:1130 +#: build/serializers.py:1098 msgid "Untracked Items" msgstr "未追蹤項目" -#: build/serializers.py:1131 +#: build/serializers.py:1099 msgid "Tracked Items" msgstr "已追蹤項目" -#: build/serializers.py:1133 +#: build/serializers.py:1101 msgid "Item Type" msgstr "品項類型" -#: build/serializers.py:1134 +#: build/serializers.py:1102 msgid "Select item type to auto-allocate" msgstr "選擇要自動分配的項目類型" -#: build/serializers.py:1188 +#: build/serializers.py:1108 order/serializers.py:2068 +msgid "Stock Priority" +msgstr "" + +#: build/serializers.py:1109 order/serializers.py:2069 +msgid "Preferred order in which matching stock items are consumed" +msgstr "" + +#: build/serializers.py:1117 +msgid "Build Lines" +msgstr "" + +#: build/serializers.py:1119 +msgid "Limit allocation to these build lines (leave blank to allocate all lines)" +msgstr "" + +#: build/serializers.py:1174 msgid "BOM Reference" msgstr "物料清單參考" -#: build/serializers.py:1194 +#: build/serializers.py:1180 msgid "BOM Part ID" msgstr "物料清單零件識別號碼" -#: build/serializers.py:1201 +#: build/serializers.py:1187 msgid "BOM Part Name" msgstr "物料清單零件名稱" -#: build/serializers.py:1253 +#: build/serializers.py:1239 msgid "Install Into" msgstr "安裝至" -#: build/serializers.py:1282 build/serializers.py:1511 +#: build/serializers.py:1268 build/serializers.py:1497 msgid "Build" msgstr "生產" -#: build/serializers.py:1302 company/models.py:638 order/api.py:324 -#: order/api.py:329 order/api.py:556 order/serializers.py:624 -#: stock/models.py:1067 stock/serializers.py:586 +#: build/serializers.py:1288 company/models.py:641 order/api.py:329 +#: order/api.py:334 order/api.py:561 order/serializers.py:635 +#: stock/models.py:1175 stock/serializers.py:593 msgid "Supplier Part" msgstr "供應商零件" -#: build/serializers.py:1318 stock/serializers.py:649 +#: build/serializers.py:1304 stock/serializers.py:656 msgid "Allocated Quantity" msgstr "已分配數量" -#: build/serializers.py:1385 +#: build/serializers.py:1371 msgid "Build Reference" msgstr "構建參考" -#: build/serializers.py:1395 +#: build/serializers.py:1381 msgid "Part Category Name" msgstr "零件類別名稱" -#: build/serializers.py:1433 common/setting/system.py:487 part/models.py:1269 +#: build/serializers.py:1419 common/setting/system.py:500 part/models.py:1287 msgid "Trackable" msgstr "可追蹤" -#: build/serializers.py:1436 +#: build/serializers.py:1422 msgid "Inherited" msgstr "已繼承的" -#: build/serializers.py:1439 part/models.py:4154 +#: build/serializers.py:1425 part/models.py:4066 msgid "Allow Variants" msgstr "允許變體" -#: build/serializers.py:1445 build/serializers.py:1451 part/models.py:3813 -#: part/models.py:4458 stock/api.py:881 +#: build/serializers.py:1431 build/serializers.py:1437 part/models.py:3705 +#: part/models.py:4387 stock/api.py:936 stock/serializers.py:1014 msgid "BOM Item" msgstr "物料清單項" -#: build/serializers.py:1529 order/serializers.py:1345 part/serializers.py:1190 -#: part/serializers.py:1773 +#: build/serializers.py:1515 order/serializers.py:1410 +#: order/serializers.py:2728 part/serializers.py:1203 part/serializers.py:1799 msgid "In Production" msgstr "生產中" -#: build/serializers.py:1531 part/serializers.py:849 part/serializers.py:1194 +#: build/serializers.py:1517 part/serializers.py:835 part/serializers.py:1207 msgid "Scheduled to Build" msgstr "排程生產中" -#: build/serializers.py:1534 part/serializers.py:882 +#: build/serializers.py:1520 part/serializers.py:868 msgid "External Stock" msgstr "外部庫存" -#: build/serializers.py:1535 part/serializers.py:1180 part/serializers.py:1836 +#: build/serializers.py:1521 part/serializers.py:1193 part/serializers.py:1862 msgid "Available Stock" msgstr "可用庫存" -#: build/serializers.py:1537 +#: build/serializers.py:1523 msgid "Available Substitute Stock" msgstr "可用的替代品庫存" -#: build/serializers.py:1540 +#: build/serializers.py:1526 msgid "Available Variant Stock" msgstr "可用的變體庫存" -#: build/serializers.py:1753 +#: build/serializers.py:1739 msgid "Consumed quantity exceeds allocated quantity" msgstr "消耗數量超過已分配數量" -#: build/serializers.py:1790 +#: build/serializers.py:1776 msgid "Optional notes for the stock consumption" msgstr "庫存耗用的可選備註" -#: build/serializers.py:1807 +#: build/serializers.py:1793 msgid "Build item must point to the correct build order" msgstr "生產項必須指向正確的生產工單" -#: build/serializers.py:1812 +#: build/serializers.py:1798 msgid "Duplicate build item allocation" msgstr "重複的生產項分配" -#: build/serializers.py:1830 +#: build/serializers.py:1816 msgid "Build line must point to the correct build order" msgstr "生產行必須指向正確的生產工單" -#: build/serializers.py:1835 +#: build/serializers.py:1821 msgid "Duplicate build line allocation" msgstr "重複的生產行分配" -#: build/serializers.py:1847 +#: build/serializers.py:1833 msgid "At least one item or line must be provided" msgstr "至少必須提供一個項目或一行" #: build/status_codes.py:11 generic/states/tests.py:21 #: generic/states/tests.py:131 order/status_codes.py:12 -#: order/status_codes.py:44 order/status_codes.py:76 order/status_codes.py:102 +#: order/status_codes.py:44 order/status_codes.py:77 order/status_codes.py:103 +#: order/status_codes.py:125 msgid "Pending" msgstr "待定" @@ -1470,59 +1555,76 @@ msgid "Production" msgstr "生產" #: build/status_codes.py:13 order/status_codes.py:14 order/status_codes.py:51 -#: order/status_codes.py:81 +#: order/status_codes.py:82 order/status_codes.py:127 msgid "On Hold" msgstr "被掛起" #: build/status_codes.py:14 order/status_codes.py:16 order/status_codes.py:53 -#: order/status_codes.py:84 +#: order/status_codes.py:85 order/status_codes.py:129 msgid "Cancelled" msgstr "已取消" -#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:587 +#: build/status_codes.py:15 generic/states/tests.py:23 importer/models.py:693 #: importer/status_codes.py:27 order/status_codes.py:15 -#: order/status_codes.py:52 order/status_codes.py:83 +#: order/status_codes.py:52 order/status_codes.py:84 order/status_codes.py:128 msgid "Complete" msgstr "完成" -#: build/tasks.py:218 +#: build/tasks.py:350 +#, python-brace-format +msgid "Build order {build} has been completed" +msgstr "生產工單 {build} 已經完成" + +#: build/tasks.py:356 +msgid "A build order has been completed" +msgstr "一張生產工單已經完成" + +#: build/tasks.py:487 msgid "Stock required for build order" msgstr "生產訂單所需庫存" -#: build/tasks.py:228 +#: build/tasks.py:497 #, python-brace-format msgid "Build order {build} requires additional stock" msgstr "生產工單 {build} 需要額外庫存" -#: build/tasks.py:252 +#: build/tasks.py:521 msgid "Overdue Build Order" msgstr "逾期的生產訂單" -#: build/tasks.py:257 +#: build/tasks.py:526 #, python-brace-format msgid "Build order {bo} is now overdue" msgstr "生產訂單 {bo} 現已逾期" -#: common/api.py:722 +#: common/api.py:764 +msgid "Has Thumbnail" +msgstr "" + +#: common/api.py:773 msgid "Is Link" msgstr "是否鏈接" -#: common/api.py:730 +#: common/api.py:781 msgid "Is File" msgstr "是否為文件" -#: common/api.py:777 +#: common/api.py:828 msgid "User does not have permission to delete these attachments" msgstr "用户沒有權限刪除此附件" -#: common/api.py:790 +#: common/api.py:841 msgid "User does not have permission to edit this attachment" msgstr "" -#: common/api.py:816 +#: common/api.py:867 msgid "User does not have permission to delete this attachment" msgstr "用户沒有權限刪除此附件" +#: common/api.py:1244 common/serializers.py:1017 common/serializers.py:1065 +msgid "Selection list is locked" +msgstr "選擇列表已鎖定" + #: common/currency.py:135 msgid "Invalid currency code" msgstr "無效的貨幣代碼" @@ -1539,15 +1641,20 @@ msgstr "未提供有效的貨幣代碼" msgid "No plugin" msgstr "暫無插件" -#: common/filters.py:359 +#: common/filters.py:110 company/api.py:155 company/api.py:311 stock/api.py:415 +#: stock/api.py:1070 +msgid "Tags" +msgstr "" + +#: common/filters.py:390 msgid "Project Code Label" msgstr "項目編碼標籤" -#: common/models.py:108 common/models.py:133 common/models.py:3279 +#: common/models.py:108 common/models.py:133 common/models.py:3475 msgid "Updated" msgstr "已是最新" -#: common/models.py:109 common/models.py:134 order/models.py:507 +#: common/models.py:109 common/models.py:134 order/models.py:568 msgid "Timestamp of last update" msgstr "最後更新時間戳" @@ -1567,794 +1674,844 @@ msgstr "唯一項目編碼" msgid "Project description" msgstr "項目描述" -#: common/models.py:190 -msgid "User or group responsible for this project" -msgstr "負責此項目的用户或羣組" - -#: common/models.py:789 common/models.py:1305 common/models.py:1343 -msgid "Settings key" -msgstr "設定鍵值" - -#: common/models.py:793 -msgid "Settings value" -msgstr "設定值" - -#: common/models.py:848 -msgid "Chosen value is not a valid option" -msgstr "所選值不是一個有效的選項" - -#: common/models.py:864 -msgid "Value must be a boolean value" -msgstr "該值必須是布爾值" - -#: common/models.py:872 -msgid "Value must be an integer value" -msgstr "該值必須為整數" - -#: common/models.py:880 -msgid "Value must be a valid number" -msgstr "值必須為有效數字" - -#: common/models.py:905 -msgid "Value does not pass validation checks" -msgstr "值未通過驗證檢查" - -#: common/models.py:927 -msgid "Key string must be unique" -msgstr "鍵字符串必須是唯一的" - -#: common/models.py:1351 common/models.py:1352 common/models.py:1456 -#: common/models.py:1457 common/models.py:1702 common/models.py:1703 -#: common/models.py:2105 common/models.py:2106 common/models.py:2932 -#: importer/models.py:101 part/models.py:3588 part/models.py:3616 -#: plugin/models.py:355 plugin/models.py:356 -#: report/templates/report/inventree_test_report.html:105 users/models.py:124 -#: users/models.py:499 -msgid "User" -msgstr "使用者" - -#: common/models.py:1374 -msgid "Price break quantity" -msgstr "批發價數量" - -#: common/models.py:1381 company/serializers.py:299 order/models.py:1907 -#: order/models.py:3131 -msgid "Price" -msgstr "價格" - -#: common/models.py:1382 -msgid "Unit price at specified quantity" -msgstr "指定數量的單位價格" - -#: common/models.py:1433 common/models.py:1618 -msgid "Endpoint" -msgstr "端點" - -#: common/models.py:1434 -msgid "Endpoint at which this webhook is received" -msgstr "接收此網絡鈎子的端點" - -#: common/models.py:1444 -msgid "Name for this webhook" -msgstr "此網絡鈎子的名稱" - -#: common/models.py:1448 common/models.py:2346 common/models.py:2481 -#: company/models.py:194 company/models.py:786 machine/models.py:40 -#: part/models.py:1292 plugin/models.py:69 stock/api.py:641 users/models.py:193 -#: users/models.py:552 users/serializers.py:339 users/serializers.py:431 +#: common/models.py:186 common/models.py:1460 common/models.py:2472 +#: common/models.py:2607 company/models.py:194 company/models.py:787 +#: machine/models.py:43 part/models.py:1310 plugin/models.py:69 +#: stock/api.py:701 users/models.py:191 users/models.py:550 +#: users/serializers.py:349 users/serializers.py:470 msgid "Active" msgstr "激活" -#: common/models.py:1448 +#: common/models.py:187 +msgid "Is this project code active?" +msgstr "" + +#: common/models.py:196 +msgid "User or group responsible for this project" +msgstr "負責此項目的用户或羣組" + +#: common/models.py:795 common/models.py:1311 common/models.py:1349 +msgid "Settings key" +msgstr "設定鍵值" + +#: common/models.py:799 +msgid "Settings value" +msgstr "設定值" + +#: common/models.py:854 +msgid "Chosen value is not a valid option" +msgstr "所選值不是一個有效的選項" + +#: common/models.py:870 +msgid "Value must be a boolean value" +msgstr "該值必須是布爾值" + +#: common/models.py:878 +msgid "Value must be an integer value" +msgstr "該值必須為整數" + +#: common/models.py:886 +msgid "Value must be a valid number" +msgstr "值必須為有效數字" + +#: common/models.py:911 +msgid "Value does not pass validation checks" +msgstr "值未通過驗證檢查" + +#: common/models.py:933 +msgid "Key string must be unique" +msgstr "鍵字符串必須是唯一的" + +#: common/models.py:1357 common/models.py:1358 common/models.py:1468 +#: common/models.py:1469 common/models.py:1716 common/models.py:1717 +#: common/models.py:2164 common/models.py:2165 common/models.py:3123 +#: importer/models.py:105 part/models.py:3478 part/models.py:3506 +#: plugin/models.py:392 plugin/models.py:393 +#: report/templates/report/inventree_test_report.html:105 users/models.py:122 +#: users/models.py:497 +msgid "User" +msgstr "使用者" + +#: common/models.py:1380 +msgid "Price break quantity" +msgstr "批發價數量" + +#: common/models.py:1387 company/serializers.py:348 order/models.py:2216 +#: order/models.py:3623 +msgid "Price" +msgstr "價格" + +#: common/models.py:1388 +msgid "Unit price at specified quantity" +msgstr "指定數量的單位價格" + +#: common/models.py:1445 common/models.py:1630 +msgid "Endpoint" +msgstr "端點" + +#: common/models.py:1446 +msgid "Endpoint at which this webhook is received" +msgstr "接收此網絡鈎子的端點" + +#: common/models.py:1456 +msgid "Name for this webhook" +msgstr "此網絡鈎子的名稱" + +#: common/models.py:1460 msgid "Is this webhook active" msgstr "網絡鈎子是否已啓用" -#: common/models.py:1464 users/models.py:172 +#: common/models.py:1476 users/models.py:170 msgid "Token" msgstr "令牌" -#: common/models.py:1465 +#: common/models.py:1477 msgid "Token for access" msgstr "訪問令牌" -#: common/models.py:1473 +#: common/models.py:1485 msgid "Secret" msgstr "密鑰" -#: common/models.py:1474 +#: common/models.py:1486 msgid "Shared secret for HMAC" msgstr "HMAC共享密鑰" -#: common/models.py:1582 common/models.py:3169 +#: common/models.py:1594 common/models.py:3360 msgid "Message ID" msgstr "消息ID" -#: common/models.py:1583 common/models.py:3159 +#: common/models.py:1595 common/models.py:3350 msgid "Unique identifier for this message" msgstr "此郵件的唯一標識符" -#: common/models.py:1591 +#: common/models.py:1603 msgid "Host" msgstr "主機" -#: common/models.py:1592 +#: common/models.py:1604 msgid "Host from which this message was received" msgstr "接收此消息的主機" -#: common/models.py:1600 +#: common/models.py:1612 msgid "Header" msgstr "標題" -#: common/models.py:1601 +#: common/models.py:1613 msgid "Header of this message" msgstr "此消息的標題" -#: common/models.py:1608 +#: common/models.py:1620 msgid "Body" msgstr "正文" -#: common/models.py:1609 +#: common/models.py:1621 msgid "Body of this message" msgstr "此消息的正文" -#: common/models.py:1619 +#: common/models.py:1631 msgid "Endpoint on which this message was received" msgstr "接收此消息的終點" -#: common/models.py:1624 +#: common/models.py:1636 msgid "Worked on" msgstr "工作於" -#: common/models.py:1625 +#: common/models.py:1637 msgid "Was the work on this message finished?" msgstr "這條消息的工作完成了嗎?" -#: common/models.py:1751 +#: common/models.py:1732 +msgid "Optional explicit URL associated with this notification" +msgstr "" + +#: common/models.py:1772 msgid "Id" msgstr "標識" -#: common/models.py:1753 +#: common/models.py:1774 msgid "Title" msgstr "標題" -#: common/models.py:1755 common/models.py:2088 company/models.py:188 -#: company/models.py:479 company/models.py:549 company/models.py:809 -#: order/models.py:462 order/models.py:1851 order/models.py:2426 -#: part/models.py:1176 +#: common/models.py:1776 common/models.py:2147 company/models.py:188 +#: company/models.py:483 company/models.py:554 company/models.py:810 +#: order/models.py:523 order/models.py:2160 order/models.py:2736 +#: part/models.py:1193 #: report/templates/report/inventree_build_order_report.html:164 msgid "Link" msgstr "連結" -#: common/models.py:1757 +#: common/models.py:1778 msgid "Published" msgstr "已發佈" -#: common/models.py:1759 +#: common/models.py:1780 msgid "Author" msgstr "作者" -#: common/models.py:1761 +#: common/models.py:1782 msgid "Summary" msgstr "摘要" -#: common/models.py:1764 common/models.py:3136 +#: common/models.py:1785 common/models.py:3327 msgid "Read" msgstr "閲讀" -#: common/models.py:1764 +#: common/models.py:1785 msgid "Was this news item read?" msgstr "這條新聞被閲讀了嗎?" -#: common/models.py:1781 +#: common/models.py:1802 msgid "Image file" msgstr "圖像文件" -#: common/models.py:1793 +#: common/models.py:1814 msgid "Target model type for this image" msgstr "此圖像的目標模型類型" -#: common/models.py:1797 +#: common/models.py:1818 msgid "Target model ID for this image" msgstr "此圖像的目標型號ID" -#: common/models.py:1819 +#: common/models.py:1840 msgid "Custom Unit" msgstr "自定義單位" -#: common/models.py:1837 +#: common/models.py:1858 msgid "Unit symbol must be unique" msgstr "單位符號必須唯一" -#: common/models.py:1852 +#: common/models.py:1873 msgid "Unit name must be a valid identifier" msgstr "單位名稱必須是有效的標識符" -#: common/models.py:1871 +#: common/models.py:1892 msgid "Unit name" msgstr "單位名稱" -#: common/models.py:1878 +#: common/models.py:1899 msgid "Symbol" msgstr "符號" -#: common/models.py:1879 +#: common/models.py:1900 msgid "Optional unit symbol" msgstr "可選單位符號" -#: common/models.py:1885 +#: common/models.py:1906 msgid "Definition" msgstr "定義" -#: common/models.py:1886 +#: common/models.py:1907 msgid "Unit definition" msgstr "單位定義" -#: common/models.py:1946 common/models.py:2079 stock/models.py:3097 -#: stock/serializers.py:258 +#: common/models.py:1975 common/models.py:2130 stock/models.py:3901 +#: stock/serializers.py:263 msgid "Attachment" msgstr "附件" -#: common/models.py:1979 +#: common/models.py:2021 msgid "Missing file" msgstr "缺少檔案" -#: common/models.py:1980 +#: common/models.py:2022 msgid "Missing external link" msgstr "缺少外部連結" -#: common/models.py:2019 +#: common/models.py:2070 msgid "No file attached to rename" msgstr "" -#: common/models.py:2022 +#: common/models.py:2073 msgid "Filename cannot be empty" msgstr "" -#: common/models.py:2027 common/models.py:2047 +#: common/models.py:2078 common/models.py:2098 msgid "Invalid filename" msgstr "" -#: common/models.py:2033 +#: common/models.py:2084 msgid "Cannot change file extension" msgstr "" -#: common/models.py:2052 +#: common/models.py:2103 msgid "A file with this name already exists" msgstr "" -#: common/models.py:2059 +#: common/models.py:2110 msgid "Failed to save renamed file" msgstr "" -#: common/models.py:2071 common/models.py:2617 +#: common/models.py:2122 common/models.py:2756 msgid "Model type" msgstr "模型類型" -#: common/models.py:2072 +#: common/models.py:2123 msgid "Target model type for image" msgstr "圖像的目標模型類型" -#: common/models.py:2080 +#: common/models.py:2132 msgid "Select file to attach" msgstr "選擇附件" -#: common/models.py:2096 +#: common/models.py:2138 +msgid "Thumbnail" +msgstr "" + +#: common/models.py:2139 +msgid "Thumbnail image for this attachment" +msgstr "" + +#: common/models.py:2155 msgid "Comment" msgstr "註解" -#: common/models.py:2097 +#: common/models.py:2156 msgid "Attachment comment" msgstr "附件評論" -#: common/models.py:2113 +#: common/models.py:2172 msgid "Upload date" msgstr "上傳日期" -#: common/models.py:2114 +#: common/models.py:2173 msgid "Date the file was uploaded" msgstr "上傳文件的日期" -#: common/models.py:2118 +#: common/models.py:2178 +msgid "Is image" +msgstr "" + +#: common/models.py:2179 +msgid "True if this attachment is a valid image file" +msgstr "" + +#: common/models.py:2183 msgid "File size" msgstr "文件大小" -#: common/models.py:2118 +#: common/models.py:2183 msgid "File size in bytes" msgstr "文件大小,以字節為單位" -#: common/models.py:2156 common/serializers.py:796 +#: common/models.py:2219 common/serializers.py:843 msgid "Invalid model type specified for attachment" msgstr "為附件指定的模型類型無效" -#: common/models.py:2177 +#: common/models.py:2303 msgid "Custom State" msgstr "自定狀態" -#: common/models.py:2178 +#: common/models.py:2304 msgid "Custom States" msgstr "定製狀態" -#: common/models.py:2183 +#: common/models.py:2309 msgid "Reference Status Set" msgstr "參考狀態設定" -#: common/models.py:2184 +#: common/models.py:2310 msgid "Status set that is extended with this custom state" msgstr "使用此自定義狀態擴展狀態的狀態集" -#: common/models.py:2188 generic/states/serializers.py:18 +#: common/models.py:2314 generic/states/serializers.py:18 msgid "Logical Key" msgstr "邏輯密鑰" -#: common/models.py:2190 +#: common/models.py:2316 msgid "State logical key that is equal to this custom state in business logic" msgstr "等同於商業邏輯中自定義狀態的狀態邏輯鍵" -#: common/models.py:2195 common/models.py:2462 machine/serializers.py:27 -#: report/templates/report/inventree_test_report.html:104 stock/models.py:3089 +#: common/models.py:2321 common/models.py:2588 machine/serializers.py:27 +#: report/templates/report/inventree_test_report.html:104 stock/models.py:3893 msgid "Value" msgstr "值" -#: common/models.py:2196 +#: common/models.py:2322 msgid "Numerical value that will be saved in the models database" msgstr "將儲存於模型資料庫中的數值" -#: common/models.py:2202 +#: common/models.py:2328 msgid "Name of the state" msgstr "狀態名" -#: common/models.py:2211 common/models.py:2468 generic/states/serializers.py:22 +#: common/models.py:2337 common/models.py:2594 generic/states/serializers.py:22 msgid "Label" msgstr "標籤" -#: common/models.py:2212 +#: common/models.py:2338 msgid "Label that will be displayed in the frontend" msgstr "在前端顯示的標籤" -#: common/models.py:2219 generic/states/serializers.py:24 +#: common/models.py:2345 generic/states/serializers.py:24 msgid "Color" msgstr "顏色" -#: common/models.py:2220 +#: common/models.py:2346 msgid "Color that will be displayed in the frontend" msgstr "將在前端顯示顏色" -#: common/models.py:2228 +#: common/models.py:2354 msgid "Model" msgstr "模式" -#: common/models.py:2229 +#: common/models.py:2355 msgid "Model this state is associated with" msgstr "該狀態關聯的模型" -#: common/models.py:2244 +#: common/models.py:2370 msgid "Model must be selected" msgstr "必須選定模型" -#: common/models.py:2247 +#: common/models.py:2373 msgid "Key must be selected" msgstr "必須選取密鑰" -#: common/models.py:2250 +#: common/models.py:2376 msgid "Logical key must be selected" msgstr "必須選中邏輯密鑰" -#: common/models.py:2254 +#: common/models.py:2380 msgid "Key must be different from logical key" msgstr "密鑰必須不同於邏輯密鑰" -#: common/models.py:2261 +#: common/models.py:2387 msgid "Valid reference status class must be provided" msgstr "必須提供有效參考狀態類別" -#: common/models.py:2267 +#: common/models.py:2393 msgid "Key must be different from the logical keys of the reference status" msgstr "密鑰必須不同於參考狀態的邏輯密鑰" -#: common/models.py:2274 +#: common/models.py:2400 msgid "Logical key must be in the logical keys of the reference status" msgstr "邏輯密鑰必須在參考狀態的邏輯鍵中" -#: common/models.py:2281 +#: common/models.py:2407 msgid "Name must be different from the names of the reference status" msgstr "名稱必須不同於參考狀態的名稱" -#: common/models.py:2321 common/models.py:2456 common/models.py:2662 +#: common/models.py:2447 common/models.py:2582 common/models.py:2801 msgid "Selection List" msgstr "選擇列表" -#: common/models.py:2322 +#: common/models.py:2448 msgid "Selection Lists" msgstr "選擇列表" -#: common/models.py:2327 +#: common/models.py:2453 msgid "Name of the selection list" msgstr "選擇列表名稱" -#: common/models.py:2334 +#: common/models.py:2460 msgid "Description of the selection list" msgstr "選擇列表描述" -#: common/models.py:2340 part/models.py:1297 +#: common/models.py:2466 part/models.py:1315 msgid "Locked" msgstr "已鎖定" -#: common/models.py:2341 +#: common/models.py:2467 msgid "Is this selection list locked?" msgstr "此選擇列表是否已鎖定?" -#: common/models.py:2347 +#: common/models.py:2473 msgid "Can this selection list be used?" msgstr "此選擇列表是否可使用?" -#: common/models.py:2355 +#: common/models.py:2481 msgid "Source Plugin" msgstr "來源模組" -#: common/models.py:2356 +#: common/models.py:2482 msgid "Plugin which provides the selection list" msgstr "提供此選擇列表的模組" -#: common/models.py:2361 +#: common/models.py:2487 msgid "Source String" msgstr "來源字串" -#: common/models.py:2362 +#: common/models.py:2488 msgid "Optional string identifying the source used for this list" msgstr "用於標示此列表來源的可選字串" -#: common/models.py:2371 +#: common/models.py:2497 msgid "Default Entry" msgstr "預設項目" -#: common/models.py:2372 +#: common/models.py:2498 msgid "Default entry for this selection list" msgstr "此選擇列表的預設項目" -#: common/models.py:2377 common/models.py:3274 +#: common/models.py:2503 common/models.py:3470 msgid "Created" msgstr "已創建" -#: common/models.py:2378 +#: common/models.py:2504 msgid "Date and time that the selection list was created" msgstr "選擇列表建立的日期與時間" -#: common/models.py:2383 +#: common/models.py:2509 msgid "Last Updated" msgstr "最近更新" -#: common/models.py:2384 +#: common/models.py:2510 msgid "Date and time that the selection list was last updated" msgstr "選擇列表最近更新的日期與時間" -#: common/models.py:2446 +#: common/models.py:2572 msgid "Selection List Entry" msgstr "選擇列表項目" -#: common/models.py:2447 +#: common/models.py:2573 msgid "Selection List Entries" msgstr "選擇列表項目" -#: common/models.py:2457 +#: common/models.py:2583 msgid "Selection list to which this entry belongs" msgstr "該項目所屬的選擇列表" -#: common/models.py:2463 +#: common/models.py:2589 msgid "Value of the selection list entry" msgstr "選擇列表項目的值" -#: common/models.py:2469 +#: common/models.py:2595 msgid "Label for the selection list entry" msgstr "選擇列表項目的標籤" -#: common/models.py:2475 +#: common/models.py:2601 msgid "Description of the selection list entry" msgstr "選擇列表項目的描述" -#: common/models.py:2482 +#: common/models.py:2608 msgid "Is this selection list entry active?" msgstr "此選擇列表項目是否啟用?" -#: common/models.py:2516 +#: common/models.py:2642 msgid "Parameter Template" msgstr "參數模板" -#: common/models.py:2517 +#: common/models.py:2643 msgid "Parameter Templates" msgstr "參數範本" -#: common/models.py:2554 +#: common/models.py:2664 +msgid "No uniqueness required" +msgstr "" + +#: common/models.py:2665 +msgid "Unique for model type" +msgstr "" + +#: common/models.py:2666 +msgid "Globally unique" +msgstr "" + +#: common/models.py:2693 msgid "Checkbox parameters cannot have units" msgstr "勾選框參數不能有單位" -#: common/models.py:2559 +#: common/models.py:2698 msgid "Checkbox parameters cannot have choices" msgstr "複選框參數不能有選項" -#: common/models.py:2579 part/models.py:3686 +#: common/models.py:2718 part/models.py:3576 msgid "Choices must be unique" msgstr "選擇必須是唯一的" -#: common/models.py:2596 +#: common/models.py:2735 msgid "Parameter template name must be unique" msgstr "參數模板名稱必須是唯一的" -#: common/models.py:2618 +#: common/models.py:2757 msgid "Target model type for this parameter template" msgstr "此參數範本的目標模型類型" -#: common/models.py:2624 +#: common/models.py:2763 msgid "Parameter Name" msgstr "參數名稱" -#: common/models.py:2630 part/models.py:1250 +#: common/models.py:2769 part/models.py:1268 msgid "Units" msgstr "單位" -#: common/models.py:2631 +#: common/models.py:2770 msgid "Physical units for this parameter" msgstr "此參數的物理單位" -#: common/models.py:2639 +#: common/models.py:2778 msgid "Parameter description" msgstr "參數説明" -#: common/models.py:2645 +#: common/models.py:2784 msgid "Checkbox" msgstr "勾選框" -#: common/models.py:2646 +#: common/models.py:2785 msgid "Is this parameter a checkbox?" msgstr "此參數是否為勾選框?" -#: common/models.py:2651 part/models.py:3773 +#: common/models.py:2790 part/models.py:3663 msgid "Choices" msgstr "選項" -#: common/models.py:2652 +#: common/models.py:2791 msgid "Valid choices for this parameter (comma-separated)" msgstr "此參數的有效選擇 (逗號分隔)" -#: common/models.py:2663 +#: common/models.py:2802 msgid "Selection list for this parameter" msgstr "此參數的選擇清單" -#: common/models.py:2668 part/models.py:3748 report/models.py:292 +#: common/models.py:2807 part/models.py:3638 report/models.py:297 msgid "Enabled" msgstr "已啓用" -#: common/models.py:2669 +#: common/models.py:2808 msgid "Is this parameter template enabled?" msgstr "是否啟用此參數範本?" -#: common/models.py:2710 +#: common/models.py:2814 +msgid "Uniqueness" +msgstr "" + +#: common/models.py:2816 +msgid "Enforce uniqueness of linked parameter values against this template" +msgstr "" + +#: common/models.py:2858 msgid "Parameter" msgstr "參數" -#: common/models.py:2711 +#: common/models.py:2859 msgid "Parameters" msgstr "參數集" -#: common/models.py:2757 +#: common/models.py:2905 msgid "Invalid choice for parameter value" msgstr "無效的參數值選擇" -#: common/models.py:2827 common/serializers.py:892 +#: common/models.py:3009 +msgid "Parameter value must be unique" +msgstr "" + +#: common/models.py:3018 common/serializers.py:940 msgid "Invalid model type specified for parameter" msgstr "為參數指定的模型類型無效" -#: common/models.py:2863 +#: common/models.py:3054 msgid "Model ID" msgstr "模型 ID" -#: common/models.py:2864 +#: common/models.py:3055 msgid "ID of the target model for this parameter" msgstr "此參數的目標模型 ID" -#: common/models.py:2873 common/setting/system.py:457 report/models.py:378 -#: report/models.py:699 report/serializers.py:117 report/serializers.py:158 -#: stock/serializers.py:245 +#: common/models.py:3064 common/setting/system.py:470 report/models.py:383 +#: report/models.py:717 report/serializers.py:115 report/serializers.py:166 +#: stock/serializers.py:250 msgid "Template" msgstr "模板" -#: common/models.py:2874 +#: common/models.py:3065 msgid "Parameter template" msgstr "參數範本" -#: common/models.py:2879 common/models.py:2921 importer/models.py:581 +#: common/models.py:3070 common/models.py:3112 importer/models.py:684 msgid "Data" msgstr "數據" -#: common/models.py:2880 +#: common/models.py:3071 msgid "Parameter Value" msgstr "參數值" -#: common/models.py:2889 company/models.py:826 order/serializers.py:896 -#: order/serializers.py:2164 part/models.py:4129 part/models.py:4498 +#: common/models.py:3080 company/models.py:827 order/serializers.py:917 +#: order/serializers.py:2299 part/models.py:4041 part/models.py:4427 #: report/templates/report/inventree_bill_of_materials_report.html:140 #: report/templates/report/inventree_purchase_order_report.html:39 #: report/templates/report/inventree_return_order_report.html:27 #: report/templates/report/inventree_sales_order_report.html:32 #: report/templates/report/inventree_stock_location_report.html:105 -#: stock/serializers.py:842 +#: report/templates/report/inventree_transfer_order_report.html:29 +#: stock/serializers.py:855 msgid "Note" msgstr "備註" -#: common/models.py:2890 stock/serializers.py:747 +#: common/models.py:3081 stock/serializers.py:754 stock/serializers.py:1115 msgid "Optional note field" msgstr "可選註釋字段" -#: common/models.py:2917 +#: common/models.py:3108 msgid "Barcode Scan" msgstr "掃描條碼" -#: common/models.py:2922 +#: common/models.py:3113 msgid "Barcode data" msgstr "條碼數據" -#: common/models.py:2933 +#: common/models.py:3124 msgid "User who scanned the barcode" msgstr "掃描條碼" -#: common/models.py:2938 importer/models.py:70 +#: common/models.py:3129 importer/models.py:72 msgid "Timestamp" msgstr "時間戳" -#: common/models.py:2939 +#: common/models.py:3130 msgid "Date and time of the barcode scan" msgstr "掃描條碼的日期和時間" -#: common/models.py:2945 +#: common/models.py:3136 msgid "URL endpoint which processed the barcode" msgstr "處理條碼的 URL 終點" -#: common/models.py:2952 order/models.py:1897 plugin/serializers.py:93 +#: common/models.py:3143 order/models.py:2206 plugin/serializers.py:93 msgid "Context" msgstr "上下文" -#: common/models.py:2953 +#: common/models.py:3144 msgid "Context data for the barcode scan" msgstr "掃描條碼的上下文數據" -#: common/models.py:2960 +#: common/models.py:3151 msgid "Response" msgstr "響應" -#: common/models.py:2961 +#: common/models.py:3152 msgid "Response data from the barcode scan" msgstr "掃描條碼的響應數據" -#: common/models.py:2967 report/templates/report/inventree_test_report.html:103 -#: stock/models.py:3083 +#: common/models.py:3158 report/templates/report/inventree_test_report.html:103 +#: stock/models.py:3887 msgid "Result" msgstr "結果" -#: common/models.py:2968 +#: common/models.py:3159 msgid "Was the barcode scan successful?" msgstr "條碼掃描成功嗎?" -#: common/models.py:3050 +#: common/models.py:3241 msgid "An error occurred" msgstr "發生錯誤" -#: common/models.py:3071 +#: common/models.py:3262 msgid "INVE-E8: Email log deletion is protected. Set INVENTREE_PROTECT_EMAIL_LOG to False to allow deletion." msgstr "INVE-E8:已保護電子郵件日誌刪除。請將 INVENTREE_PROTECT_EMAIL_LOG 設為 False 以允許刪除。" -#: common/models.py:3118 +#: common/models.py:3309 msgid "Email Message" msgstr "電子郵件訊息" -#: common/models.py:3119 +#: common/models.py:3310 msgid "Email Messages" msgstr "電子郵件訊息" -#: common/models.py:3126 +#: common/models.py:3317 msgid "Announced" msgstr "已公告" -#: common/models.py:3128 +#: common/models.py:3319 msgid "Sent" msgstr "已發送" -#: common/models.py:3129 +#: common/models.py:3320 msgid "Failed" msgstr "失敗" -#: common/models.py:3132 +#: common/models.py:3323 msgid "Delivered" msgstr "已送達" -#: common/models.py:3140 +#: common/models.py:3331 msgid "Confirmed" msgstr "已確認" -#: common/models.py:3146 +#: common/models.py:3337 msgid "Inbound" msgstr "入站" -#: common/models.py:3147 +#: common/models.py:3338 msgid "Outbound" msgstr "出站" -#: common/models.py:3152 +#: common/models.py:3343 msgid "No Reply" msgstr "不回覆" -#: common/models.py:3153 +#: common/models.py:3344 msgid "Track Delivery" msgstr "追蹤投遞" -#: common/models.py:3154 +#: common/models.py:3345 msgid "Track Read" msgstr "追蹤已讀" -#: common/models.py:3155 +#: common/models.py:3346 msgid "Track Click" msgstr "追蹤點擊" -#: common/models.py:3158 common/models.py:3261 +#: common/models.py:3349 common/models.py:3457 msgid "Global ID" msgstr "全域 ID" -#: common/models.py:3171 +#: common/models.py:3362 msgid "Identifier for this message (might be supplied by external system)" msgstr "此訊息的識別碼(可能由外部系統提供)" -#: common/models.py:3178 +#: common/models.py:3369 msgid "Thread ID" msgstr "討論串 ID" -#: common/models.py:3180 +#: common/models.py:3371 msgid "Identifier for this message thread (might be supplied by external system)" msgstr "此訊息討論串的識別碼(可能由外部系統提供)" -#: common/models.py:3189 +#: common/models.py:3380 msgid "Thread" msgstr "討論串" -#: common/models.py:3190 +#: common/models.py:3381 msgid "Linked thread for this message" msgstr "此訊息所連結的討論串" -#: common/models.py:3206 +#: common/models.py:3397 msgid "Priority" msgstr "優先序" -#: common/models.py:3248 +#: common/models.py:3439 msgid "Email Thread" msgstr "電子郵件討論串" -#: common/models.py:3249 +#: common/models.py:3440 msgid "Email Threads" msgstr "電子郵件討論串" -#: common/models.py:3255 generic/states/serializers.py:16 -#: machine/serializers.py:24 plugin/models.py:46 users/models.py:113 +#: common/models.py:3451 generic/states/serializers.py:16 +#: machine/serializers.py:24 plugin/models.py:46 users/models.py:111 msgid "Key" msgstr "鍵" -#: common/models.py:3258 +#: common/models.py:3454 msgid "Unique key for this thread (used to identify the thread)" msgstr "此討論串的唯一鍵(用於辨識)" -#: common/models.py:3262 +#: common/models.py:3458 msgid "Unique identifier for this thread" msgstr "此討論串的唯一識別碼" -#: common/models.py:3269 +#: common/models.py:3465 msgid "Started Internal" msgstr "內部建立" -#: common/models.py:3270 +#: common/models.py:3466 msgid "Was this thread started internally?" msgstr "此討論串是否為內部建立?" -#: common/models.py:3275 +#: common/models.py:3471 msgid "Date and time that the thread was created" msgstr "討論串建立的日期時間" -#: common/models.py:3280 +#: common/models.py:3476 msgid "Date and time that the thread was last updated" msgstr "討論串最後更新的日期時間" @@ -2376,7 +2533,7 @@ msgstr "{verbose_name} 已取消" msgid "A order that is assigned to you was canceled" msgstr "分配給您的訂單已取消" -#: common/notifications.py:73 common/notifications.py:80 order/api.py:607 +#: common/notifications.py:73 common/notifications.py:80 order/api.py:612 msgid "Items Received" msgstr "收到的物品" @@ -2388,104 +2545,100 @@ msgstr "已根據採購訂單收到物品" msgid "Items have been received against a return order" msgstr "已收到退貨訂單中的物品" -#: common/serializers.py:125 +#: common/serializers.py:127 msgid "Indicates if changing this setting requires confirmation" msgstr "指示變更此設定是否需要確認" -#: common/serializers.py:139 +#: common/serializers.py:141 msgid "This setting requires confirmation before changing. Please confirm the change." msgstr "變更此設定前需要確認。請確認變更。" -#: common/serializers.py:172 +#: common/serializers.py:174 msgid "Indicates if the setting is overridden by an environment variable" msgstr "表示此設定是否被環境變數覆蓋" -#: common/serializers.py:174 +#: common/serializers.py:176 plugin/serializers.py:293 msgid "Override" msgstr "覆蓋" -#: common/serializers.py:610 +#: common/serializers.py:644 msgid "Is Running" msgstr "正在運行" -#: common/serializers.py:616 +#: common/serializers.py:650 msgid "Pending Tasks" msgstr "等待完成的任務" -#: common/serializers.py:622 +#: common/serializers.py:656 msgid "Scheduled Tasks" msgstr "預定的任務" -#: common/serializers.py:628 +#: common/serializers.py:662 msgid "Failed Tasks" msgstr "失敗的任務" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Task ID" msgstr "任務ID" -#: common/serializers.py:643 +#: common/serializers.py:677 msgid "Unique task ID" msgstr "唯一任務ID" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock" msgstr "鎖定" -#: common/serializers.py:645 +#: common/serializers.py:679 msgid "Lock time" msgstr "鎖定時間" -#: common/serializers.py:647 +#: common/serializers.py:681 msgid "Task name" msgstr "任務名稱" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function" msgstr "功能" -#: common/serializers.py:649 +#: common/serializers.py:683 msgid "Function name" msgstr "功能名稱" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Arguments" msgstr "參數" -#: common/serializers.py:651 +#: common/serializers.py:685 msgid "Task arguments" msgstr "任務參數" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Keyword Arguments" msgstr "關鍵字參數" -#: common/serializers.py:654 +#: common/serializers.py:688 msgid "Task keyword arguments" msgstr "任務關鍵詞參數" -#: common/serializers.py:764 +#: common/serializers.py:811 msgid "Filename" msgstr "檔案名稱" -#: common/serializers.py:771 common/serializers.py:838 -#: common/serializers.py:914 importer/models.py:90 report/api.py:41 -#: report/models.py:298 report/serializers.py:71 +#: common/serializers.py:818 common/serializers.py:886 +#: common/serializers.py:960 importer/models.py:94 report/api.py:42 +#: report/models.py:303 report/serializers.py:69 msgid "Model Type" msgstr "模型類型" -#: common/serializers.py:799 +#: common/serializers.py:846 msgid "User does not have permission to create or edit attachments for this model" msgstr "用户無權為此模式創建或編輯附件" -#: common/serializers.py:895 +#: common/serializers.py:943 msgid "User does not have permission to create or edit parameters for this model" msgstr "使用者沒有權限建立或編輯此模型的參數" -#: common/serializers.py:970 common/serializers.py:1073 -msgid "Selection list is locked" -msgstr "選擇列表已鎖定" - #: common/setting/system.py:97 msgid "No group" msgstr "無分組" @@ -2614,13 +2767,13 @@ msgstr "貨幣更新間隔時間" msgid "How often to update exchange rates (set to zero to disable)" msgstr "檢查更新的頻率(設置為零以禁用)" -#: common/setting/system.py:280 common/setting/system.py:300 -#: common/setting/system.py:313 common/setting/system.py:321 -#: common/setting/system.py:328 common/setting/system.py:337 -#: common/setting/system.py:346 common/setting/system.py:587 -#: common/setting/system.py:615 common/setting/system.py:734 -#: common/setting/system.py:1151 common/setting/system.py:1167 -#: common/setting/system.py:1184 +#: common/setting/system.py:280 common/setting/system.py:307 +#: common/setting/system.py:320 common/setting/system.py:328 +#: common/setting/system.py:335 common/setting/system.py:344 +#: common/setting/system.py:353 common/setting/system.py:600 +#: common/setting/system.py:628 common/setting/system.py:753 +#: common/setting/system.py:1214 common/setting/system.py:1230 +#: common/setting/system.py:1247 msgid "days" msgstr "天" @@ -2633,6 +2786,14 @@ msgid "Currency update plugin to use" msgstr "使用貨幣更新插件" #: common/setting/system.py:290 +msgid "Upload Size Limit" +msgstr "" + +#: common/setting/system.py:291 +msgid "Maximum allowable upload size for images and files" +msgstr "" + +#: common/setting/system.py:297 msgid "Strict URL Validation" msgstr "嚴格的 URL 驗證" @@ -2760,947 +2921,1017 @@ msgstr "條形碼生成插件" msgid "Plugin to use for internal barcode data generation" msgstr "用於內部條形碼數據生成的插件" -#: common/setting/system.py:399 +#: common/setting/system.py:406 +msgid "Part Locking" +msgstr "" + +#: common/setting/system.py:407 +msgid "Enable locking of parts to prevent modification" +msgstr "" + +#: common/setting/system.py:412 msgid "Part Revisions" msgstr "零件修訂" -#: common/setting/system.py:400 +#: common/setting/system.py:413 msgid "Enable revision field for Part" msgstr "啓用零件修訂字段" -#: common/setting/system.py:405 +#: common/setting/system.py:418 msgid "Assembly Revision Only" msgstr "僅限裝配修訂版本" -#: common/setting/system.py:406 +#: common/setting/system.py:419 msgid "Only allow revisions for assembly parts" msgstr "僅允許對裝配零件進行修訂" -#: common/setting/system.py:411 +#: common/setting/system.py:424 msgid "Allow Deletion from Assembly" msgstr "允許從裝配中刪除" -#: common/setting/system.py:412 +#: common/setting/system.py:425 msgid "Allow deletion of parts which are used in an assembly" msgstr "允許刪除已在裝配中使用的零件" -#: common/setting/system.py:417 +#: common/setting/system.py:430 msgid "IPN Regex" msgstr "IPN 內部零件號" -#: common/setting/system.py:418 +#: common/setting/system.py:431 msgid "Regular expression pattern for matching Part IPN" msgstr "匹配零件 IPN(內部零件號)的正則表達式模式" -#: common/setting/system.py:421 +#: common/setting/system.py:434 msgid "Allow Duplicate IPN" msgstr "允許重複的 IPN(內部零件號)" -#: common/setting/system.py:422 +#: common/setting/system.py:435 msgid "Allow multiple parts to share the same IPN" msgstr "允許多個零件共享相同的 IPN(內部零件號)" -#: common/setting/system.py:427 +#: common/setting/system.py:440 msgid "Allow Editing IPN" msgstr "允許編輯 IPN(內部零件號)" -#: common/setting/system.py:428 +#: common/setting/system.py:441 msgid "Allow changing the IPN value while editing a part" msgstr "允許編輯零件時更改內部零件號" -#: common/setting/system.py:433 +#: common/setting/system.py:446 msgid "Copy Part BOM Data" msgstr "複製零件物料清單數據" -#: common/setting/system.py:434 +#: common/setting/system.py:447 msgid "Copy BOM data by default when duplicating a part" msgstr "複製零件時默認複製物料清單數據" -#: common/setting/system.py:439 +#: common/setting/system.py:452 msgid "Copy Part Parameter Data" msgstr "複製零件參數數據" -#: common/setting/system.py:440 +#: common/setting/system.py:453 msgid "Copy parameter data by default when duplicating a part" msgstr "複製零件時默認複製參數數據" -#: common/setting/system.py:445 +#: common/setting/system.py:458 msgid "Copy Part Test Data" msgstr "複製零件測試數據" -#: common/setting/system.py:446 +#: common/setting/system.py:459 msgid "Copy test data by default when duplicating a part" msgstr "複製零件時默認複製測試數據" -#: common/setting/system.py:451 +#: common/setting/system.py:464 msgid "Copy Category Parameter Templates" msgstr "複製類別參數模板" -#: common/setting/system.py:452 +#: common/setting/system.py:465 msgid "Copy category parameter templates when creating a part" msgstr "創建零件時複製類別參數模板" -#: common/setting/system.py:458 +#: common/setting/system.py:471 msgid "Parts are templates by default" msgstr "零件默認為模板" -#: common/setting/system.py:464 +#: common/setting/system.py:477 msgid "Parts can be assembled from other components by default" msgstr "默認情況下,元件可由其他零件組裝而成" -#: common/setting/system.py:469 part/models.py:1263 part/serializers.py:1740 -#: part/serializers.py:1748 +#: common/setting/system.py:482 part/models.py:1281 part/serializers.py:1766 +#: part/serializers.py:1774 msgid "Component" msgstr "組件" -#: common/setting/system.py:470 +#: common/setting/system.py:483 msgid "Parts can be used as sub-components by default" msgstr "默認情況下,零件可用作子部件" -#: common/setting/system.py:475 part/models.py:1281 +#: common/setting/system.py:488 part/models.py:1299 msgid "Purchaseable" msgstr "可購買" -#: common/setting/system.py:476 +#: common/setting/system.py:489 msgid "Parts are purchaseable by default" msgstr "默認情況下可購買零件" -#: common/setting/system.py:481 part/models.py:1287 stock/api.py:642 +#: common/setting/system.py:494 part/models.py:1305 stock/api.py:702 msgid "Salable" msgstr "可銷售" -#: common/setting/system.py:482 +#: common/setting/system.py:495 msgid "Parts are salable by default" msgstr "零件默認為可銷售" -#: common/setting/system.py:488 +#: common/setting/system.py:501 msgid "Parts are trackable by default" msgstr "默認情況下可跟蹤零件" -#: common/setting/system.py:493 part/models.py:1303 +#: common/setting/system.py:506 part/models.py:1321 msgid "Virtual" msgstr "虛擬的" -#: common/setting/system.py:494 +#: common/setting/system.py:507 msgid "Parts are virtual by default" msgstr "默認情況下,零件是虛擬的" -#: common/setting/system.py:499 +#: common/setting/system.py:512 msgid "Show related parts" msgstr "顯示相關零件" -#: common/setting/system.py:500 +#: common/setting/system.py:513 msgid "Display related parts for a part" msgstr "顯示零件的相關零件" -#: common/setting/system.py:505 +#: common/setting/system.py:518 msgid "Initial Stock Data" msgstr "初始庫存數據" -#: common/setting/system.py:506 +#: common/setting/system.py:519 msgid "Allow creation of initial stock when adding a new part" msgstr "允許在添加新零件時創建初始庫存" -#: common/setting/system.py:511 +#: common/setting/system.py:524 msgid "Initial Supplier Data" msgstr "初始供應商數據" -#: common/setting/system.py:513 +#: common/setting/system.py:526 msgid "Allow creation of initial supplier data when adding a new part" msgstr "允許在添加新零件時創建初始供應商數據" -#: common/setting/system.py:519 +#: common/setting/system.py:532 msgid "Part Name Display Format" msgstr "零件名稱顯示格式" -#: common/setting/system.py:520 +#: common/setting/system.py:533 msgid "Format to display the part name" msgstr "顯示零件名稱的格式" -#: common/setting/system.py:526 +#: common/setting/system.py:539 msgid "Part Category Default Icon" msgstr "零件類別默認圖標" -#: common/setting/system.py:527 +#: common/setting/system.py:540 msgid "Part category default icon (empty means no icon)" msgstr "零件類別默認圖標 (空表示沒有圖標)" -#: common/setting/system.py:532 +#: common/setting/system.py:545 msgid "Minimum Pricing Decimal Places" msgstr "最小定價小數位數" -#: common/setting/system.py:534 +#: common/setting/system.py:547 msgid "Minimum number of decimal places to display when rendering pricing data" msgstr "呈現定價數據時顯示的最小小數位數" -#: common/setting/system.py:545 +#: common/setting/system.py:558 msgid "Maximum Pricing Decimal Places" msgstr "最大定價小數位數" -#: common/setting/system.py:547 +#: common/setting/system.py:560 msgid "Maximum number of decimal places to display when rendering pricing data" msgstr "呈現定價數據時顯示的最大小數位數" -#: common/setting/system.py:558 +#: common/setting/system.py:571 msgid "Use Supplier Pricing" msgstr "使用供應商定價" -#: common/setting/system.py:560 +#: common/setting/system.py:573 msgid "Include supplier price breaks in overall pricing calculations" msgstr "將供應商的價批發價納入總體定價計算中" -#: common/setting/system.py:566 +#: common/setting/system.py:579 msgid "Purchase History Override" msgstr "購買歷史記錄覆蓋" -#: common/setting/system.py:568 +#: common/setting/system.py:581 msgid "Historical purchase order pricing overrides supplier price breaks" msgstr "歷史採購訂單定價優先於供應商批發價" -#: common/setting/system.py:574 +#: common/setting/system.py:587 msgid "Use Stock Item Pricing" msgstr "使用庫存項定價" -#: common/setting/system.py:576 +#: common/setting/system.py:589 msgid "Use pricing from manually entered stock data for pricing calculations" msgstr "使用手動輸入的庫存數據進行定價計算" -#: common/setting/system.py:582 +#: common/setting/system.py:595 msgid "Stock Item Pricing Age" msgstr "庫存項目定價時間" -#: common/setting/system.py:584 +#: common/setting/system.py:597 msgid "Exclude stock items older than this number of days from pricing calculations" msgstr "從定價計算中排除超過此天數的庫存項目" -#: common/setting/system.py:591 +#: common/setting/system.py:604 msgid "Use Variant Pricing" msgstr "使用變體定價" -#: common/setting/system.py:592 +#: common/setting/system.py:605 msgid "Include variant pricing in overall pricing calculations" msgstr "在整體定價計算中包括變體定價" -#: common/setting/system.py:597 +#: common/setting/system.py:610 msgid "Active Variants Only" msgstr "僅限活躍變體" -#: common/setting/system.py:599 +#: common/setting/system.py:612 msgid "Only use active variant parts for calculating variant pricing" msgstr "僅使用活躍變體零件計算變體價格" -#: common/setting/system.py:605 +#: common/setting/system.py:618 msgid "Auto Update Pricing" msgstr "自動更新定價" -#: common/setting/system.py:607 +#: common/setting/system.py:620 msgid "Automatically update part pricing when internal data changes" msgstr "當內部資料變更時自動更新零件定價" -#: common/setting/system.py:613 +#: common/setting/system.py:626 msgid "Pricing Rebuild Interval" msgstr "價格重建間隔" -#: common/setting/system.py:614 +#: common/setting/system.py:627 msgid "Number of days before part pricing is automatically updated" msgstr "零件價格自動更新前的天數" -#: common/setting/system.py:620 +#: common/setting/system.py:633 msgid "Internal Prices" msgstr "內部價格" -#: common/setting/system.py:621 +#: common/setting/system.py:634 msgid "Enable internal prices for parts" msgstr "啓用內部零件價格" -#: common/setting/system.py:626 +#: common/setting/system.py:639 msgid "Internal Price Override" msgstr "覆蓋內部價格" -#: common/setting/system.py:628 +#: common/setting/system.py:641 msgid "If available, internal prices override price range calculations" msgstr "如果有內部價格,內部價格將覆蓋價格範圍計算" -#: common/setting/system.py:634 +#: common/setting/system.py:647 msgid "Allow BOM Zero Quantity" msgstr "允許 BOM 零數量" -#: common/setting/system.py:636 +#: common/setting/system.py:649 msgid "Accept a zero quantity for BOM item for part. Enables using setup quantity to define a quantity required per build, independent of build quantity" msgstr "接受零件的 BOM 項目數量為零。允許使用設定數量來定義每次生產所需的數量,而與生產數量無關" -#: common/setting/system.py:642 +#: common/setting/system.py:655 msgid "Enable label printing" msgstr "啓用標籤打印功能" -#: common/setting/system.py:643 +#: common/setting/system.py:656 msgid "Enable label printing from the web interface" msgstr "啓用從網絡界面打印標籤" -#: common/setting/system.py:648 +#: common/setting/system.py:661 msgid "Label Image DPI" msgstr "標籤圖片 DPI" -#: common/setting/system.py:650 +#: common/setting/system.py:663 msgid "DPI resolution when generating image files to supply to label printing plugins" msgstr "生成圖像文件以供標籤打印插件使用時的 DPI 分辨率" -#: common/setting/system.py:656 +#: common/setting/system.py:669 msgid "Enable Reports" msgstr "啓用報告" -#: common/setting/system.py:657 +#: common/setting/system.py:670 msgid "Enable generation of reports" msgstr "啓用報告生成" -#: common/setting/system.py:662 +#: common/setting/system.py:675 msgid "Debug Mode" msgstr "調試模式" -#: common/setting/system.py:663 +#: common/setting/system.py:676 msgid "Generate reports in debug mode (HTML output)" msgstr "以調試模式生成報告(HTML 輸出)" -#: common/setting/system.py:668 +#: common/setting/system.py:681 +msgid "Report URL Fetching" +msgstr "" + +#: common/setting/system.py:682 +msgid "Allow fetching of remote URLs when generating reports" +msgstr "" + +#: common/setting/system.py:687 msgid "Log Report Errors" msgstr "日誌錯誤報告" -#: common/setting/system.py:669 +#: common/setting/system.py:688 msgid "Log errors which occur when generating reports" msgstr "記錄生成報告時出現的錯誤" -#: common/setting/system.py:674 plugin/builtin/labels/label_sheet.py:29 -#: report/models.py:386 +#: common/setting/system.py:693 plugin/builtin/labels/label_sheet.py:30 +#: report/models.py:391 msgid "Page Size" msgstr "頁面大小" -#: common/setting/system.py:675 +#: common/setting/system.py:694 msgid "Default page size for PDF reports" msgstr "PDF 報告默認頁面大小" -#: common/setting/system.py:680 +#: common/setting/system.py:699 msgid "Enforce Parameter Units" msgstr "強制參數單位" -#: common/setting/system.py:682 +#: common/setting/system.py:701 msgid "If units are provided, parameter values must match the specified units" msgstr "如果提供了單位,參數值必須與指定的單位匹配" -#: common/setting/system.py:688 +#: common/setting/system.py:707 msgid "Globally Unique Serials" msgstr "全局唯一序列號" -#: common/setting/system.py:689 +#: common/setting/system.py:708 msgid "Serial numbers for stock items must be globally unique" msgstr "庫存項的序列號必須全局唯一" -#: common/setting/system.py:694 +#: common/setting/system.py:713 msgid "Delete Depleted Stock" msgstr "刪除已耗盡的庫存" -#: common/setting/system.py:695 +#: common/setting/system.py:714 msgid "Determines default behavior when a stock item is depleted" msgstr "設置庫存耗盡時的默認行為" -#: common/setting/system.py:700 +#: common/setting/system.py:719 msgid "Allow Edit Serial Number" msgstr "" -#: common/setting/system.py:701 +#: common/setting/system.py:720 msgid "Allow editing of serial number for stock items" msgstr "" -#: common/setting/system.py:706 +#: common/setting/system.py:725 msgid "Delete Serialized Stock" msgstr "" -#: common/setting/system.py:707 +#: common/setting/system.py:726 msgid "Allow deletion of stock items which have a serial number" msgstr "" -#: common/setting/system.py:712 +#: common/setting/system.py:731 msgid "Batch Code Template" msgstr "批號模板" -#: common/setting/system.py:713 +#: common/setting/system.py:732 msgid "Template for generating default batch codes for stock items" msgstr "為庫存項生成默認批號的模板" -#: common/setting/system.py:717 +#: common/setting/system.py:736 msgid "Stock Expiry" msgstr "庫存過期" -#: common/setting/system.py:718 +#: common/setting/system.py:737 msgid "Enable stock expiry functionality" msgstr "啓用庫存過期功能" -#: common/setting/system.py:723 +#: common/setting/system.py:742 msgid "Sell Expired Stock" msgstr "銷售過期庫存" -#: common/setting/system.py:724 +#: common/setting/system.py:743 msgid "Allow sale of expired stock" msgstr "允許銷售過期庫存" -#: common/setting/system.py:729 +#: common/setting/system.py:748 msgid "Stock Stale Time" msgstr "庫存過期時間" -#: common/setting/system.py:731 +#: common/setting/system.py:750 msgid "Number of days stock items are considered stale before expiring" msgstr "庫存項在到期前被視為過期的天數" -#: common/setting/system.py:738 +#: common/setting/system.py:757 msgid "Build Expired Stock" msgstr "生產過期庫存" -#: common/setting/system.py:739 +#: common/setting/system.py:758 msgid "Allow building with expired stock" msgstr "允許用過期的庫存生產" -#: common/setting/system.py:744 +#: common/setting/system.py:763 msgid "Stock Ownership Control" msgstr "庫存所有權控制" -#: common/setting/system.py:745 +#: common/setting/system.py:764 msgid "Enable ownership control over stock locations and items" msgstr "啓用庫存地點和項目的所有權控制" -#: common/setting/system.py:750 +#: common/setting/system.py:769 msgid "Stock Location Default Icon" msgstr "庫存地點默認圖標" -#: common/setting/system.py:751 +#: common/setting/system.py:770 msgid "Stock location default icon (empty means no icon)" msgstr "庫存地點默認圖標 (空表示沒有圖標)" -#: common/setting/system.py:756 +#: common/setting/system.py:775 msgid "Show Installed Stock Items" msgstr "顯示已安裝的庫存項" -#: common/setting/system.py:757 +#: common/setting/system.py:776 msgid "Display installed stock items in stock tables" msgstr "在庫存表中顯示已安裝的庫存項" -#: common/setting/system.py:762 +#: common/setting/system.py:781 msgid "Check BOM when installing items" msgstr "在安裝項目時檢查物料清單" -#: common/setting/system.py:764 +#: common/setting/system.py:783 msgid "Installed stock items must exist in the BOM for the parent part" msgstr "已安裝的庫存項目必須存在於上級零件的物料清單中" -#: common/setting/system.py:770 +#: common/setting/system.py:789 msgid "Allow Out of Stock Transfer" msgstr "允許超出庫存轉移" -#: common/setting/system.py:772 +#: common/setting/system.py:791 msgid "Allow stock items which are not in stock to be transferred between stock locations" msgstr "允許非庫存的庫存項目在庫存位置之間轉移" -#: common/setting/system.py:778 +#: common/setting/system.py:797 +msgid "Merge stock with existing stock on transfer by default" +msgstr "" + +#: common/setting/system.py:799 +msgid "Default state for merge stock on transfer behaviour. (Can be changed per transfer if desired)" +msgstr "" + +#: common/setting/system.py:805 msgid "Build Order Reference Pattern" msgstr "生產訂單參考模式" -#: common/setting/system.py:779 +#: common/setting/system.py:806 msgid "Required pattern for generating Build Order reference field" msgstr "生成生產訂單參考字段所需的模式" -#: common/setting/system.py:784 common/setting/system.py:852 -#: common/setting/system.py:872 common/setting/system.py:924 +#: common/setting/system.py:811 common/setting/system.py:879 +#: common/setting/system.py:899 common/setting/system.py:949 +#: common/setting/system.py:979 msgid "Require Responsible Owner" msgstr "要求負責人" -#: common/setting/system.py:785 common/setting/system.py:853 -#: common/setting/system.py:873 common/setting/system.py:925 +#: common/setting/system.py:812 common/setting/system.py:880 +#: common/setting/system.py:900 common/setting/system.py:950 +#: common/setting/system.py:980 msgid "A responsible owner must be assigned to each order" msgstr "必須為每個訂單分配一個負責人" -#: common/setting/system.py:790 +#: common/setting/system.py:817 msgid "Require Active Part" msgstr "需要活動零件" -#: common/setting/system.py:791 +#: common/setting/system.py:818 msgid "Prevent build order creation for inactive parts" msgstr "防止為非活動零件創建生產訂單" -#: common/setting/system.py:796 +#: common/setting/system.py:823 msgid "Require Locked Part" msgstr "需要鎖定零件" -#: common/setting/system.py:797 +#: common/setting/system.py:824 msgid "Prevent build order creation for unlocked parts" msgstr "防止為未鎖定的零件創建生產訂單" -#: common/setting/system.py:802 +#: common/setting/system.py:829 msgid "Require Valid BOM" msgstr "需要有效的物料清單" -#: common/setting/system.py:803 +#: common/setting/system.py:830 msgid "Prevent build order creation unless BOM has been validated" msgstr "除非物料清單已驗證,否則禁止創建生產訂單" -#: common/setting/system.py:808 +#: common/setting/system.py:835 msgid "Require Closed Child Orders" msgstr "需要關閉子訂單" -#: common/setting/system.py:810 +#: common/setting/system.py:837 msgid "Prevent build order completion until all child orders are closed" msgstr "在所有子訂單關閉之前,阻止生產訂單的完成" -#: common/setting/system.py:816 +#: common/setting/system.py:843 msgid "External Build Orders" msgstr "外部生產工單" -#: common/setting/system.py:817 +#: common/setting/system.py:844 msgid "Enable external build order functionality" msgstr "啟用外部生產工單功能" -#: common/setting/system.py:822 +#: common/setting/system.py:849 msgid "Require External Build Orders" msgstr "" -#: common/setting/system.py:824 +#: common/setting/system.py:851 msgid "Require an external build order when ordering assembled parts from an external supplier" msgstr "" -#: common/setting/system.py:830 +#: common/setting/system.py:857 msgid "Block Until Tests Pass" msgstr "阻止直到測試通過" -#: common/setting/system.py:832 +#: common/setting/system.py:859 msgid "Prevent build outputs from being completed until all required tests pass" msgstr "在所有必要的測試通過之前,阻止產出完成" -#: common/setting/system.py:838 +#: common/setting/system.py:865 msgid "Enable Return Orders" msgstr "啓用訂單退貨" -#: common/setting/system.py:839 +#: common/setting/system.py:866 msgid "Enable return order functionality in the user interface" msgstr "在用户界面中啓用訂單退貨功能" -#: common/setting/system.py:844 +#: common/setting/system.py:871 msgid "Return Order Reference Pattern" msgstr "退貨訂單參考模式" -#: common/setting/system.py:846 +#: common/setting/system.py:873 msgid "Required pattern for generating Return Order reference field" msgstr "生成退貨訂單參考字段所需的模式" -#: common/setting/system.py:858 +#: common/setting/system.py:885 msgid "Edit Completed Return Orders" msgstr "編輯已完成的退貨訂單" -#: common/setting/system.py:860 +#: common/setting/system.py:887 msgid "Allow editing of return orders after they have been completed" msgstr "允許編輯已完成的退貨訂單" -#: common/setting/system.py:866 +#: common/setting/system.py:893 msgid "Sales Order Reference Pattern" msgstr "銷售訂單參考模式" -#: common/setting/system.py:867 +#: common/setting/system.py:894 msgid "Required pattern for generating Sales Order reference field" msgstr "生成銷售訂單參考字段所需參照模式" -#: common/setting/system.py:878 +#: common/setting/system.py:905 msgid "Sales Order Default Shipment" msgstr "銷售訂單默認配送方式" -#: common/setting/system.py:879 +#: common/setting/system.py:906 msgid "Enable creation of default shipment with sales orders" msgstr "啓用創建銷售訂單的默認配送功能" -#: common/setting/system.py:884 +#: common/setting/system.py:911 msgid "Edit Completed Sales Orders" msgstr "編輯已完成的銷售訂單" -#: common/setting/system.py:886 +#: common/setting/system.py:913 msgid "Allow editing of sales orders after they have been shipped or completed" msgstr "允許在訂單配送或完成後編輯銷售訂單" -#: common/setting/system.py:892 +#: common/setting/system.py:919 msgid "Shipment Requires Checking" msgstr "發貨需要檢查" -#: common/setting/system.py:894 +#: common/setting/system.py:921 msgid "Prevent completion of shipments until items have been checked" msgstr "在項目被檢查前,防止完成發貨" -#: common/setting/system.py:900 +#: common/setting/system.py:927 msgid "Mark Shipped Orders as Complete" msgstr "標記該訂單為已完成?" -#: common/setting/system.py:902 +#: common/setting/system.py:929 msgid "Sales orders marked as shipped will automatically be completed, bypassing the \"shipped\" status" msgstr "標記為已發貨的銷售訂單將自動完成,繞過“已發貨”狀態" -#: common/setting/system.py:908 +#: common/setting/system.py:935 +msgid "Enable Transfer Orders" +msgstr "" + +#: common/setting/system.py:936 +msgid "Enable transfer order functionality in the user interface" +msgstr "" + +#: common/setting/system.py:941 +msgid "Transfer Order Reference Pattern" +msgstr "" + +#: common/setting/system.py:943 +msgid "Required pattern for generating Transfer Order reference field" +msgstr "" + +#: common/setting/system.py:955 +msgid "Edit Completed Transfer Orders" +msgstr "" + +#: common/setting/system.py:957 +msgid "Allow editing of transfer orders after they have been completed" +msgstr "" + +#: common/setting/system.py:963 msgid "Block Incomplete Item Tests" msgstr "" -#: common/setting/system.py:910 +#: common/setting/system.py:965 msgid "Prevent allocation of stock items to sales orders if required item tests are incomplete" msgstr "" -#: common/setting/system.py:916 +#: common/setting/system.py:971 msgid "Purchase Order Reference Pattern" msgstr "採購訂單參考模式" -#: common/setting/system.py:918 +#: common/setting/system.py:973 msgid "Required pattern for generating Purchase Order reference field" msgstr "生成採購訂單參考字段所需的模式" -#: common/setting/system.py:930 +#: common/setting/system.py:985 msgid "Edit Completed Purchase Orders" msgstr "編輯已完成的採購訂單" -#: common/setting/system.py:932 +#: common/setting/system.py:987 msgid "Allow editing of purchase orders after they have been shipped or completed" msgstr "允許在採購訂單已配送或完成後編輯訂單" -#: common/setting/system.py:938 +#: common/setting/system.py:993 msgid "Convert Currency" msgstr "轉換幣別" -#: common/setting/system.py:939 +#: common/setting/system.py:994 msgid "Convert item value to base currency when receiving stock" msgstr "收貨時將項目價值換算為基準幣別" -#: common/setting/system.py:944 +#: common/setting/system.py:999 msgid "Auto Complete Purchase Orders" msgstr "自動完成採購訂單" -#: common/setting/system.py:946 +#: common/setting/system.py:1001 msgid "Automatically mark purchase orders as complete when all line items are received" msgstr "當收到所有行項目時,自動將採購訂單標記為完成" -#: common/setting/system.py:953 +#: common/setting/system.py:1007 +msgid "Merge Purchase Order Line Items" +msgstr "" + +#: common/setting/system.py:1009 +msgid "Merge new purchase order line items with existing lines that share the same part, destination, and target date" +msgstr "" + +#: common/setting/system.py:1016 msgid "Enable password forgot" msgstr "忘記啓用密碼" -#: common/setting/system.py:954 +#: common/setting/system.py:1017 msgid "Enable password forgot function on the login pages" msgstr "在登錄頁面上啓用忘記密碼功能" -#: common/setting/system.py:959 +#: common/setting/system.py:1022 msgid "Enable registration" msgstr "啓用註冊" -#: common/setting/system.py:960 +#: common/setting/system.py:1023 msgid "Enable self-registration for users on the login pages" msgstr "在登錄頁面為用户啓用自行註冊功能" -#: common/setting/system.py:965 +#: common/setting/system.py:1028 msgid "Enable SSO" msgstr "啓用單點登錄" -#: common/setting/system.py:966 +#: common/setting/system.py:1029 msgid "Enable SSO on the login pages" msgstr "在登錄界面啓用單點登錄" -#: common/setting/system.py:971 +#: common/setting/system.py:1034 msgid "Enable SSO registration" msgstr "啓用單點登錄註冊" -#: common/setting/system.py:973 +#: common/setting/system.py:1036 msgid "Enable self-registration via SSO for users on the login pages" msgstr "允許登錄頁面上的用户通過 SSO 進行自我註冊" -#: common/setting/system.py:979 +#: common/setting/system.py:1042 msgid "Enable SSO group sync" msgstr "啓用單點登錄羣組同步" -#: common/setting/system.py:981 +#: common/setting/system.py:1044 msgid "Enable synchronizing InvenTree groups with groups provided by the IdP" msgstr "啓用庫存管理系統組和由身份提供者提供的組的同步功能" -#: common/setting/system.py:987 +#: common/setting/system.py:1050 msgid "SSO group key" msgstr "單點登錄系統組密鑰" -#: common/setting/system.py:988 +#: common/setting/system.py:1051 msgid "The name of the groups claim attribute provided by the IdP" msgstr "由身份提供者提供的組聲明屬性名稱" -#: common/setting/system.py:993 +#: common/setting/system.py:1056 msgid "SSO group map" msgstr "單點登錄系統組地圖" -#: common/setting/system.py:995 +#: common/setting/system.py:1058 msgid "A mapping from SSO groups to local InvenTree groups. If the local group does not exist, it will be created." msgstr "從單點登錄系統組組到本地庫存管理系統組的映射。如果本地組不存在,它將被創建。" -#: common/setting/system.py:1001 +#: common/setting/system.py:1064 msgid "Remove groups outside of SSO" msgstr "移除單點登錄系統以外的羣組" -#: common/setting/system.py:1003 +#: common/setting/system.py:1066 msgid "Whether groups assigned to the user should be removed if they are not backend by the IdP. Disabling this setting might cause security issues" msgstr "如果分配給用户的組不是身份提供者的後端,是否應該刪除它們。禁用此設置可能會造成安全問題" -#: common/setting/system.py:1009 +#: common/setting/system.py:1072 msgid "Email required" msgstr "需要郵箱地址" -#: common/setting/system.py:1010 +#: common/setting/system.py:1073 msgid "Require user to supply mail on signup" msgstr "要求用户在註冊時提供郵件" -#: common/setting/system.py:1015 +#: common/setting/system.py:1078 msgid "Auto-fill SSO users" msgstr "自動填充單點登錄系統用户" -#: common/setting/system.py:1016 +#: common/setting/system.py:1079 msgid "Automatically fill out user-details from SSO account-data" msgstr "自動使用單點登錄系統賬户的數據填寫用户詳細信息" -#: common/setting/system.py:1021 +#: common/setting/system.py:1084 msgid "Mail twice" msgstr "發兩次郵件" -#: common/setting/system.py:1022 +#: common/setting/system.py:1085 msgid "On signup ask users twice for their mail" msgstr "註冊時詢問用户他們的電子郵件兩次" -#: common/setting/system.py:1027 +#: common/setting/system.py:1090 msgid "Password twice" msgstr "兩次輸入密碼" -#: common/setting/system.py:1028 +#: common/setting/system.py:1091 msgid "On signup ask users twice for their password" msgstr "當註冊時請用户輸入密碼兩次" -#: common/setting/system.py:1033 +#: common/setting/system.py:1096 msgid "Allowed domains" msgstr "域名白名單" -#: common/setting/system.py:1035 +#: common/setting/system.py:1098 msgid "Restrict signup to certain domains (comma-separated, starting with @)" msgstr "限制註冊到某些域名 (逗號分隔,以 @ 開頭)" -#: common/setting/system.py:1041 +#: common/setting/system.py:1104 msgid "Group on signup" msgstr "註冊羣組" -#: common/setting/system.py:1043 +#: common/setting/system.py:1106 msgid "Group to which new users are assigned on registration. If SSO group sync is enabled, this group is only set if no group can be assigned from the IdP." msgstr "註冊時分配給新用户的組。 如果啓用了單點登錄系統羣組同步,此羣組僅在無法從 IdP 分配任何羣組的情況下才被設置。" -#: common/setting/system.py:1049 +#: common/setting/system.py:1112 msgid "Enforce MFA" msgstr "強制啓用多因素安全認證" -#: common/setting/system.py:1050 +#: common/setting/system.py:1113 msgid "Users must use multifactor security." msgstr "用户必須使用多因素安全認證。" -#: common/setting/system.py:1055 +#: common/setting/system.py:1118 msgid "Enabling this setting will require all users to set up multifactor authentication. All sessions will be disconnected immediately." msgstr "啟用此設定將要求所有使用者設定多因素驗證。所有工作階段將立即中斷連線。" -#: common/setting/system.py:1060 +#: common/setting/system.py:1123 msgid "Check plugins on startup" msgstr "啓動時檢查插件" -#: common/setting/system.py:1062 +#: common/setting/system.py:1125 msgid "Check that all plugins are installed on startup - enable in container environments" msgstr "啓動時檢查全部插件是否已安裝 - 在容器環境中啓用" -#: common/setting/system.py:1069 +#: common/setting/system.py:1132 msgid "Check for plugin updates" msgstr "檢查插件更新" -#: common/setting/system.py:1070 +#: common/setting/system.py:1133 msgid "Enable periodic checks for updates to installed plugins" msgstr "啓用定期檢查已安裝插件的更新" -#: common/setting/system.py:1076 +#: common/setting/system.py:1139 msgid "Enable URL integration" msgstr "啓用統一資源定位符集成" -#: common/setting/system.py:1077 +#: common/setting/system.py:1140 msgid "Enable plugins to add URL routes" msgstr "啓用插件以添加統一資源定位符路由" -#: common/setting/system.py:1083 +#: common/setting/system.py:1146 msgid "Enable navigation integration" msgstr "啓用導航集成" -#: common/setting/system.py:1084 +#: common/setting/system.py:1147 msgid "Enable plugins to integrate into navigation" msgstr "啓用插件以集成到導航中" -#: common/setting/system.py:1090 +#: common/setting/system.py:1153 msgid "Enable app integration" msgstr "啓用應用集成" -#: common/setting/system.py:1091 +#: common/setting/system.py:1154 msgid "Enable plugins to add apps" msgstr "啓用插件添加應用" -#: common/setting/system.py:1097 +#: common/setting/system.py:1160 msgid "Enable schedule integration" msgstr "啓用調度集成" -#: common/setting/system.py:1098 +#: common/setting/system.py:1161 msgid "Enable plugins to run scheduled tasks" msgstr "啓用插件來運行預定任務" -#: common/setting/system.py:1104 +#: common/setting/system.py:1167 msgid "Enable event integration" msgstr "啓用事件集成" -#: common/setting/system.py:1105 +#: common/setting/system.py:1168 msgid "Enable plugins to respond to internal events" msgstr "啓用插件響應內部事件" -#: common/setting/system.py:1111 +#: common/setting/system.py:1174 msgid "Enable interface integration" msgstr "啓用界面集成" -#: common/setting/system.py:1112 +#: common/setting/system.py:1175 msgid "Enable plugins to integrate into the user interface" msgstr "啓用插件集成到用户界面" -#: common/setting/system.py:1118 +#: common/setting/system.py:1181 msgid "Enable mail integration" msgstr "啟用郵件整合" -#: common/setting/system.py:1119 +#: common/setting/system.py:1182 msgid "Enable plugins to process outgoing/incoming mails" msgstr "允許模組處理寄出/接收郵件" -#: common/setting/system.py:1125 +#: common/setting/system.py:1188 msgid "Enable project codes" msgstr "啟用專案代碼" -#: common/setting/system.py:1126 +#: common/setting/system.py:1189 msgid "Enable project codes for tracking projects" msgstr "啟用專案代碼以追蹤專案" -#: common/setting/system.py:1131 +#: common/setting/system.py:1194 msgid "Enable Stocktake" msgstr "啟用盤點" -#: common/setting/system.py:1133 +#: common/setting/system.py:1196 msgid "Enable functionality for recording historical stock levels and value" msgstr "啟用記錄庫存數量及價值歷史的功能" -#: common/setting/system.py:1139 +#: common/setting/system.py:1202 msgid "Exclude External Locations" msgstr "排除外部地點" -#: common/setting/system.py:1141 +#: common/setting/system.py:1204 msgid "Exclude stock items in external locations from stocktake calculations" msgstr "從盤點計算中排除外部位置的庫存項目" -#: common/setting/system.py:1147 +#: common/setting/system.py:1210 msgid "Automatic Stocktake Period" msgstr "自動盤點週期" -#: common/setting/system.py:1148 +#: common/setting/system.py:1211 msgid "Number of days between automatic stocktake recording" msgstr "自動記錄盤點的天數間隔" -#: common/setting/system.py:1154 +#: common/setting/system.py:1217 msgid "Delete Old Stocktake Entries" msgstr "刪除舊的盤點項目" -#: common/setting/system.py:1156 +#: common/setting/system.py:1219 msgid "Delete stocktake entries older than the specified number of days" msgstr "刪除超過指定天數的盤點項目" -#: common/setting/system.py:1162 +#: common/setting/system.py:1225 msgid "Stocktake Deletion Interval" msgstr "盤點刪除間隔" -#: common/setting/system.py:1164 +#: common/setting/system.py:1227 msgid "Stocktake entries will be deleted after specified number of days" msgstr "盤點項目將在指定天數後刪除" -#: common/setting/system.py:1171 +#: common/setting/system.py:1234 msgid "Delete Old Stock Tracking Entries" msgstr "刪除舊庫存的追蹤紀錄" -#: common/setting/system.py:1173 +#: common/setting/system.py:1236 msgid "Delete stock tracking entries older than the specified number of days" msgstr "刪除超過指定天數的庫存追蹤項目" -#: common/setting/system.py:1179 +#: common/setting/system.py:1242 msgid "Stock Tracking Deletion Interval" msgstr "庫存追蹤刪除間隔" -#: common/setting/system.py:1181 +#: common/setting/system.py:1244 msgid "Stock tracking entries will be deleted after specified number of days" msgstr "庫存追蹤項目將在指定天數後刪除" -#: common/setting/system.py:1188 +#: common/setting/system.py:1251 msgid "Display Users full names" msgstr "顯示用户全名" -#: common/setting/system.py:1189 +#: common/setting/system.py:1252 msgid "Display Users full names instead of usernames" msgstr "顯示用户全名而不是用户名" -#: common/setting/system.py:1194 +#: common/setting/system.py:1257 msgid "Display User Profiles" msgstr "顯示使用者個人檔案" -#: common/setting/system.py:1195 +#: common/setting/system.py:1258 msgid "Display Users Profiles on their profile page" msgstr "在個人頁面顯示使用者檔案資訊" -#: common/setting/system.py:1200 +#: common/setting/system.py:1263 msgid "Week Starts On" msgstr "" -#: common/setting/system.py:1201 +#: common/setting/system.py:1264 msgid "Starting day of the week, for display in calendar views" msgstr "" -#: common/setting/system.py:1204 +#: common/setting/system.py:1267 msgid "Sunday" msgstr "" -#: common/setting/system.py:1205 +#: common/setting/system.py:1268 msgid "Monday" msgstr "" -#: common/setting/system.py:1206 +#: common/setting/system.py:1269 msgid "Tuesday" msgstr "" -#: common/setting/system.py:1207 +#: common/setting/system.py:1270 msgid "Wednesday" msgstr "" -#: common/setting/system.py:1208 +#: common/setting/system.py:1271 msgid "Thursday" msgstr "" -#: common/setting/system.py:1209 +#: common/setting/system.py:1272 msgid "Friday" msgstr "" -#: common/setting/system.py:1210 +#: common/setting/system.py:1273 msgid "Saturday" msgstr "" -#: common/setting/system.py:1214 +#: common/setting/system.py:1277 +msgid "Calendar Horizon" +msgstr "" + +#: common/setting/system.py:1279 +msgid "Number of months into the future to display in calendar views" +msgstr "" + +#: common/setting/system.py:1283 +msgid "months" +msgstr "" + +#: common/setting/system.py:1286 msgid "Enable Test Station Data" msgstr "啓用測試站數據" -#: common/setting/system.py:1215 +#: common/setting/system.py:1287 msgid "Enable test station data collection for test results" msgstr "啓用測試站數據收集以獲取測試結果" -#: common/setting/system.py:1220 +#: common/setting/system.py:1292 msgid "Enable Machine Ping" msgstr "啟用設備 Ping" -#: common/setting/system.py:1222 +#: common/setting/system.py:1294 msgid "Enable periodic ping task of registered machines to check their status" msgstr "啟用對已註冊機器的定期 ping 任務以檢查其狀態" @@ -3881,213 +4112,246 @@ msgid "Number of results to show in each section of the search preview window" msgstr "在搜索預覽窗口的每個部分中顯示的結果數" #: common/setting/user.py:163 +msgid "Search Results Preview Panel" +msgstr "" + +#: common/setting/user.py:165 +msgid "Open search results in the preview panel, rather than navigating directly to the result" +msgstr "" + +#: common/setting/user.py:171 msgid "Regex Search" msgstr "正則表達式搜索" -#: common/setting/user.py:164 +#: common/setting/user.py:172 msgid "Enable regular expressions in search queries" msgstr "在搜索查詢中啓用正則表達式" -#: common/setting/user.py:169 +#: common/setting/user.py:177 msgid "Whole Word Search" msgstr "整詞搜索" -#: common/setting/user.py:170 +#: common/setting/user.py:178 msgid "Search queries return results for whole word matches" msgstr "搜索查詢返回整詞匹配的結果" -#: common/setting/user.py:175 +#: common/setting/user.py:183 msgid "Search Notes" msgstr "搜尋備註" -#: common/setting/user.py:177 +#: common/setting/user.py:185 msgid "Search queries return results for matches from the item's notes" msgstr "於搜尋結果中包含項目的備註匹配" -#: common/setting/user.py:183 +#: common/setting/user.py:191 msgid "Escape Key Closes Forms" msgstr "Esc鍵關閉窗體" -#: common/setting/user.py:184 +#: common/setting/user.py:192 msgid "Use the escape key to close modal forms" msgstr "使用ESC鍵關閉模態窗體" -#: common/setting/user.py:189 +#: common/setting/user.py:197 msgid "Fixed Navbar" msgstr "固定導航欄" -#: common/setting/user.py:190 +#: common/setting/user.py:198 msgid "The navbar position is fixed to the top of the screen" msgstr "導航欄位置固定在屏幕頂部" -#: common/setting/user.py:195 +#: common/setting/user.py:203 msgid "Fixed Table Headers" msgstr "固定表格表頭" -#: common/setting/user.py:196 +#: common/setting/user.py:204 msgid "Table headers are fixed to the top of the table" msgstr "表格表頭固定於表格頂端" -#: common/setting/user.py:201 +#: common/setting/user.py:209 msgid "Show Spotlight" msgstr "顯示 Spotlight 導覽" -#: common/setting/user.py:202 +#: common/setting/user.py:210 msgid "Enable spotlight navigation functionality" msgstr "啟用 Spotlight 導覽功能" -#: common/setting/user.py:207 +#: common/setting/user.py:215 msgid "Navigation Icons" msgstr "導覽圖示" -#: common/setting/user.py:208 +#: common/setting/user.py:216 msgid "Display icons in the navigation bar" msgstr "在導覽列顯示圖示" -#: common/setting/user.py:213 +#: common/setting/user.py:221 msgid "Date Format" msgstr "時間格式" -#: common/setting/user.py:214 +#: common/setting/user.py:222 msgid "Preferred format for displaying dates" msgstr "顯示時間的首選格式" -#: common/setting/user.py:227 +#: common/setting/user.py:235 +msgid "Table Preview Panel" +msgstr "" + +#: common/setting/user.py:236 +msgid "Display a preview panel when selecting items in tables" +msgstr "" + +#: common/setting/user.py:241 msgid "Show Stock History" msgstr "顯示庫存歷史" -#: common/setting/user.py:228 +#: common/setting/user.py:242 msgid "Display stock history information in the part detail page" msgstr "在零件詳細頁顯示庫存歷史資訊" -#: common/setting/user.py:233 +#: common/setting/user.py:247 msgid "Show Last Breadcrumb" msgstr "顯示當前麵包屑節點" -#: common/setting/user.py:234 +#: common/setting/user.py:248 msgid "Show the current page in breadcrumbs" msgstr "在麵包屑中顯示目前頁面" -#: common/setting/user.py:239 +#: common/setting/user.py:253 +msgid "Show Extra Model Information" +msgstr "" + +#: common/setting/user.py:254 +msgid "Display extra information in model selection dropdowns" +msgstr "" + +#: common/setting/user.py:259 msgid "Show full stock location in tables" msgstr "表格中顯示完整庫存位置" -#: common/setting/user.py:241 +#: common/setting/user.py:261 msgid "Disabled: The full location path is displayed as a hover tooltip. Enabled: The full location path is displayed as plain text." msgstr "停用:完整位置路徑以滑鼠懸停提示顯示。啟用:直接以文字顯示完整路徑。" -#: common/setting/user.py:247 +#: common/setting/user.py:267 msgid "Show full part categories in tables" msgstr "表格中顯示完整零件分類" -#: common/setting/user.py:249 +#: common/setting/user.py:269 msgid "Disabled: The full category path is displayed as a hover tooltip. Enabled: The full category path is displayed as plain text." msgstr "停用:完整分類路徑以滑鼠懸停提示顯示。啟用:直接以文字顯示完整路徑。" -#: common/setting/user.py:255 +#: common/setting/user.py:275 msgid "Show Subassemblies in BOM table" msgstr "" -#: common/setting/user.py:256 +#: common/setting/user.py:276 msgid "Enable display of subassemblies in the BOM table" msgstr "" -#: common/setting/user.py:261 +#: common/setting/user.py:281 msgid "Receive error reports" msgstr "接收錯誤報告" -#: common/setting/user.py:262 +#: common/setting/user.py:282 msgid "Receive notifications for system errors" msgstr "接收系統錯誤通知" -#: common/setting/user.py:267 +#: common/setting/user.py:287 msgid "Last used printing machines" msgstr "上次使用的打印設備" -#: common/setting/user.py:268 +#: common/setting/user.py:288 msgid "Save the last used printing machines for a user" msgstr "為用户保存上次使用的打印設備" -#: common/setting/user.py:272 +#: common/setting/user.py:292 msgid "Display Items at Final Level" msgstr "" -#: common/setting/user.py:274 +#: common/setting/user.py:294 msgid "Automatically default to showing items/parts instead of sub-levels for locations or categories with no children" msgstr "" -#: common/validators.py:38 +#: common/validators.py:40 msgid "All models" msgstr "所有模型" -#: common/validators.py:63 +#: common/validators.py:65 msgid "No attachment model type provided" msgstr "未提供附件型號" -#: common/validators.py:69 +#: common/validators.py:71 msgid "Invalid attachment model type" msgstr "附件模型類型無效" -#: common/validators.py:110 +#: common/validators.py:87 +#, python-brace-format +msgid "File size exceeds maximum upload limit of {max_size} MB" +msgstr "" + +#: common/validators.py:93 +msgid "Invalid file name" +msgstr "" + +#: common/validators.py:127 msgid "Minimum places cannot be greater than maximum places" msgstr "最小位置不能大於最大位置" -#: common/validators.py:122 +#: common/validators.py:139 msgid "Maximum places cannot be less than minimum places" msgstr "最大名額不能小於最小名額" -#: common/validators.py:133 +#: common/validators.py:150 msgid "An empty domain is not allowed." msgstr "不允許空域。" -#: common/validators.py:135 +#: common/validators.py:152 #, python-brace-format msgid "Invalid domain name: {domain}" msgstr "無效的域名: {domain}" -#: common/validators.py:151 +#: common/validators.py:168 msgid "Value must be uppercase" msgstr "值必須為大寫" -#: common/validators.py:157 +#: common/validators.py:174 msgid "Value must be a valid variable identifier" msgstr "值必須為有效的變數識別符" -#: company/api.py:141 +#: company/api.py:148 msgid "Part is Active" msgstr "零件已激活" -#: company/api.py:145 +#: company/api.py:152 msgid "Manufacturer is Active" msgstr "製造商處於活動狀態" -#: company/api.py:252 +#: company/api.py:261 msgid "Supplier Part is Active" msgstr "供應商零件處於激活狀態" -#: company/api.py:254 +#: company/api.py:263 msgid "Primary Supplier Part" msgstr "主要供應商零件" -#: company/api.py:258 +#: company/api.py:267 msgid "Internal Part is Active" msgstr "內部零件已激活" -#: company/api.py:263 +#: company/api.py:272 msgid "Supplier is Active" msgstr "供應商已激活" -#: company/api.py:275 company/models.py:535 company/serializers.py:446 -#: part/serializers.py:489 +#: company/api.py:284 company/models.py:540 company/serializers.py:499 +#: part/serializers.py:468 msgid "Manufacturer" msgstr "製造商" -#: company/api.py:282 company/models.py:124 company/models.py:404 -#: stock/api.py:899 +#: company/api.py:291 company/models.py:124 company/models.py:408 +#: stock/api.py:954 msgid "Company" msgstr "公司" -#: company/api.py:292 +#: company/api.py:301 msgid "Has Stock" msgstr "有庫存" @@ -4123,8 +4387,8 @@ msgstr "聯繫電話" msgid "Contact email address" msgstr "聯繫人電子郵箱地址" -#: company/models.py:181 company/models.py:311 order/models.py:525 -#: users/models.py:559 +#: company/models.py:181 company/models.py:315 order/models.py:586 +#: users/models.py:557 msgid "Contact" msgstr "聯繫人" @@ -4176,283 +4440,283 @@ msgstr "稅籍編號" msgid "Company Tax ID" msgstr "公司稅籍編號" -#: company/models.py:350 order/models.py:535 order/models.py:2371 +#: company/models.py:354 order/models.py:596 order/models.py:2681 msgid "Address" msgstr "地址" -#: company/models.py:351 +#: company/models.py:355 msgid "Addresses" msgstr "地址" -#: company/models.py:405 +#: company/models.py:409 msgid "Select company" msgstr "選擇公司" -#: company/models.py:410 +#: company/models.py:414 msgid "Address title" msgstr "地址標題" -#: company/models.py:411 +#: company/models.py:415 msgid "Title describing the address entry" msgstr "描述地址條目的標題" -#: company/models.py:417 +#: company/models.py:421 msgid "Primary address" msgstr "主要地址" -#: company/models.py:418 +#: company/models.py:422 msgid "Set as primary address" msgstr "設置主要地址" -#: company/models.py:423 +#: company/models.py:427 msgid "Line 1" msgstr "第1行" -#: company/models.py:424 +#: company/models.py:428 msgid "Address line 1" msgstr "地址行1" -#: company/models.py:430 +#: company/models.py:434 msgid "Line 2" msgstr "第2行" -#: company/models.py:431 +#: company/models.py:435 msgid "Address line 2" msgstr "地址行2" -#: company/models.py:437 company/models.py:438 +#: company/models.py:441 company/models.py:442 msgid "Postal code" msgstr "郵政編碼" -#: company/models.py:444 +#: company/models.py:448 msgid "City/Region" msgstr "城市/地區" -#: company/models.py:445 +#: company/models.py:449 msgid "Postal code city/region" msgstr "郵政編碼城市/地區" -#: company/models.py:451 +#: company/models.py:455 msgid "State/Province" msgstr "省/市/自治區" -#: company/models.py:452 +#: company/models.py:456 msgid "State or province" msgstr "省、自治區或直轄市" -#: company/models.py:458 +#: company/models.py:462 msgid "Country" msgstr "國家/地區" -#: company/models.py:459 +#: company/models.py:463 msgid "Address country" msgstr "地址所在國家" -#: company/models.py:465 +#: company/models.py:469 msgid "Courier shipping notes" msgstr "快遞運單" -#: company/models.py:466 +#: company/models.py:470 msgid "Notes for shipping courier" msgstr "運輸快遞注意事項" -#: company/models.py:472 +#: company/models.py:476 msgid "Internal shipping notes" msgstr "內部裝運通知單" -#: company/models.py:473 +#: company/models.py:477 msgid "Shipping notes for internal use" msgstr "內部使用的裝運通知單" -#: company/models.py:480 +#: company/models.py:484 msgid "Link to address information (external)" msgstr "鏈接地址信息 (外部)" -#: company/models.py:507 company/models.py:802 company/serializers.py:474 -#: stock/api.py:560 +#: company/models.py:512 company/models.py:803 company/serializers.py:527 +#: stock/api.py:620 msgid "Manufacturer Part" msgstr "製造商零件" -#: company/models.py:524 company/models.py:764 stock/models.py:1056 -#: stock/serializers.py:418 +#: company/models.py:529 company/models.py:765 stock/models.py:1164 +#: stock/serializers.py:427 msgid "Base Part" msgstr "基礎零件" -#: company/models.py:526 company/models.py:766 +#: company/models.py:531 company/models.py:767 msgid "Select part" msgstr "選擇零件" -#: company/models.py:536 +#: company/models.py:541 msgid "Select manufacturer" msgstr "選擇製造商" -#: company/models.py:542 company/serializers.py:485 order/serializers.py:743 -#: part/serializers.py:499 +#: company/models.py:547 company/serializers.py:538 order/serializers.py:764 +#: part/serializers.py:478 msgid "MPN" msgstr "製造商零件編號" -#: company/models.py:543 stock/serializers.py:578 +#: company/models.py:548 stock/serializers.py:585 msgid "Manufacturer Part Number" msgstr "製造商零件編號" -#: company/models.py:550 +#: company/models.py:555 msgid "URL for external manufacturer part link" msgstr "外部製造商零件鏈接的URL" -#: company/models.py:559 +#: company/models.py:564 msgid "Manufacturer part description" msgstr "製造商零件説明" -#: company/models.py:691 +#: company/models.py:692 msgid "Pack units must be compatible with the base part units" msgstr "包裝單位必須與基礎零件單位兼容" -#: company/models.py:698 +#: company/models.py:699 msgid "Pack units must be greater than zero" msgstr "包裝單位必須大於零" -#: company/models.py:712 +#: company/models.py:713 msgid "Linked manufacturer part must reference the same base part" msgstr "鏈接的製造商零件必須引用相同的基礎零件" -#: company/models.py:774 company/serializers.py:433 company/serializers.py:468 -#: order/models.py:666 part/serializers.py:473 +#: company/models.py:775 company/serializers.py:486 company/serializers.py:521 +#: order/models.py:741 part/serializers.py:452 #: plugin/builtin/suppliers/digikey.py:26 plugin/builtin/suppliers/lcsc.py:27 #: plugin/builtin/suppliers/mouser.py:25 plugin/builtin/suppliers/tme.py:27 -#: stock/api.py:566 templates/email/overdue_purchase_order.html:16 +#: stock/api.py:626 templates/email/overdue_purchase_order.html:16 msgid "Supplier" msgstr "供應商" -#: company/models.py:775 +#: company/models.py:776 msgid "Select supplier" msgstr "選擇供應商" -#: company/models.py:781 part/serializers.py:484 +#: company/models.py:782 part/serializers.py:463 msgid "Supplier stock keeping unit" msgstr "供應商庫存管理單位" -#: company/models.py:787 +#: company/models.py:788 msgid "Is this supplier part active?" msgstr "此供應商零件是否處於活動狀態?" -#: company/models.py:792 +#: company/models.py:793 msgid "Primary" msgstr "主要" -#: company/models.py:793 +#: company/models.py:794 msgid "Is this the primary supplier part for the linked Part?" msgstr "這是關聯零件的主要供應商零件嗎?" -#: company/models.py:803 +#: company/models.py:804 msgid "Select manufacturer part" msgstr "選擇製造商零件" -#: company/models.py:810 +#: company/models.py:811 msgid "URL for external supplier part link" msgstr "外部供應商零件鏈接的URL" -#: company/models.py:819 +#: company/models.py:820 msgid "Supplier part description" msgstr "供應商零件説明" -#: company/models.py:835 part/models.py:2310 +#: company/models.py:836 part/models.py:2239 msgid "base cost" msgstr "基本費用" -#: company/models.py:836 part/models.py:2311 +#: company/models.py:837 part/models.py:2240 msgid "Minimum charge (e.g. stocking fee)" msgstr "最低費用(例如庫存費)" -#: company/models.py:843 order/serializers.py:888 stock/models.py:1087 -#: stock/serializers.py:1681 +#: company/models.py:844 order/serializers.py:909 stock/models.py:1195 +#: stock/serializers.py:1935 msgid "Packaging" msgstr "打包" -#: company/models.py:844 +#: company/models.py:845 msgid "Part packaging" msgstr "零件打包" -#: company/models.py:849 +#: company/models.py:850 msgid "Pack Quantity" msgstr "包裝數量" -#: company/models.py:851 +#: company/models.py:852 msgid "Total quantity supplied in a single pack. Leave empty for single items." msgstr "單包供應的總數量。為單個項目留空。" -#: company/models.py:870 part/models.py:2317 +#: company/models.py:871 part/models.py:2246 msgid "multiple" msgstr "多個" -#: company/models.py:871 +#: company/models.py:872 msgid "Order multiple" msgstr "訂購多個" -#: company/models.py:883 +#: company/models.py:884 msgid "Quantity available from supplier" msgstr "供應商提供的數量" -#: company/models.py:889 +#: company/models.py:890 msgid "Availability Updated" msgstr "可用性已更新" -#: company/models.py:890 +#: company/models.py:891 msgid "Date of last update of availability data" msgstr "上次更新可用性數據的日期" -#: company/models.py:1018 +#: company/models.py:1019 msgid "Supplier Price Break" msgstr "供應商批發價" -#: company/serializers.py:185 +#: company/serializers.py:192 msgid "Default currency used for this supplier" msgstr "此供應商使用的默認貨幣" -#: company/serializers.py:202 +#: company/serializers.py:228 msgid "Company Name" msgstr "公司名稱" -#: company/serializers.py:390 part/serializers.py:854 stock/serializers.py:444 +#: company/serializers.py:443 part/serializers.py:840 stock/serializers.py:453 msgid "In Stock" msgstr "有庫存" -#: company/serializers.py:408 +#: company/serializers.py:461 msgid "Price Breaks" msgstr "價格折扣" -#: company/serializers.py:461 +#: company/serializers.py:514 msgid "Pretty Name" msgstr "顯示名稱" -#: data_exporter/mixins.py:328 data_exporter/mixins.py:417 +#: data_exporter/mixins.py:341 data_exporter/mixins.py:430 msgid "Error occurred during data export" msgstr "資料匯出過程發生錯誤" -#: data_exporter/mixins.py:395 +#: data_exporter/mixins.py:408 msgid "Data export plugin returned incorrect data format" msgstr "資料匯出模組回傳的資料格式不正確" -#: data_exporter/serializers.py:73 +#: data_exporter/serializers.py:83 msgid "Export Format" msgstr "匯出格式" -#: data_exporter/serializers.py:74 +#: data_exporter/serializers.py:84 msgid "Select export file format" msgstr "選擇匯出檔案格式" -#: data_exporter/serializers.py:81 +#: data_exporter/serializers.py:91 msgid "Export Plugin" msgstr "匯出模組" -#: data_exporter/serializers.py:82 +#: data_exporter/serializers.py:92 msgid "Select export plugin" msgstr "選擇匯出模組" -#: generic/states/fields.py:146 +#: generic/states/fields.py:174 msgid "Additional status information for this item" msgstr "此項目的附加狀態信息" -#: generic/states/fields.py:160 +#: generic/states/fields.py:188 msgid "Custom status key" msgstr "自定義狀態密鑰" @@ -4476,123 +4740,152 @@ msgstr "放置" msgid "Invalid status code" msgstr "無效的狀態代碼" -#: importer/models.py:74 +#: importer/models.py:76 msgid "Data File" msgstr "數據文件" -#: importer/models.py:75 +#: importer/models.py:77 msgid "Data file to import" msgstr "要導入的數據文件" -#: importer/models.py:84 +#: importer/models.py:87 msgid "Columns" msgstr "列" -#: importer/models.py:91 +#: importer/models.py:95 msgid "Target model type for this import session" msgstr "此匯入作業的目標模型類型" -#: importer/models.py:97 +#: importer/models.py:101 msgid "Import status" msgstr "導入狀態" -#: importer/models.py:107 +#: importer/models.py:111 msgid "Field Defaults" msgstr "字段默認值" -#: importer/models.py:114 +#: importer/models.py:119 msgid "Field Overrides" msgstr "字段覆蓋" -#: importer/models.py:121 +#: importer/models.py:127 msgid "Field Filters" msgstr "字段篩選器" -#: importer/models.py:127 +#: importer/models.py:134 msgid "Update Existing Records" msgstr "更新既有紀錄" -#: importer/models.py:128 +#: importer/models.py:135 msgid "If enabled, existing records will be updated with new data" msgstr "啟用時,既有紀錄將以新資料更新" -#: importer/models.py:281 +#: importer/models.py:325 msgid "Some required fields have not been mapped" msgstr "某些必填字段尚未映射" -#: importer/models.py:388 +#: importer/models.py:427 +msgid "Completed Row Count History" +msgstr "" + +#: importer/models.py:430 +msgid "Row Count History" +msgstr "" + +#: importer/models.py:453 msgid "ID" msgstr "ID" -#: importer/models.py:389 +#: importer/models.py:454 msgid "Existing database identifier for the record" msgstr "資料庫中既有紀錄的識別碼" -#: importer/models.py:459 +#: importer/models.py:532 msgid "Column is already mapped to a database field" msgstr "列已映射到數據庫字段" -#: importer/models.py:464 +#: importer/models.py:537 msgid "Field is already mapped to a data column" msgstr "字段已映射到數據列" -#: importer/models.py:473 +#: importer/models.py:546 msgid "Column mapping must be linked to a valid import session" msgstr "列映射必須鏈接到有效的導入會話" -#: importer/models.py:478 +#: importer/models.py:551 msgid "Column does not exist in the data file" msgstr "數據文件中不存在列" -#: importer/models.py:485 +#: importer/models.py:558 msgid "Field does not exist in the target model" msgstr "目標模型中不存在字段" -#: importer/models.py:489 +#: importer/models.py:562 msgid "Selected field is read-only" msgstr "所選字段為只讀" -#: importer/models.py:494 importer/models.py:571 +#: importer/models.py:568 +msgid "Lookup field can only be set for related (foreign-key) fields" +msgstr "" + +#: importer/models.py:576 +#, python-brace-format +msgid "Invalid lookup field. Valid options are: {options}" +msgstr "" + +#: importer/models.py:583 importer/models.py:670 msgid "Import Session" msgstr "導入會話" -#: importer/models.py:498 +#: importer/models.py:587 msgid "Field" msgstr "字段" -#: importer/models.py:500 +#: importer/models.py:589 msgid "Column" msgstr "列" -#: importer/models.py:575 +#: importer/models.py:595 +msgid "Lookup Field" +msgstr "" + +#: importer/models.py:597 +msgid "Database field to use for foreign-key lookup. Leave blank for automatic lookup." +msgstr "" + +#: importer/models.py:674 msgid "Row Index" msgstr "行索引" -#: importer/models.py:578 +#: importer/models.py:679 msgid "Original row data" msgstr "原始行數據" -#: importer/models.py:583 machine/models.py:111 +#: importer/models.py:688 machine/models.py:114 msgid "Errors" msgstr "錯誤" -#: importer/models.py:585 part/serializers.py:1148 +#: importer/models.py:691 part/serializers.py:1161 msgid "Valid" msgstr "有效" -#: importer/models.py:846 -msgid "ID is required for updating existing records." -msgstr "更新既有紀錄需要提供 ID。" +#: importer/models.py:932 +msgid "Multiple matches found for value - please ensure the value is unique, or select a specific lookup field" +msgstr "" -#: importer/models.py:853 +#: importer/models.py:985 msgid "No record found with the provided ID" msgstr "找不到提供 ID 的記錄" -#: importer/models.py:859 +#: importer/models.py:990 msgid "Invalid ID format provided" msgstr "提供的 ID 格式無效" -#: importer/operations.py:31 importer/operations.py:52 +#: importer/models.py:1056 +msgid "ID is required for updating existing records." +msgstr "更新既有紀錄需要提供 ID。" + +#: importer/operations.py:31 importer/operations.py:60 msgid "Unsupported data file format" msgstr "不支持的數據文件格式" @@ -4600,43 +4893,47 @@ msgstr "不支持的數據文件格式" msgid "Failed to open data file" msgstr "打開數據文件失敗" -#: importer/operations.py:54 +#: importer/operations.py:55 +msgid "Could not decode data file as text" +msgstr "" + +#: importer/operations.py:62 msgid "Invalid data file dimensions" msgstr "數據文件維度無效" -#: importer/serializers.py:92 +#: importer/serializers.py:102 importer/serializers.py:105 msgid "Invalid field defaults" msgstr "字段默認值無效" -#: importer/serializers.py:105 +#: importer/serializers.py:118 importer/serializers.py:121 msgid "Invalid field overrides" msgstr "無效的字段覆蓋" -#: importer/serializers.py:118 +#: importer/serializers.py:134 importer/serializers.py:137 msgid "Invalid field filters" msgstr "字段篩選器無效" -#: importer/serializers.py:177 +#: importer/serializers.py:218 msgid "Rows" msgstr "行" -#: importer/serializers.py:178 +#: importer/serializers.py:219 msgid "List of row IDs to accept" msgstr "要接受的行ID列表" -#: importer/serializers.py:191 +#: importer/serializers.py:232 msgid "No rows provided" msgstr "未提供行" -#: importer/serializers.py:195 +#: importer/serializers.py:236 msgid "Row does not belong to this session" msgstr "行不屬於此會話" -#: importer/serializers.py:198 +#: importer/serializers.py:239 msgid "Row contains invalid data" msgstr "行包含無效數據" -#: importer/serializers.py:201 +#: importer/serializers.py:242 msgid "Row has already been completed" msgstr "行已完成" @@ -4672,115 +4969,115 @@ msgstr "數據文件包含的列太多" msgid "Data file contains too many rows" msgstr "數據文件包含的行太多" -#: importer/validators.py:53 +#: importer/validators.py:53 importer/validators.py:56 msgid "Value must be a valid dictionary object" msgstr "值必須是有效的字典對象" -#: machine/machine_types/label_printer.py:212 +#: machine/machine_types/label_printer.py:216 msgid "Copies" msgstr "拷貝" -#: machine/machine_types/label_printer.py:213 +#: machine/machine_types/label_printer.py:217 msgid "Number of copies to print for each label" msgstr "每個標籤要打印的份數" -#: machine/machine_types/label_printer.py:231 +#: machine/machine_types/label_printer.py:235 msgid "Connected" msgstr "已連接" -#: machine/machine_types/label_printer.py:232 order/api.py:1848 +#: machine/machine_types/label_printer.py:236 order/api.py:2457 msgid "Unknown" msgstr "未知" -#: machine/machine_types/label_printer.py:233 +#: machine/machine_types/label_printer.py:237 msgid "Printing" msgstr "正在打印" -#: machine/machine_types/label_printer.py:234 +#: machine/machine_types/label_printer.py:238 msgid "Warning" msgstr "警告" -#: machine/machine_types/label_printer.py:235 +#: machine/machine_types/label_printer.py:239 msgid "No media" msgstr "無媒體" -#: machine/machine_types/label_printer.py:236 +#: machine/machine_types/label_printer.py:240 msgid "Paper jam" msgstr "卡紙" -#: machine/machine_types/label_printer.py:237 +#: machine/machine_types/label_printer.py:241 msgid "Disconnected" msgstr "已斷開連接" -#: machine/machine_types/label_printer.py:238 +#: machine/machine_types/label_printer.py:242 msgid "Error" msgstr "錯誤" -#: machine/machine_types/label_printer.py:245 +#: machine/machine_types/label_printer.py:249 msgid "Label Printer" msgstr "標籤打印機" -#: machine/machine_types/label_printer.py:246 +#: machine/machine_types/label_printer.py:250 msgid "Directly print labels for various items." msgstr "直接打印各種物品的標籤。" -#: machine/machine_types/label_printer.py:252 +#: machine/machine_types/label_printer.py:256 msgid "Printer Location" msgstr "打印機位置" -#: machine/machine_types/label_printer.py:253 +#: machine/machine_types/label_printer.py:257 msgid "Scope the printer to a specific location" msgstr "將打印機定位到特定位置" -#: machine/models.py:26 +#: machine/models.py:29 msgid "Name of machine" msgstr "設備名稱" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Machine Type" msgstr "設備類型" -#: machine/models.py:30 +#: machine/models.py:33 msgid "Type of machine" msgstr "設備類型" -#: machine/models.py:35 machine/models.py:147 +#: machine/models.py:38 machine/models.py:150 msgid "Driver" msgstr "驅動" -#: machine/models.py:36 +#: machine/models.py:39 msgid "Driver used for the machine" msgstr "設備使用的驅動器" -#: machine/models.py:40 +#: machine/models.py:43 msgid "Machines can be disabled" msgstr "可以禁用設備" -#: machine/models.py:96 +#: machine/models.py:99 msgid "Driver available" msgstr "可用驅動" -#: machine/models.py:101 +#: machine/models.py:104 msgid "No errors" msgstr "無錯誤" -#: machine/models.py:106 +#: machine/models.py:109 msgid "Initialized" msgstr "已初始化" -#: machine/models.py:118 +#: machine/models.py:121 msgid "Machine status" msgstr "設備狀態" -#: machine/models.py:146 +#: machine/models.py:149 msgid "Machine" msgstr "設備" -#: machine/models.py:158 +#: machine/models.py:161 msgid "Machine Config" msgstr "設備配置" -#: machine/models.py:163 +#: machine/models.py:166 msgid "Config type" msgstr "配置類型" @@ -4792,7 +5089,7 @@ msgstr "屬性鍵值" msgid "Value of the property" msgstr "屬性值" -#: machine/serializers.py:30 users/models.py:236 +#: machine/serializers.py:30 users/models.py:234 msgid "Group" msgstr "組" @@ -4816,117 +5113,118 @@ msgstr "最大進度" msgid "Maximum value for progress type, required if type=progress" msgstr "進度類型的最大值,當 type=progress 時為必填" -#: order/api.py:130 +#: order/api.py:133 msgid "Order Reference" msgstr "訂單參考" -#: order/api.py:158 order/api.py:1220 +#: order/api.py:161 order/api.py:1292 order/api.py:2091 msgid "Outstanding" msgstr "未完成" -#: order/api.py:174 +#: order/api.py:177 msgid "Has Project Code" msgstr "有項目編碼" -#: order/api.py:188 order/models.py:493 +#: order/api.py:191 order/models.py:554 msgid "Created By" msgstr "創建人" -#: order/api.py:192 +#: order/api.py:195 msgid "Created Before" msgstr "建立時間早於" -#: order/api.py:196 +#: order/api.py:199 msgid "Created After" msgstr "建立時間晚於" -#: order/api.py:200 +#: order/api.py:203 msgid "Has Start Date" msgstr "具有開始日期" -#: order/api.py:208 +#: order/api.py:211 msgid "Start Date Before" msgstr "開始日期早於" -#: order/api.py:212 +#: order/api.py:215 msgid "Start Date After" msgstr "開始日期晚於" -#: order/api.py:216 +#: order/api.py:219 msgid "Has Target Date" msgstr "具有目標日期" -#: order/api.py:224 +#: order/api.py:227 msgid "Target Date Before" msgstr "目標日期早於" -#: order/api.py:228 +#: order/api.py:231 msgid "Target Date After" msgstr "目標日期晚於" -#: order/api.py:232 +#: order/api.py:235 msgid "Updated Before" msgstr "更新之前" -#: order/api.py:236 +#: order/api.py:239 msgid "Updated After" msgstr "更新之後" -#: order/api.py:287 +#: order/api.py:292 msgid "Has Pricing" msgstr "有定價" -#: order/api.py:340 order/api.py:827 order/api.py:1529 +#: order/api.py:345 order/api.py:846 order/api.py:1612 order/api.py:1909 msgid "Completed Before" msgstr "完成時間早於" -#: order/api.py:344 order/api.py:831 order/api.py:1533 +#: order/api.py:349 order/api.py:850 order/api.py:1616 order/api.py:1913 msgid "Completed After" msgstr "完成時間晚於" -#: order/api.py:350 order/api.py:354 +#: order/api.py:355 order/api.py:359 msgid "External Build Order" msgstr "外部生產工單" -#: order/api.py:539 order/api.py:927 order/api.py:1183 order/models.py:2003 -#: order/models.py:2129 order/models.py:2181 order/models.py:2362 -#: order/models.py:2558 order/models.py:3087 order/models.py:3153 +#: order/api.py:544 order/api.py:946 order/api.py:1255 order/api.py:2054 +#: order/api.py:2213 order/models.py:2312 order/models.py:2438 +#: order/models.py:2490 order/models.py:2672 order/models.py:3061 +#: order/models.py:3579 order/models.py:3645 order/models.py:4012 msgid "Order" msgstr "訂單" -#: order/api.py:543 order/api.py:995 +#: order/api.py:548 order/api.py:1014 order/api.py:2281 msgid "Order Complete" msgstr "訂單完成" -#: order/api.py:575 order/api.py:579 order/serializers.py:754 +#: order/api.py:580 order/api.py:584 order/serializers.py:775 msgid "Internal Part" msgstr "內部零件" -#: order/api.py:597 +#: order/api.py:602 msgid "Order Pending" msgstr "訂單待定" -#: order/api.py:980 +#: order/api.py:999 order/api.py:2266 msgid "Completed" msgstr "已完成" -#: order/api.py:1236 +#: order/api.py:1308 msgid "Has Shipment" msgstr "已出貨" -#: order/api.py:1444 +#: order/api.py:1527 msgid "Shipment not found" msgstr "找不到發貨紀錄" -#: order/api.py:1842 order/models.py:577 order/models.py:2004 -#: order/models.py:2130 +#: order/api.py:2449 order/models.py:656 order/models.py:2313 +#: order/models.py:2439 #: report/templates/report/inventree_purchase_order_report.html:14 -#: stock/serializers.py:129 templates/email/overdue_purchase_order.html:15 +#: stock/serializers.py:134 templates/email/overdue_purchase_order.html:15 msgid "Purchase Order" msgstr "採購訂單" -#: order/api.py:1844 order/models.py:1292 order/models.py:2182 -#: order/models.py:2363 order/models.py:2559 +#: order/api.py:2451 order/models.py:1377 order/models.py:2491 +#: order/models.py:2673 order/models.py:3062 #: report/templates/report/inventree_build_order_report.html:135 #: report/templates/report/inventree_sales_order_report.html:14 #: report/templates/report/inventree_sales_order_shipment_report.html:15 @@ -4934,782 +5232,891 @@ msgstr "採購訂單" msgid "Sales Order" msgstr "銷售訂單" -#: order/api.py:1846 order/models.py:2730 order/models.py:3088 -#: order/models.py:3154 +#: order/api.py:2453 order/models.py:3228 order/models.py:3580 +#: order/models.py:3646 #: report/templates/report/inventree_return_order_report.html:13 #: templates/email/overdue_return_order.html:15 msgid "Return Order" msgstr "退貨訂單" -#: order/models.py:90 +#: order/api.py:2455 order/models.py:3668 order/models.py:4013 +#: report/templates/report/inventree_transfer_order_report.html:12 +msgid "Transfer Order" +msgstr "" + +#: order/models.py:109 #: report/templates/report/inventree_purchase_order_report.html:38 #: report/templates/report/inventree_sales_order_report.html:31 msgid "Total Price" msgstr "總價格" -#: order/models.py:91 +#: order/models.py:110 msgid "Total price for this order" msgstr "此訂單的總價" -#: order/models.py:96 order/serializers.py:62 +#: order/models.py:115 order/serializers.py:70 msgid "Order Currency" msgstr "訂單貨幣" -#: order/models.py:99 order/serializers.py:63 +#: order/models.py:118 order/serializers.py:71 msgid "Currency for this order (leave blank to use company default)" msgstr "此訂單的貨幣 (留空以使用公司默認值)" -#: order/models.py:326 +#: order/models.py:375 msgid "This order is locked and cannot be modified" msgstr "此訂單已鎖定,無法修改" -#: order/models.py:380 +#: order/models.py:434 msgid "Contact does not match selected company" msgstr "聯繫人與所選公司不匹配" -#: order/models.py:387 +#: order/models.py:441 msgid "Start date must be before target date" msgstr "開始日期必須早於目標日期" -#: order/models.py:394 +#: order/models.py:452 msgid "Address does not match selected company" msgstr "地址不符合選定的公司" -#: order/models.py:448 +#: order/models.py:509 msgid "Order description (optional)" msgstr "訂單描述 (可選)" -#: order/models.py:457 order/models.py:1871 +#: order/models.py:518 order/models.py:2180 msgid "Select project code for this order" msgstr "為此訂單選擇項目編碼" -#: order/models.py:463 order/models.py:1852 order/models.py:2427 +#: order/models.py:524 order/models.py:2161 order/models.py:2737 msgid "Link to external page" msgstr "鏈接到外部頁面" -#: order/models.py:470 +#: order/models.py:531 msgid "Start date" msgstr "開始日期" -#: order/models.py:471 +#: order/models.py:532 msgid "Scheduled start date for this order" msgstr "此訂單的預定開始日期" -#: order/models.py:477 order/models.py:1859 order/serializers.py:308 +#: order/models.py:538 order/models.py:2168 order/serializers.py:306 #: report/templates/report/inventree_build_order_report.html:125 msgid "Target Date" msgstr "預計日期" -#: order/models.py:479 +#: order/models.py:540 msgid "Expected date for order delivery. Order will be overdue after this date." msgstr "訂單交付的預期日期。訂單將在此日期後過期。" -#: order/models.py:499 +#: order/models.py:560 msgid "Issue Date" msgstr "簽發日期" -#: order/models.py:500 +#: order/models.py:561 msgid "Date order was issued" msgstr "訂單發出日期" -#: order/models.py:506 +#: order/models.py:567 msgid "Updated At" msgstr "更新於" -#: order/models.py:515 +#: order/models.py:576 msgid "User or group responsible for this order" msgstr "負責此訂單的用户或組" -#: order/models.py:526 +#: order/models.py:587 msgid "Point of contact for this order" msgstr "此訂單的聯繫人" -#: order/models.py:536 +#: order/models.py:597 msgid "Company address for this order" msgstr "此訂單的公司地址" -#: order/models.py:642 order/models.py:1355 +#: order/models.py:722 order/models.py:1441 msgid "Order reference" msgstr "訂單參考" -#: order/models.py:651 order/models.py:1379 order/models.py:2820 -#: stock/serializers.py:565 stock/serializers.py:1017 users/models.py:540 +#: order/models.py:731 order/models.py:1465 order/models.py:3319 +#: order/models.py:3745 stock/serializers.py:976 users/models.py:538 msgid "Status" msgstr "狀態" -#: order/models.py:652 +#: order/models.py:732 msgid "Purchase order status" msgstr "採購訂單狀態" -#: order/models.py:667 +#: order/models.py:742 msgid "Company from which the items are being ordered" msgstr "訂購物品的公司" -#: order/models.py:678 +#: order/models.py:753 msgid "Supplier Reference" msgstr "供應商參考" -#: order/models.py:679 +#: order/models.py:754 msgid "Supplier order reference code" msgstr "供應商訂單參考代碼" -#: order/models.py:688 +#: order/models.py:763 msgid "received by" msgstr "接收人" -#: order/models.py:695 order/models.py:2835 +#: order/models.py:770 order/models.py:3334 order/models.py:3786 msgid "Date order was completed" msgstr "訂單完成日期" -#: order/models.py:704 order/models.py:2062 +#: order/models.py:779 order/models.py:2371 msgid "Destination" msgstr "目的地" -#: order/models.py:705 order/models.py:2066 +#: order/models.py:780 order/models.py:2375 msgid "Destination for received items" msgstr "收到項目的存放目的地" -#: order/models.py:751 +#: order/models.py:826 msgid "Part supplier must match PO supplier" msgstr "零件供應商必須與採購訂單供應商匹配" -#: order/models.py:1021 +#: order/models.py:1086 msgid "Line item does not match purchase order" msgstr "行項目與採購訂單不匹配" -#: order/models.py:1024 +#: order/models.py:1089 msgid "Line item is missing a linked part" msgstr "行項目缺少關聯零件" -#: order/models.py:1038 +#: order/models.py:1103 msgid "Quantity must be a positive number" msgstr "數量必須是正數" -#: order/models.py:1072 +#: order/models.py:1144 msgid "Serial numbers cannot be assigned to virtual parts" msgstr "序號無法分配給虛擬零件" -#: order/models.py:1366 order/models.py:2807 stock/models.py:1109 -#: stock/models.py:1110 stock/serializers.py:1397 +#: order/models.py:1358 +msgid "Allow any stock (serialized or unserialized)" +msgstr "" + +#: order/models.py:1359 +msgid "Serialized stock only" +msgstr "" + +#: order/models.py:1360 +msgid "Unserialized stock only" +msgstr "" + +#: order/models.py:1452 order/models.py:3306 stock/models.py:1217 +#: stock/models.py:1218 stock/serializers.py:1650 #: templates/email/overdue_return_order.html:16 #: templates/email/overdue_sales_order.html:16 msgid "Customer" msgstr "客户" -#: order/models.py:1367 +#: order/models.py:1453 msgid "Company to which the items are being sold" msgstr "出售物品的公司" -#: order/models.py:1380 +#: order/models.py:1466 msgid "Sales order status" msgstr "銷售訂單狀態" -#: order/models.py:1391 order/models.py:2827 +#: order/models.py:1472 order/models.py:3326 msgid "Customer Reference " msgstr "客户參考 " -#: order/models.py:1392 order/models.py:2828 +#: order/models.py:1473 order/models.py:3327 msgid "Customer order reference code" msgstr "客户訂單參考代碼" -#: order/models.py:1396 order/models.py:2379 +#: order/models.py:1477 order/models.py:2689 msgid "Shipment Date" msgstr "發貨日期" -#: order/models.py:1405 +#: order/models.py:1486 msgid "shipped by" msgstr "發貨人" -#: order/models.py:1456 +#: order/models.py:1660 order/serializers.py:1724 order/serializers.py:1879 +#: order/serializers.py:2762 order/serializers.py:2969 +msgid "Line item is not associated with this order" +msgstr "行項目與此訂單不關聯" + +#: order/models.py:1717 order/serializers.py:3063 +msgid "No match found for the following serial numbers" +msgstr "未找到以下序列號的匹配項" + +#: order/models.py:1724 order/serializers.py:3070 +msgid "The following serial numbers are unavailable" +msgstr "以下序列號不可用" + +#: order/models.py:1764 order/models.py:3830 msgid "Order is already complete" msgstr "訂單已完成" -#: order/models.py:1459 +#: order/models.py:1767 order/models.py:3833 msgid "Order is already cancelled" msgstr "訂單已取消" -#: order/models.py:1463 +#: order/models.py:1771 msgid "Only an open order can be marked as complete" msgstr "只有未結訂單才能標記為已完成" -#: order/models.py:1467 +#: order/models.py:1775 msgid "Order cannot be completed as there are incomplete shipments" msgstr "由於發貨不完整,訂單無法完成" -#: order/models.py:1472 +#: order/models.py:1780 msgid "Order cannot be completed as there are incomplete allocations" msgstr "訂單無法完成,因為仍有未完成的分配" -#: order/models.py:1481 +#: order/models.py:1789 msgid "Order cannot be completed as there are incomplete line items" msgstr "訂單無法完成,因為行項目不完整" -#: order/models.py:1778 order/models.py:1803 +#: order/models.py:2078 order/models.py:2103 msgid "The order is locked and cannot be modified" msgstr "此訂單已鎖定,無法修改" -#: order/models.py:1811 +#: order/models.py:2111 msgid "Item quantity" msgstr "項目數量" -#: order/models.py:1829 +#: order/models.py:2119 +msgid "Discount" +msgstr "" + +#: order/models.py:2120 +msgid "Discount percentage applied to this line item (0-100)" +msgstr "" + +#: order/models.py:2138 msgid "Line Number" msgstr "行號" -#: order/models.py:1830 +#: order/models.py:2139 msgid "Line number for this item (optional)" msgstr "此項目的行號 (選填)" -#: order/models.py:1839 +#: order/models.py:2148 msgid "Line item reference" msgstr "行項目參考" -#: order/models.py:1846 +#: order/models.py:2155 msgid "Line item notes" msgstr "行項目註釋" -#: order/models.py:1861 +#: order/models.py:2170 msgid "Target date for this line item (leave blank to use the target date from the order)" msgstr "此行項目的目標日期 (留空以使用訂單中的目標日期)" -#: order/models.py:1891 +#: order/models.py:2200 msgid "Line item description (optional)" msgstr "行項目描述 (可選)" -#: order/models.py:1898 +#: order/models.py:2207 msgid "Additional context for this line" msgstr "此行的附加上下文" -#: order/models.py:1908 +#: order/models.py:2217 msgid "Unit price" msgstr "單位價格" -#: order/models.py:1927 +#: order/models.py:2236 msgid "Purchase Order Line Item" msgstr "採購訂單行項目" -#: order/models.py:1956 +#: order/models.py:2265 msgid "Supplier part must match supplier" msgstr "供應商零件必須與供應商匹配" -#: order/models.py:1964 +#: order/models.py:2273 msgid "Build order must be marked as external" msgstr "生產工單必須標記為外部" -#: order/models.py:1971 +#: order/models.py:2280 msgid "Build orders can only be linked to assembly parts" msgstr "生產工單只能連結到組裝零件" -#: order/models.py:1977 +#: order/models.py:2286 msgid "Build order part must match line item part" msgstr "生產工單的零件必須與行項目的零件一致" -#: order/models.py:1987 +#: order/models.py:2296 msgid "An external build order is required for assembly parts" msgstr "" -#: order/models.py:2023 +#: order/models.py:2332 msgid "Supplier part" msgstr "供應商零件" -#: order/models.py:2030 +#: order/models.py:2339 msgid "Received" msgstr "已接收" -#: order/models.py:2031 +#: order/models.py:2340 msgid "Number of items received" msgstr "收到的物品數量" -#: order/models.py:2039 stock/models.py:1232 stock/serializers.py:666 +#: order/models.py:2348 stock/models.py:1347 stock/serializers.py:673 +#: stock/serializers.py:1048 msgid "Purchase Price" msgstr "採購價格" -#: order/models.py:2040 +#: order/models.py:2349 msgid "Unit purchase price" msgstr "每單位的採購價格" -#: order/models.py:2056 +#: order/models.py:2365 msgid "External Build Order to be fulfilled by this line item" msgstr "由此行項目履行的外部生產工單" -#: order/models.py:2118 +#: order/models.py:2427 msgid "Purchase Order Extra Line" msgstr "採購訂單附加行" -#: order/models.py:2147 +#: order/models.py:2456 msgid "Sales Order Line Item" msgstr "銷售訂單行項目" -#: order/models.py:2174 +#: order/models.py:2483 msgid "Only salable parts can be assigned to a sales order" msgstr "只有可銷售的零件才能分配給銷售訂單" -#: order/models.py:2200 +#: order/models.py:2509 msgid "Sale Price" msgstr "售出價格" -#: order/models.py:2201 +#: order/models.py:2510 msgid "Unit sale price" msgstr "單位售出價格" -#: order/models.py:2210 order/status_codes.py:50 +#: order/models.py:2519 order/status_codes.py:50 msgid "Shipped" msgstr "已配送" -#: order/models.py:2211 +#: order/models.py:2520 msgid "Shipped quantity" msgstr "發貨數量" -#: order/models.py:2323 +#: order/models.py:2633 msgid "Sales Order Shipment" msgstr "銷售訂單發貨" -#: order/models.py:2336 +#: order/models.py:2646 msgid "Shipment address must match the customer" msgstr "配送地址必須跟客戶相符" -#: order/models.py:2372 +#: order/models.py:2682 msgid "Shipping address for this shipment" msgstr "配送的採購地址" -#: order/models.py:2380 +#: order/models.py:2690 msgid "Date of shipment" msgstr "發貨日期" -#: order/models.py:2386 +#: order/models.py:2696 msgid "Delivery Date" msgstr "送達日期" -#: order/models.py:2387 +#: order/models.py:2697 msgid "Date of delivery of shipment" msgstr "裝運交貨日期" -#: order/models.py:2395 +#: order/models.py:2705 msgid "Checked By" msgstr "審核人" -#: order/models.py:2396 +#: order/models.py:2706 msgid "User who checked this shipment" msgstr "檢查此裝運的用户" -#: order/models.py:2403 order/models.py:2655 order/serializers.py:1808 -#: order/serializers.py:1942 +#: order/models.py:2713 order/models.py:3162 order/serializers.py:1899 +#: order/serializers.py:1952 order/serializers.py:2053 #: report/templates/report/inventree_sales_order_shipment_report.html:14 msgid "Shipment" msgstr "配送" -#: order/models.py:2404 +#: order/models.py:2714 msgid "Shipment number" msgstr "配送單號" -#: order/models.py:2412 +#: order/models.py:2722 msgid "Tracking Number" msgstr "跟蹤單號" -#: order/models.py:2413 +#: order/models.py:2723 msgid "Shipment tracking information" msgstr "配送跟蹤信息" -#: order/models.py:2420 +#: order/models.py:2730 msgid "Invoice Number" msgstr "發票編號" -#: order/models.py:2421 +#: order/models.py:2731 msgid "Reference number for associated invoice" msgstr "相關發票的參考號" -#: order/models.py:2467 +#: order/models.py:2777 msgid "Shipment has already been sent" msgstr "貨物已發出" -#: order/models.py:2470 +#: order/models.py:2780 msgid "Shipment has no allocated stock items" msgstr "發貨沒有分配庫存項目" -#: order/models.py:2477 +#: order/models.py:2787 msgid "Shipment must be checked before it can be completed" msgstr "發貨紀錄必須在完成前進行檢查" -#: order/models.py:2547 +#: order/models.py:3050 msgid "Sales Order Extra Line" msgstr "銷售訂單加行" -#: order/models.py:2576 +#: order/models.py:3079 msgid "Sales Order Allocation" msgstr "銷售訂單分配" -#: order/models.py:2599 order/models.py:2601 +#: order/models.py:3102 order/models.py:3104 order/models.py:4105 +#: order/models.py:4107 msgid "Stock item has not been assigned" msgstr "庫存項目尚未分配" -#: order/models.py:2608 +#: order/models.py:3111 order/models.py:4114 msgid "Cannot allocate stock item to a line with a different part" msgstr "無法將庫存項目分配給具有不同零件的行" -#: order/models.py:2611 +#: order/models.py:3114 order/models.py:4117 msgid "Cannot allocate stock to a line without a part" msgstr "無法將庫存分配給沒有零件的生產線" -#: order/models.py:2614 +#: order/models.py:3117 order/models.py:4120 msgid "Allocation quantity cannot exceed stock quantity" msgstr "分配數量不能超過庫存數量" -#: order/models.py:2630 +#: order/models.py:3137 order/models.py:4142 msgid "Allocation quantity must be greater than zero" msgstr "分配的數量必須大於零" -#: order/models.py:2633 order/serializers.py:1678 +#: order/models.py:3140 order/models.py:4145 order/serializers.py:1769 +#: order/serializers.py:2798 msgid "Quantity must be 1 for serialized stock item" msgstr "序列化庫存項目的數量必須為1" -#: order/models.py:2636 +#: order/models.py:3143 msgid "Sales order does not match shipment" msgstr "銷售訂單與發貨不匹配" -#: order/models.py:2637 plugin/base/barcodes/api.py:643 +#: order/models.py:3144 plugin/base/barcodes/api.py:721 msgid "Shipment does not match sales order" msgstr "發貨與銷售訂單不匹配" -#: order/models.py:2645 +#: order/models.py:3152 order/models.py:4153 msgid "Line" msgstr "行" -#: order/models.py:2656 +#: order/models.py:3163 msgid "Sales order shipment reference" msgstr "銷售訂單發貨參考" -#: order/models.py:2669 order/models.py:3095 +#: order/models.py:3176 order/models.py:3587 order/models.py:4166 msgid "Item" msgstr "項目" -#: order/models.py:2670 +#: order/models.py:3177 order/models.py:4167 msgid "Select stock item to allocate" msgstr "選擇要分配的庫存項目" -#: order/models.py:2679 +#: order/models.py:3186 order/models.py:4176 msgid "Enter stock allocation quantity" msgstr "輸入庫存分配數量" -#: order/models.py:2796 +#: order/models.py:3295 msgid "Return Order reference" msgstr "退貨訂單參考" -#: order/models.py:2808 +#: order/models.py:3307 msgid "Company from which items are being returned" msgstr "退回物品的公司" -#: order/models.py:2821 +#: order/models.py:3320 msgid "Return order status" msgstr "退貨訂單狀態" -#: order/models.py:3053 +#: order/models.py:3545 msgid "Return Order Line Item" msgstr "退貨訂單行項目" -#: order/models.py:3066 +#: order/models.py:3558 msgid "Stock item must be specified" msgstr "必須指定庫存項目" -#: order/models.py:3070 +#: order/models.py:3562 msgid "Return quantity exceeds stock quantity" msgstr "退回數量超過庫存數量" -#: order/models.py:3075 +#: order/models.py:3567 msgid "Return quantity must be greater than zero" msgstr "退回數量必須大於零" -#: order/models.py:3080 +#: order/models.py:3572 msgid "Invalid quantity for serialized stock item" msgstr "序列化庫存項目的數量無效" -#: order/models.py:3096 +#: order/models.py:3588 msgid "Select item to return from customer" msgstr "選擇要從客户處退回的商品" -#: order/models.py:3111 +#: order/models.py:3603 msgid "Received Date" msgstr "接收日期" -#: order/models.py:3112 +#: order/models.py:3604 msgid "The date this return item was received" msgstr "收到此退貨項目的日期" -#: order/models.py:3124 +#: order/models.py:3616 msgid "Outcome" msgstr "結果" -#: order/models.py:3125 +#: order/models.py:3617 msgid "Outcome for this line item" msgstr "該行項目的結果" -#: order/models.py:3132 +#: order/models.py:3624 msgid "Cost associated with return or repair for this line item" msgstr "與此行項目的退貨或維修相關的成本" -#: order/models.py:3142 +#: order/models.py:3634 msgid "Return Order Extra Line" msgstr "退貨訂單附加行" -#: order/serializers.py:76 -msgid "Order ID" -msgstr "訂單ID" +#: order/models.py:3735 +msgid "Transfer Order Reference" +msgstr "" -#: order/serializers.py:76 -msgid "ID of the order to duplicate" -msgstr "要複製的訂單ID" +#: order/models.py:3746 +msgid "Transfer order status" +msgstr "" -#: order/serializers.py:82 -msgid "Copy Lines" -msgstr "複製行" +#: order/models.py:3761 +msgid "Source for transferred items" +msgstr "" -#: order/serializers.py:83 -msgid "Copy line items from the original order" -msgstr "從原始訂單複製行項目" +#: order/models.py:3771 +msgid "Destination for transferred items" +msgstr "" -#: order/serializers.py:89 -msgid "Copy Extra Lines" -msgstr "複製額外行" +#: order/models.py:3776 +msgid "Consume Stock" +msgstr "" -#: order/serializers.py:90 -msgid "Copy extra line items from the original order" -msgstr "從原始訂單複製額外的行項目" +#: order/models.py:3778 +msgid "Rather than transfer the stock to the destination, \"consume\" it, by removing transferred quantity from the allocated stock item" +msgstr "" -#: order/serializers.py:96 part/serializers.py:414 -msgid "Copy Parameters" -msgstr "複製參數" +#: order/models.py:3837 +msgid "Order cannot be completed until a destination location is set" +msgstr "" -#: order/serializers.py:97 -msgid "Copy order parameters from the original order" -msgstr "從原始訂單複製訂單參數" +#: order/models.py:3842 +msgid "Order cannot be completed until it is fully allocated" +msgstr "" -#: order/serializers.py:112 +#: order/models.py:3994 +msgid "Transfer Order Line Item" +msgstr "" + +#: order/models.py:4027 +msgid "transferred" +msgstr "" + +#: order/models.py:4028 +msgid "transferred quantity" +msgstr "" + +#: order/models.py:4082 +msgid "Transfer Order Allocation" +msgstr "" + +#: order/models.py:4235 +msgid "Failed to consume stock item against transfer order" +msgstr "" + +#: order/models.py:4247 order/models.py:4259 +msgid "Failed to transfer stock item against transfer order" +msgstr "" + +#: order/serializers.py:90 order/serializers.py:2086 #: report/templates/report/inventree_purchase_order_report.html:29 #: report/templates/report/inventree_return_order_report.html:19 #: report/templates/report/inventree_sales_order_report.html:22 +#: report/templates/report/inventree_transfer_order_report.html:20 msgid "Line Items" msgstr "行項目" -#: order/serializers.py:117 +#: order/serializers.py:95 msgid "Completed Lines" msgstr "已完成行項目" -#: order/serializers.py:185 -msgid "Duplicate Order" -msgstr "複製訂單" +#: order/serializers.py:103 +msgid "Custom Status Key" +msgstr "" -#: order/serializers.py:186 -msgid "Specify options for duplicating this order" -msgstr "指定複製此訂單的選項" +#: order/serializers.py:104 +msgid "Update order status to a custom value for this logical value" +msgstr "" -#: order/serializers.py:265 -msgid "Invalid order ID" -msgstr "訂單ID不正確" +#: order/serializers.py:188 +msgid "Custom status key must be an integer" +msgstr "" -#: order/serializers.py:445 +#: order/serializers.py:195 +msgid "Invalid custom status key" +msgstr "" + +#: order/serializers.py:198 +msgid "Invalid custom status key for this order status" +msgstr "" + +#: order/serializers.py:462 msgid "Supplier Name" msgstr "供應商名稱" -#: order/serializers.py:494 +#: order/serializers.py:511 order/serializers.py:2547 msgid "Order cannot be cancelled" msgstr "訂單不能取消" -#: order/serializers.py:509 order/serializers.py:1699 +#: order/serializers.py:526 order/serializers.py:1790 msgid "Allow order to be closed with incomplete line items" msgstr "允許關閉行項目不完整的訂單" -#: order/serializers.py:519 order/serializers.py:1709 +#: order/serializers.py:536 order/serializers.py:1800 msgid "Order has incomplete line items" msgstr "訂單中的行項目不完整" -#: order/serializers.py:639 +#: order/serializers.py:650 msgid "Order is not open" msgstr "訂單未打開" -#: order/serializers.py:677 +#: order/serializers.py:690 msgid "Auto Pricing" msgstr "自動定價" -#: order/serializers.py:679 +#: order/serializers.py:692 msgid "Automatically calculate purchase price based on supplier part data" msgstr "根據供應商零件數據自動計算採購價格" -#: order/serializers.py:696 +#: order/serializers.py:709 stock/serializers.py:1058 msgid "Purchase price currency" msgstr "購買價格貨幣" -#: order/serializers.py:727 +#: order/serializers.py:740 msgid "Merge Items" msgstr "合併項目" -#: order/serializers.py:729 +#: order/serializers.py:742 msgid "Merge items with the same part, destination and target date into one line item" msgstr "將具有相同零件、目的地和目標日期的項目合併到一個行項目中" -#: order/serializers.py:736 part/serializers.py:483 +#: order/serializers.py:757 part/serializers.py:462 msgid "SKU" msgstr "庫存量單位" -#: order/serializers.py:750 part/models.py:1152 part/serializers.py:342 +#: order/serializers.py:771 part/models.py:1169 part/serializers.py:382 msgid "Internal Part Number" msgstr "內部零件編號" -#: order/serializers.py:758 +#: order/serializers.py:779 msgid "Internal Part Name" msgstr "內部零件名稱" -#: order/serializers.py:774 +#: order/serializers.py:795 msgid "Supplier part must be specified" msgstr "必須指定供應商零件" -#: order/serializers.py:777 +#: order/serializers.py:798 msgid "Purchase order must be specified" msgstr "必須指定採購訂單" -#: order/serializers.py:785 +#: order/serializers.py:806 msgid "Supplier must match purchase order" msgstr "供應商必須匹配採購訂單" -#: order/serializers.py:786 +#: order/serializers.py:807 msgid "Purchase order must match supplier" msgstr "採購訂單必須與供應商匹配" -#: order/serializers.py:838 order/serializers.py:1779 +#: order/serializers.py:859 order/serializers.py:1870 order/serializers.py:2960 msgid "Line Item" msgstr "行項目" -#: order/serializers.py:847 order/serializers.py:987 order/serializers.py:2160 +#: order/serializers.py:868 order/serializers.py:1008 order/serializers.py:2295 msgid "Select destination location for received items" msgstr "為收到的物品選擇目的地位置" -#: order/serializers.py:863 +#: order/serializers.py:884 msgid "Enter batch code for incoming stock items" msgstr "輸入入庫項目的批號" -#: order/serializers.py:870 stock/models.py:1191 -#: templates/email/stale_stock_notification.html:22 users/models.py:137 +#: order/serializers.py:891 stock/models.py:1299 +#: templates/email/stale_stock_notification.html:22 users/models.py:135 msgid "Expiry Date" msgstr "有效期至" -#: order/serializers.py:871 +#: order/serializers.py:892 msgid "Enter expiry date for incoming stock items" msgstr "輸入入庫庫存項目的到期日" -#: order/serializers.py:879 +#: order/serializers.py:900 msgid "Enter serial numbers for incoming stock items" msgstr "輸入入庫庫存項目的序列號" -#: order/serializers.py:889 +#: order/serializers.py:910 msgid "Override packaging information for incoming stock items" msgstr "覆蓋傳入庫存項目的包裝資料" -#: order/serializers.py:897 order/serializers.py:2165 +#: order/serializers.py:918 order/serializers.py:2300 msgid "Additional note for incoming stock items" msgstr "傳入庫存項目的附加説明" -#: order/serializers.py:904 +#: order/serializers.py:925 msgid "Barcode" msgstr "條形碼" -#: order/serializers.py:905 +#: order/serializers.py:926 msgid "Scanned barcode" msgstr "掃描條形碼" -#: order/serializers.py:921 +#: order/serializers.py:942 msgid "Barcode is already in use" msgstr "條形碼已被使用" -#: order/serializers.py:1004 order/serializers.py:2184 +#: order/serializers.py:1025 order/serializers.py:2319 +#: stock/serializers.py:1138 msgid "Line items must be provided" msgstr "必須提供行項目" -#: order/serializers.py:1023 +#: order/serializers.py:1051 msgid "Destination location must be specified" msgstr "必須指定目標位置" -#: order/serializers.py:1030 +#: order/serializers.py:1058 msgid "Supplied barcode values must be unique" msgstr "提供的條形碼值必須是唯一的" -#: order/serializers.py:1155 +#: order/serializers.py:1075 +msgid "Supplied serial numbers must be unique" +msgstr "" + +#: order/serializers.py:1217 msgid "Shipments" msgstr "配送紀錄" -#: order/serializers.py:1159 +#: order/serializers.py:1221 msgid "Completed Shipments" msgstr "完成配送" -#: order/serializers.py:1163 +#: order/serializers.py:1225 msgid "Allocated Lines" msgstr "已分配行" -#: order/serializers.py:1356 +#: order/serializers.py:1421 msgid "Sale price currency" msgstr "售出價格貨幣" -#: order/serializers.py:1403 +#: order/serializers.py:1473 msgid "Allocated Items" msgstr "已分配項目" -#: order/serializers.py:1601 +#: order/serializers.py:1692 msgid "No shipment details provided" msgstr "未提供裝運詳細信息" -#: order/serializers.py:1633 order/serializers.py:1788 -msgid "Line item is not associated with this order" -msgstr "行項目與此訂單不關聯" - -#: order/serializers.py:1652 +#: order/serializers.py:1743 order/serializers.py:2781 msgid "Quantity must be positive" msgstr "數量必須為正" -#: order/serializers.py:1673 +#: order/serializers.py:1764 msgid "Stock item has not passed all required tests" msgstr "" -#: order/serializers.py:1798 +#: order/serializers.py:1889 order/serializers.py:2979 msgid "Enter serial numbers to allocate" msgstr "輸入要分配的序列號" -#: order/serializers.py:1820 order/serializers.py:1950 +#: order/serializers.py:1911 order/serializers.py:1960 +#: order/serializers.py:2100 msgid "Shipment has already been shipped" msgstr "貨物已發出" -#: order/serializers.py:1823 order/serializers.py:1953 +#: order/serializers.py:1914 order/serializers.py:1963 +#: order/serializers.py:2103 msgid "Shipment is not associated with this order" msgstr "發貨與此訂單無關" -#: order/serializers.py:1886 -msgid "No match found for the following serial numbers" -msgstr "未找到以下序列號的匹配項" +#: order/serializers.py:2035 +msgid "Stock location where items are sourced (leave blank to use any location)" +msgstr "" -#: order/serializers.py:1893 -msgid "The following serial numbers are unavailable" -msgstr "以下序列號不可用" +#: order/serializers.py:2045 +msgid "Exclude stock items from this location" +msgstr "" -#: order/serializers.py:2126 +#: order/serializers.py:2054 +msgid "Assign allocations to this shipment" +msgstr "" + +#: order/serializers.py:2061 +msgid "Allow stock to be taken from multiple locations to fulfil a single line item" +msgstr "" + +#: order/serializers.py:2075 +msgid "Serialized Stock" +msgstr "" + +#: order/serializers.py:2077 +msgid "Control whether serialized stock items are included in auto-allocation" +msgstr "" + +#: order/serializers.py:2088 +msgid "Limit allocation to these line items (leave blank to allocate all lines)" +msgstr "" + +#: order/serializers.py:2114 +msgid "Line item does not belong to this order" +msgstr "" + +#: order/serializers.py:2261 msgid "Return order line item" msgstr "退貨訂單行項目" -#: order/serializers.py:2136 +#: order/serializers.py:2271 msgid "Line item does not match return order" msgstr "行項目與退貨訂單不匹配" -#: order/serializers.py:2139 +#: order/serializers.py:2274 msgid "Line item has already been received" msgstr "行項目已收到" -#: order/serializers.py:2176 +#: order/serializers.py:2311 msgid "Items can only be received against orders which are in progress" msgstr "只能根據正在進行的訂單接收物品" -#: order/serializers.py:2252 +#: order/serializers.py:2388 msgid "Quantity to return" msgstr "退回數量" -#: order/serializers.py:2277 +#: order/serializers.py:2413 msgid "Line price currency" msgstr "行價格貨幣" +#: order/serializers.py:2562 +msgid "Allow order to complete with incomplete allocations" +msgstr "" + +#: order/serializers.py:2572 +msgid "Order has incomplete allocations" +msgstr "" + #: order/status_codes.py:17 order/status_codes.py:54 stock/status_codes.py:16 msgid "Lost" msgstr "丟失" @@ -5718,1279 +6125,1312 @@ msgstr "丟失" msgid "Returned" msgstr "已退回" -#: order/status_codes.py:47 order/status_codes.py:79 +#: order/status_codes.py:47 order/status_codes.py:80 msgid "In Progress" msgstr "正在進行" -#: order/status_codes.py:105 +#: order/status_codes.py:106 msgid "Return" msgstr "退回" -#: order/status_codes.py:108 +#: order/status_codes.py:109 msgid "Repair" msgstr "維修" -#: order/status_codes.py:111 +#: order/status_codes.py:112 msgid "Replace" msgstr "替換" -#: order/status_codes.py:114 +#: order/status_codes.py:115 msgid "Refund" msgstr "退款" -#: order/status_codes.py:117 +#: order/status_codes.py:118 msgid "Reject" msgstr "拒絕" -#: order/tasks.py:48 +#: order/status_codes.py:126 +#: report/templates/report/inventree_build_order_report.html:121 +msgid "Issued" +msgstr "已派發" + +#: order/tasks.py:49 msgid "Overdue Purchase Order" msgstr "逾期採購訂單" -#: order/tasks.py:53 +#: order/tasks.py:54 #, python-brace-format msgid "Purchase order {po} is now overdue" msgstr "採購訂單 {po} 已逾期" -#: order/tasks.py:118 +#: order/tasks.py:119 msgid "Overdue Sales Order" msgstr "逾期銷售訂單" -#: order/tasks.py:123 +#: order/tasks.py:124 #, python-brace-format msgid "Sales order {so} is now overdue" msgstr "銷售訂單 {so} 已逾期" -#: order/tasks.py:185 +#: order/tasks.py:186 msgid "Overdue Return Order" msgstr "逾期退貨訂單" -#: order/tasks.py:190 +#: order/tasks.py:191 #, python-brace-format msgid "Return order {ro} is now overdue" msgstr "退貨訂單 {ro} 已逾期" -#: part/api.py:88 +#: part/api.py:90 msgid "Starred" msgstr "已加星標" -#: part/api.py:90 +#: part/api.py:92 msgid "Filter by starred categories" msgstr "按星標類別篩選" -#: part/api.py:107 stock/api.py:287 +#: part/api.py:109 stock/api.py:327 msgid "Depth" msgstr "深度" -#: part/api.py:107 +#: part/api.py:109 msgid "Filter by category depth" msgstr "按類別深度篩選" -#: part/api.py:125 stock/api.py:305 +#: part/api.py:127 stock/api.py:345 msgid "Top Level" msgstr "頂級" -#: part/api.py:127 +#: part/api.py:129 msgid "Filter by top-level categories" msgstr "按頂級類別篩選" -#: part/api.py:140 stock/api.py:320 +#: part/api.py:142 stock/api.py:360 msgid "Cascade" msgstr "級聯" -#: part/api.py:142 +#: part/api.py:144 msgid "Include sub-categories in filtered results" msgstr "在篩選結果中包含子類別" -#: part/api.py:162 +#: part/api.py:164 msgid "Parent" msgstr "父類" -#: part/api.py:164 +#: part/api.py:166 msgid "Filter by parent category" msgstr "按父類別篩選" -#: part/api.py:199 +#: part/api.py:201 msgid "Exclude sub-categories under the specified category" msgstr "排除指定類別下的子類別" -#: part/api.py:424 +#: part/api.py:298 stock/api.py:507 +msgid "Max Level" +msgstr "" + +#: part/api.py:300 stock/api.py:509 +msgid "Limit the depth of the category tree" +msgstr "" + +#: part/api.py:442 msgid "Has Results" msgstr "有結果" -#: part/api.py:654 +#: part/api.py:672 msgid "Is Variant" msgstr "為變體" -#: part/api.py:662 +#: part/api.py:680 msgid "Is Revision" msgstr "是修訂版本" -#: part/api.py:672 +#: part/api.py:690 msgid "Has Revisions" msgstr "有修訂版本" -#: part/api.py:870 +#: part/api.py:897 msgid "BOM Valid" msgstr "物料清單合規" -#: part/api.py:979 +#: part/api.py:1006 msgid "Cascade Categories" msgstr "級聯類別" -#: part/api.py:980 +#: part/api.py:1007 msgid "If true, include items in child categories of the given category" msgstr "若為 true,則包含給定類別的子類別中的項目" -#: part/api.py:986 +#: part/api.py:1013 msgid "Filter by numeric category ID or the literal 'null'" msgstr "依數字類別 ID 或常值 'null' 篩選" -#: part/api.py:1299 +#: part/api.py:1327 msgid "Assembly part is active" msgstr "組件零件處於作用中狀態" -#: part/api.py:1303 +#: part/api.py:1331 msgid "Assembly part is trackable" msgstr "組件零件可追蹤" -#: part/api.py:1307 +#: part/api.py:1335 msgid "Assembly part is testable" msgstr "裝配部份是可測試的" -#: part/api.py:1311 +#: part/api.py:1339 msgid "Assembly part is locked" msgstr "" -#: part/api.py:1316 +#: part/api.py:1344 msgid "Component part is active" msgstr "子零件處於作用中狀態" -#: part/api.py:1320 +#: part/api.py:1348 msgid "Component part is trackable" msgstr "子零件可追蹤" -#: part/api.py:1324 +#: part/api.py:1352 msgid "Component part is testable" msgstr "組件部份是可測試的" -#: part/api.py:1328 +#: part/api.py:1356 msgid "Component part is an assembly" msgstr "子零件是一個組件" -#: part/api.py:1332 +#: part/api.py:1360 msgid "Component part is virtual" msgstr "子零件是虛擬的" -#: part/api.py:1336 +#: part/api.py:1364 msgid "Has available stock" msgstr "有可用庫存" -#: part/api.py:1393 +#: part/api.py:1421 msgid "Uses" msgstr "使用" -#: part/models.py:92 part/models.py:413 +#: part/models.py:94 part/models.py:415 #: templates/email/part_event_notification.html:16 msgid "Part Category" msgstr "零件類別" -#: part/models.py:93 users/ruleset.py:28 +#: part/models.py:95 users/ruleset.py:29 msgid "Part Categories" msgstr "零件類別" -#: part/models.py:111 part/models.py:1188 +#: part/models.py:113 part/models.py:1205 msgid "Default Location" msgstr "默認位置" -#: part/models.py:112 +#: part/models.py:114 msgid "Default location for parts in this category" msgstr "此類別零件的默認庫存地點" -#: part/models.py:117 stock/models.py:204 +#: part/models.py:119 stock/models.py:206 msgid "Structural" msgstr "結構性" -#: part/models.py:119 +#: part/models.py:121 msgid "Parts may not be directly assigned to a structural category, but may be assigned to child categories." msgstr "零件可能無法直接分配到結構類別,但可以分配到子類別。" -#: part/models.py:128 +#: part/models.py:130 msgid "Default keywords" msgstr "默認關鍵字" -#: part/models.py:129 +#: part/models.py:131 msgid "Default keywords for parts in this category" msgstr "此類別零件的默認關鍵字" -#: part/models.py:136 stock/models.py:99 stock/models.py:186 +#: part/models.py:138 stock/models.py:102 stock/models.py:188 msgid "Icon" msgstr "圖標" -#: part/models.py:137 part/serializers.py:152 part/serializers.py:171 -#: stock/models.py:187 +#: part/models.py:139 part/serializers.py:175 part/serializers.py:207 +#: stock/models.py:189 msgid "Icon (optional)" msgstr "圖標(可選)" -#: part/models.py:181 +#: part/models.py:183 msgid "You cannot make this part category structural because some parts are already assigned to it!" msgstr "您不能使這個零件類別結構化,因為有些零件已經分配給了它!" -#: part/models.py:369 +#: part/models.py:371 msgid "Part Category Parameter Template" msgstr "零件類別參數模板" -#: part/models.py:425 +#: part/models.py:427 msgid "Default Value" msgstr "默認值" -#: part/models.py:426 +#: part/models.py:428 msgid "Default Parameter Value" msgstr "默認參數值" -#: part/models.py:529 part/serializers.py:112 users/ruleset.py:29 +#: part/models.py:531 part/serializers.py:135 users/ruleset.py:30 msgid "Parts" msgstr "零件" -#: part/models.py:575 +#: part/models.py:577 msgid "Cannot delete parameters of a locked part" msgstr "無法刪除已鎖定零件的參數" -#: part/models.py:580 +#: part/models.py:582 msgid "Cannot modify parameters of a locked part" msgstr "無法修改已鎖定零件的參數" -#: part/models.py:591 +#: part/models.py:593 msgid "Cannot delete this part as it is locked" msgstr "無法刪除這個零件,因為它已被鎖定" -#: part/models.py:594 +#: part/models.py:596 msgid "Cannot delete this part as it is still active" msgstr "無法刪除這個零件,因為它仍然處於活動狀態" -#: part/models.py:599 +#: part/models.py:601 msgid "Cannot delete this part as it is used in an assembly" msgstr "無法刪除這個零件,因為它被使用在了裝配中" -#: part/models.py:683 part/models.py:690 +#: part/models.py:685 part/models.py:692 #, python-brace-format msgid "Part '{self}' cannot be used in BOM for '{parent}' (recursive)" msgstr "零件 \"{self}\" 不能用在 \"{parent}\" 的物料清單 (遞歸)" -#: part/models.py:702 +#: part/models.py:704 #, python-brace-format msgid "Part '{parent}' is used in BOM for '{self}' (recursive)" msgstr "零件 \"{parent}\" 被使用在了 \"{self}\" 的物料清單 (遞歸)" -#: part/models.py:769 +#: part/models.py:775 #, python-brace-format msgid "IPN must match regex pattern {pattern}" msgstr "內部零件號必須匹配正則表達式 {pattern}" -#: part/models.py:777 +#: part/models.py:783 msgid "Part cannot be a revision of itself" msgstr "零件不能是對自身的修訂" -#: part/models.py:784 +#: part/models.py:790 msgid "Revision code must be specified for a part marked as a revision" msgstr "標記為修訂版的零件必須指定修訂版代碼" -#: part/models.py:792 +#: part/models.py:798 msgid "Revisions are only allowed for assembly parts" msgstr "修訂僅對裝配零件允許" -#: part/models.py:799 +#: part/models.py:805 msgid "Cannot make a revision of a template part" msgstr "無法對模版零件進行修訂" -#: part/models.py:805 +#: part/models.py:811 msgid "Parent part must point to the same template" msgstr "上級零件必須指向相同的模版" -#: part/models.py:902 +#: part/models.py:909 msgid "Stock item with this serial number already exists" msgstr "該序列號庫存項己存在" -#: part/models.py:1032 +#: part/models.py:1040 msgid "Duplicate IPN not allowed in part settings" msgstr "在零件設置中不允許重複的內部零件號" -#: part/models.py:1045 +#: part/models.py:1053 msgid "Duplicate part revision already exists." msgstr "重複的零件修訂版本已經存在。" -#: part/models.py:1055 +#: part/models.py:1072 msgid "Part with this Name, IPN and Revision already exists." msgstr "有這個名字,內部零件號,和修訂版本的零件已經存在" -#: part/models.py:1070 +#: part/models.py:1087 msgid "Parts cannot be assigned to structural part categories!" msgstr "零件不能分配到結構性零件類別!" -#: part/models.py:1102 +#: part/models.py:1119 msgid "Part name" msgstr "零件名稱" -#: part/models.py:1107 +#: part/models.py:1124 msgid "Is Template" msgstr "是模板" -#: part/models.py:1108 +#: part/models.py:1125 msgid "Is this part a template part?" msgstr "這個零件是一個模版零件嗎?" -#: part/models.py:1118 +#: part/models.py:1135 msgid "Is this part a variant of another part?" msgstr "這個零件是另一零件的變體嗎?" -#: part/models.py:1119 +#: part/models.py:1136 msgid "Variant Of" msgstr "變體" -#: part/models.py:1126 +#: part/models.py:1143 msgid "Part description (optional)" msgstr "零件描述(可選)" -#: part/models.py:1133 +#: part/models.py:1150 msgid "Keywords" msgstr "關鍵詞" -#: part/models.py:1134 +#: part/models.py:1151 msgid "Part keywords to improve visibility in search results" msgstr "提高搜索結果可見性的零件關鍵字" -#: part/models.py:1144 +#: part/models.py:1161 msgid "Part category" msgstr "零件類別" -#: part/models.py:1151 part/serializers.py:828 +#: part/models.py:1168 part/serializers.py:814 #: report/templates/report/inventree_stock_location_report.html:103 msgid "IPN" msgstr "內部零件號 IPN" -#: part/models.py:1159 +#: part/models.py:1176 msgid "Part revision or version number" msgstr "零件修訂版本或版本號" -#: part/models.py:1160 report/models.py:231 +#: part/models.py:1177 report/models.py:234 msgid "Revision" msgstr "版本" -#: part/models.py:1169 +#: part/models.py:1186 msgid "Is this part a revision of another part?" msgstr "這零件是另一零件的修訂版本嗎?" -#: part/models.py:1170 +#: part/models.py:1187 msgid "Revision Of" msgstr "修訂版本" -#: part/models.py:1186 +#: part/models.py:1203 msgid "Where is this item normally stored?" msgstr "該物品通常存放在哪裏?" -#: part/models.py:1223 +#: part/models.py:1241 msgid "Default Expiry" msgstr "默認到期" -#: part/models.py:1224 +#: part/models.py:1242 msgid "Expiry time (in days) for stock items of this part" msgstr "此零件庫存項的過期時間 (天)" -#: part/models.py:1232 part/serializers.py:898 +#: part/models.py:1250 part/serializers.py:884 msgid "Minimum Stock" msgstr "最低庫存" -#: part/models.py:1233 +#: part/models.py:1251 msgid "Minimum allowed stock level" msgstr "允許的最小庫存量" -#: part/models.py:1241 part/serializers.py:902 +#: part/models.py:1259 part/serializers.py:888 msgid "Maximum Stock" msgstr "" -#: part/models.py:1242 +#: part/models.py:1260 msgid "Maximum allowed stock level" msgstr "" -#: part/models.py:1251 +#: part/models.py:1269 msgid "Units of measure for this part" msgstr "此零件的計量單位" -#: part/models.py:1258 +#: part/models.py:1276 msgid "Can this part be built from other parts?" msgstr "這個零件可由其他零件加工而成嗎?" -#: part/models.py:1264 +#: part/models.py:1282 msgid "Can this part be used to build other parts?" msgstr "這個零件可用於創建其他零件嗎?" -#: part/models.py:1270 +#: part/models.py:1288 msgid "Does this part have tracking for unique items?" msgstr "此零件是否有唯一物品的追蹤功能" -#: part/models.py:1276 +#: part/models.py:1294 msgid "Can this part have test results recorded against it?" msgstr "這一部分能否記錄到測試結果?" -#: part/models.py:1282 +#: part/models.py:1300 msgid "Can this part be purchased from external suppliers?" msgstr "這個零件可從外部供應商購買嗎?" -#: part/models.py:1288 +#: part/models.py:1306 msgid "Can this part be sold to customers?" msgstr "此零件可以銷售給客户嗎?" -#: part/models.py:1292 +#: part/models.py:1310 msgid "Is this part active?" msgstr "這個零件是否已激活?" -#: part/models.py:1298 +#: part/models.py:1316 msgid "Locked parts cannot be edited" msgstr "無法編輯鎖定的零件" -#: part/models.py:1304 +#: part/models.py:1322 msgid "Is this a virtual part, such as a software product or license?" msgstr "這是一個虛擬零件,例如一個軟件產品或許可證嗎?" -#: part/models.py:1309 +#: part/models.py:1328 +msgid "Is this part consumable, such as glue or a fastener?" +msgstr "" + +#: part/models.py:1333 msgid "BOM Validated" msgstr "BOM 已驗證" -#: part/models.py:1310 +#: part/models.py:1334 msgid "Is the BOM for this part valid?" msgstr "此零件的 BOM 是否已通過驗證?" -#: part/models.py:1316 +#: part/models.py:1340 msgid "BOM checksum" msgstr "物料清單校驗和" -#: part/models.py:1317 +#: part/models.py:1341 msgid "Stored BOM checksum" msgstr "保存的物料清單校驗和" -#: part/models.py:1325 +#: part/models.py:1349 msgid "BOM checked by" msgstr "物料清單檢查人" -#: part/models.py:1330 +#: part/models.py:1354 msgid "BOM checked date" msgstr "物料清單檢查日期" -#: part/models.py:1346 +#: part/models.py:1370 msgid "Creation User" msgstr "新建用户" -#: part/models.py:1356 +#: part/models.py:1380 msgid "Owner responsible for this part" msgstr "此零件的負責人" -#: part/models.py:2318 +#: part/models.py:2247 msgid "Sell multiple" msgstr "出售多個" -#: part/models.py:3327 +#: part/models.py:3216 msgid "Currency used to cache pricing calculations" msgstr "用於緩存定價計算的貨幣" -#: part/models.py:3343 +#: part/models.py:3232 msgid "Minimum BOM Cost" msgstr "最低物料清單成本" -#: part/models.py:3344 +#: part/models.py:3233 msgid "Minimum cost of component parts" msgstr "元件的最低成本" -#: part/models.py:3350 +#: part/models.py:3239 msgid "Maximum BOM Cost" msgstr "物料清單的最高成本" -#: part/models.py:3351 +#: part/models.py:3240 msgid "Maximum cost of component parts" msgstr "元件的最高成本" -#: part/models.py:3357 +#: part/models.py:3246 msgid "Minimum Purchase Cost" msgstr "最低購買成本" -#: part/models.py:3358 +#: part/models.py:3247 msgid "Minimum historical purchase cost" msgstr "最高歷史購買成本" -#: part/models.py:3364 +#: part/models.py:3253 msgid "Maximum Purchase Cost" msgstr "最大購買成本" -#: part/models.py:3365 +#: part/models.py:3254 msgid "Maximum historical purchase cost" msgstr "最高歷史購買成本" -#: part/models.py:3371 +#: part/models.py:3260 msgid "Minimum Internal Price" msgstr "最低內部價格" -#: part/models.py:3372 +#: part/models.py:3261 msgid "Minimum cost based on internal price breaks" msgstr "基於內部批發價的最低成本" -#: part/models.py:3378 +#: part/models.py:3267 msgid "Maximum Internal Price" msgstr "最大內部價格" -#: part/models.py:3379 +#: part/models.py:3268 msgid "Maximum cost based on internal price breaks" msgstr "基於內部批發價的最高成本" -#: part/models.py:3385 +#: part/models.py:3274 msgid "Minimum Supplier Price" msgstr "供應商最低價格" -#: part/models.py:3386 +#: part/models.py:3275 msgid "Minimum price of part from external suppliers" msgstr "外部供應商零件的最低價格" -#: part/models.py:3392 +#: part/models.py:3281 msgid "Maximum Supplier Price" msgstr "供應商最高價格" -#: part/models.py:3393 +#: part/models.py:3282 msgid "Maximum price of part from external suppliers" msgstr "來自外部供應商的商零件的最高價格" -#: part/models.py:3399 +#: part/models.py:3288 msgid "Minimum Variant Cost" msgstr "最小變體成本" -#: part/models.py:3400 +#: part/models.py:3289 msgid "Calculated minimum cost of variant parts" msgstr "計算出的變體零件的最低成本" -#: part/models.py:3406 +#: part/models.py:3295 msgid "Maximum Variant Cost" msgstr "最大變體成本" -#: part/models.py:3407 +#: part/models.py:3296 msgid "Calculated maximum cost of variant parts" msgstr "計算出的變體零件的最大成本" -#: part/models.py:3413 part/models.py:3427 +#: part/models.py:3302 part/models.py:3316 msgid "Minimum Cost" msgstr "最低成本" -#: part/models.py:3414 +#: part/models.py:3303 msgid "Override minimum cost" msgstr "覆蓋最低成本" -#: part/models.py:3420 part/models.py:3434 +#: part/models.py:3309 part/models.py:3323 msgid "Maximum Cost" msgstr "最高成本" -#: part/models.py:3421 +#: part/models.py:3310 msgid "Override maximum cost" msgstr "覆蓋最大成本" -#: part/models.py:3428 +#: part/models.py:3317 msgid "Calculated overall minimum cost" msgstr "計算總最低成本" -#: part/models.py:3435 +#: part/models.py:3324 msgid "Calculated overall maximum cost" msgstr "計算總最大成本" -#: part/models.py:3441 +#: part/models.py:3330 msgid "Minimum Sale Price" msgstr "最低售出價格" -#: part/models.py:3442 +#: part/models.py:3331 msgid "Minimum sale price based on price breaks" msgstr "基於批發價的最低售出價格" -#: part/models.py:3448 +#: part/models.py:3337 msgid "Maximum Sale Price" msgstr "最高售出價格" -#: part/models.py:3449 +#: part/models.py:3338 msgid "Maximum sale price based on price breaks" msgstr "基於批發價的最大售出價格" -#: part/models.py:3455 +#: part/models.py:3344 msgid "Minimum Sale Cost" msgstr "最低銷售成本" -#: part/models.py:3456 +#: part/models.py:3345 msgid "Minimum historical sale price" msgstr "歷史最低售出價格" -#: part/models.py:3462 +#: part/models.py:3351 msgid "Maximum Sale Cost" msgstr "最高銷售成本" -#: part/models.py:3463 +#: part/models.py:3352 msgid "Maximum historical sale price" msgstr "歷史最高售出價格" -#: part/models.py:3481 +#: part/models.py:3370 msgid "Part for stocktake" msgstr "用於盤點的零件" -#: part/models.py:3486 +#: part/models.py:3375 msgid "Item Count" msgstr "物品數量" -#: part/models.py:3487 +#: part/models.py:3376 msgid "Number of individual stock entries at time of stocktake" msgstr "盤點時的個別庫存條目數" -#: part/models.py:3495 +#: part/models.py:3384 msgid "Total available stock at time of stocktake" msgstr "盤點時可用庫存總額" -#: part/models.py:3499 report/templates/report/inventree_test_report.html:106 -#: stock/models.py:3129 +#: part/models.py:3388 report/templates/report/inventree_test_report.html:106 +#: stock/models.py:3933 msgid "Date" msgstr "日期" -#: part/models.py:3500 +#: part/models.py:3389 msgid "Date stocktake was performed" msgstr "進行盤點的日期" -#: part/models.py:3507 +#: part/models.py:3396 msgid "Minimum Stock Cost" msgstr "最低庫存成本" -#: part/models.py:3508 +#: part/models.py:3397 msgid "Estimated minimum cost of stock on hand" msgstr "現有存庫存最低成本估算" -#: part/models.py:3514 +#: part/models.py:3403 msgid "Maximum Stock Cost" msgstr "最高庫存成本" -#: part/models.py:3515 +#: part/models.py:3404 msgid "Estimated maximum cost of stock on hand" msgstr "目前庫存最高成本估算" -#: part/models.py:3525 +#: part/models.py:3414 msgid "Part Sale Price Break" msgstr "零件售出價格折扣" -#: part/models.py:3639 +#: part/models.py:3438 +msgid "Part Internal Price Break" +msgstr "" + +#: part/models.py:3529 msgid "Part Test Template" msgstr "零件測試模板" -#: part/models.py:3665 +#: part/models.py:3555 msgid "Invalid template name - must include at least one alphanumeric character" msgstr "模板名稱無效 - 必須包含至少一個字母或者數字" -#: part/models.py:3697 +#: part/models.py:3587 msgid "Test templates can only be created for testable parts" msgstr "測試模板只能為可拆分的部件創建" -#: part/models.py:3711 +#: part/models.py:3601 msgid "Test template with the same key already exists for part" msgstr "零件已存在具有相同主鍵的測試模板" -#: part/models.py:3728 +#: part/models.py:3618 msgid "Test Name" msgstr "測試名" -#: part/models.py:3729 +#: part/models.py:3619 msgid "Enter a name for the test" msgstr "輸入測試的名稱" -#: part/models.py:3735 +#: part/models.py:3625 msgid "Test Key" msgstr "測試主鍵" -#: part/models.py:3736 +#: part/models.py:3626 msgid "Simplified key for the test" msgstr "簡化測試主鍵" -#: part/models.py:3743 +#: part/models.py:3633 msgid "Test Description" msgstr "測試説明" -#: part/models.py:3744 +#: part/models.py:3634 msgid "Enter description for this test" msgstr "輸入測試的描述" -#: part/models.py:3748 +#: part/models.py:3638 msgid "Is this test enabled?" msgstr "此測試是否已啓用?" -#: part/models.py:3753 +#: part/models.py:3643 msgid "Required" msgstr "必須的" -#: part/models.py:3754 +#: part/models.py:3644 msgid "Is this test required to pass?" msgstr "需要此測試才能通過嗎?" -#: part/models.py:3759 +#: part/models.py:3649 msgid "Requires Value" msgstr "需要值" -#: part/models.py:3760 +#: part/models.py:3650 msgid "Does this test require a value when adding a test result?" msgstr "添加測試結果時是否需要一個值?" -#: part/models.py:3765 +#: part/models.py:3655 msgid "Requires Attachment" msgstr "需要附件" -#: part/models.py:3767 +#: part/models.py:3657 msgid "Does this test require a file attachment when adding a test result?" msgstr "添加測試結果時是否需要文件附件?" -#: part/models.py:3774 +#: part/models.py:3664 msgid "Valid choices for this test (comma-separated)" msgstr "此測試的有效選擇 (逗號分隔)" -#: part/models.py:3918 +#: part/models.py:3815 msgid "Invalid quantity - no units specified for part" msgstr "" -#: part/models.py:3927 +#: part/models.py:3824 msgid "Quantity must be greater than or equal to zero" msgstr "數量必須大於或等於零" -#: part/models.py:4023 +#: part/models.py:3925 msgid "BOM item cannot be modified - assembly is locked" msgstr "物料清單項目不能被修改 - 裝配已鎖定" -#: part/models.py:4030 +#: part/models.py:3932 msgid "BOM item cannot be modified - variant assembly is locked" msgstr "物料清單項目不能修改 - 變體裝配已鎖定" -#: part/models.py:4040 +#: part/models.py:3942 msgid "Select parent part" msgstr "選擇父零件" -#: part/models.py:4050 +#: part/models.py:3952 msgid "Sub part" msgstr "子零件" -#: part/models.py:4051 +#: part/models.py:3953 msgid "Select part to be used in BOM" msgstr "選擇要用於物料清單的零件" -#: part/models.py:4057 part/serializers.py:1688 +#: part/models.py:3959 part/serializers.py:1704 msgid "Amount" msgstr "" -#: part/models.py:4058 +#: part/models.py:3960 msgid "Amount of sub-part consumed to produce one part" msgstr "" -#: part/models.py:4070 +#: part/models.py:3972 msgid "BOM quantity for this BOM item" msgstr "此物料清單項目的數量" -#: part/models.py:4076 +#: part/models.py:3978 msgid "This BOM item is optional" msgstr "此物料清單項目是可選的" -#: part/models.py:4082 +#: part/models.py:3984 msgid "This BOM item is consumable (it is not tracked in build orders)" msgstr "這個物料清單項目是耗材 (它沒有在生產訂單中被追蹤)" -#: part/models.py:4090 +#: part/models.py:3992 msgid "Setup Quantity" msgstr "建置額外數量" -#: part/models.py:4091 +#: part/models.py:3993 msgid "Extra required quantity for a build, to account for setup losses" msgstr "為彌補建置 / 開工損耗所需的額外數量" -#: part/models.py:4099 +#: part/models.py:4001 msgid "Attrition" msgstr "損耗率" -#: part/models.py:4101 +#: part/models.py:4003 msgid "Estimated attrition for a build, expressed as a percentage (0-100)" msgstr "製造預估損耗(百分比 0–100)" -#: part/models.py:4112 +#: part/models.py:4014 msgid "Rounding Multiple" msgstr "進位倍數" -#: part/models.py:4114 +#: part/models.py:4016 msgid "Round up required production quantity to nearest multiple of this value" msgstr "將所需生產數量向上取整到此數值的整數倍" -#: part/models.py:4122 +#: part/models.py:4023 part/serializers.py:1722 +msgid "Piece Count" +msgstr "" + +#: part/models.py:4025 part/serializers.py:1724 +msgid "Number of pieces required (for cut-to-length items). Total material = quantity x piece_count." +msgstr "" + +#: part/models.py:4034 msgid "BOM item reference" msgstr "物料清單項目引用" -#: part/models.py:4130 +#: part/models.py:4042 msgid "BOM item notes" msgstr "物料清單項目註釋" -#: part/models.py:4136 +#: part/models.py:4048 msgid "Checksum" msgstr "校驗和" -#: part/models.py:4137 +#: part/models.py:4049 msgid "BOM line checksum" msgstr "物料清單行校驗和" -#: part/models.py:4142 +#: part/models.py:4054 msgid "Validated" msgstr "已驗證" -#: part/models.py:4143 +#: part/models.py:4055 msgid "This BOM item has been validated" msgstr "此物料清單項目已驗證" -#: part/models.py:4148 +#: part/models.py:4060 msgid "Gets inherited" msgstr "獲取繼承的" -#: part/models.py:4149 +#: part/models.py:4061 msgid "This BOM item is inherited by BOMs for variant parts" msgstr "此物料清單項目是由物料清單繼承的變體零件" -#: part/models.py:4155 +#: part/models.py:4067 msgid "Stock items for variant parts can be used for this BOM item" msgstr "變體零件的庫存項可以用於此物料清單項目" -#: part/models.py:4262 stock/models.py:956 +#: part/models.py:4204 stock/models.py:1064 msgid "Quantity must be integer value for trackable parts" msgstr "可追蹤零件的數量必須是整數" -#: part/models.py:4272 part/models.py:4274 +#: part/models.py:4214 part/models.py:4216 msgid "Sub part must be specified" msgstr "必須指定子零件" -#: part/models.py:4425 +#: part/models.py:4354 msgid "BOM Item Substitute" msgstr "物料清單項目替代品" -#: part/models.py:4446 +#: part/models.py:4375 msgid "Substitute part cannot be the same as the master part" msgstr "替代品零件不能與主零件相同" -#: part/models.py:4459 +#: part/models.py:4388 msgid "Parent BOM item" msgstr "上級物料清單項目" -#: part/models.py:4467 +#: part/models.py:4396 msgid "Substitute part" msgstr "替代品零件" -#: part/models.py:4483 +#: part/models.py:4412 msgid "Part 1" msgstr "零件 1" -#: part/models.py:4491 +#: part/models.py:4420 msgid "Part 2" msgstr "零件2" -#: part/models.py:4492 +#: part/models.py:4421 msgid "Select Related Part" msgstr "選擇相關的零件" -#: part/models.py:4499 +#: part/models.py:4428 msgid "Note for this relationship" msgstr "此關係的備註" -#: part/models.py:4518 +#: part/models.py:4447 msgid "Part relationship cannot be created between a part and itself" msgstr "零件關係不能在零件和自身之間創建" -#: part/models.py:4523 +#: part/models.py:4452 msgid "Duplicate relationship already exists" msgstr "複製關係已經存在" -#: part/serializers.py:107 +#: part/serializers.py:66 +msgid "Delete Subcategories" +msgstr "" + +#: part/serializers.py:67 +msgid "Delete all sub-categories contained within this category" +msgstr "" + +#: part/serializers.py:72 +msgid "Delete Parts" +msgstr "" + +#: part/serializers.py:73 +msgid "Delete all parts contained within this category" +msgstr "" + +#: part/serializers.py:130 msgid "Parent Category" msgstr "上級類別" -#: part/serializers.py:108 +#: part/serializers.py:131 msgid "Parent part category" msgstr "上級零件類別" -#: part/serializers.py:116 part/serializers.py:168 +#: part/serializers.py:139 part/serializers.py:204 msgid "Subcategories" msgstr "子類別" -#: part/serializers.py:207 +#: part/serializers.py:243 msgid "Results" msgstr "結果" -#: part/serializers.py:208 +#: part/serializers.py:244 msgid "Number of results recorded against this template" msgstr "根據該模板記錄的結果數量" -#: part/serializers.py:239 part/serializers.py:257 stock/serializers.py:672 +#: part/serializers.py:275 part/serializers.py:296 stock/serializers.py:679 msgid "Purchase currency of this stock item" msgstr "購買此庫存項的貨幣" -#: part/serializers.py:284 +#: part/serializers.py:323 msgid "File is not an image" msgstr "檔案不是圖片" -#: part/serializers.py:394 -msgid "Original Part" -msgstr "原始零件" - -#: part/serializers.py:395 -msgid "Select original part to duplicate" -msgstr "選擇要複製的原始零件" - -#: part/serializers.py:400 -msgid "Copy Image" -msgstr "複製圖片" - -#: part/serializers.py:401 -msgid "Copy image from original part" -msgstr "從原零件複製圖片" - -#: part/serializers.py:407 -msgid "Copy BOM" -msgstr "複製物料清單" - -#: part/serializers.py:408 -msgid "Copy bill of materials from original part" -msgstr "從原始零件複製材料清單" - -#: part/serializers.py:415 -msgid "Copy parameter data from original part" -msgstr "從原始零件複製參數數據" - -#: part/serializers.py:421 -msgid "Copy Notes" -msgstr "複製備註" - -#: part/serializers.py:422 -msgid "Copy notes from original part" -msgstr "從原始零件複製備註" - -#: part/serializers.py:428 -msgid "Copy Tests" -msgstr "複製測試模板" - -#: part/serializers.py:429 -msgid "Copy test templates from original part" -msgstr "從原始零件複製測試模板" - -#: part/serializers.py:447 +#: part/serializers.py:426 msgid "Initial Stock Quantity" msgstr "初始化庫存數量" -#: part/serializers.py:449 +#: part/serializers.py:428 msgid "Specify initial stock quantity for this Part. If quantity is zero, no stock is added." msgstr "指定此零件的初始庫存數量。如果數量為零,則不添加任何庫存。" -#: part/serializers.py:456 +#: part/serializers.py:435 msgid "Initial Stock Location" msgstr "初始化庫存地點" -#: part/serializers.py:457 +#: part/serializers.py:436 msgid "Specify initial stock location for this Part" msgstr "初始化指定此零件的庫存地點" -#: part/serializers.py:474 +#: part/serializers.py:453 msgid "Select supplier (or leave blank to skip)" msgstr "選擇供應商(或為空以跳過)" -#: part/serializers.py:490 +#: part/serializers.py:469 msgid "Select manufacturer (or leave blank to skip)" msgstr "選擇製造商(或為空)" -#: part/serializers.py:500 +#: part/serializers.py:479 msgid "Manufacturer part number" msgstr "製造商零件號" -#: part/serializers.py:507 +#: part/serializers.py:486 msgid "Selected company is not a valid supplier" msgstr "所選公司不是一個有效的供應商" -#: part/serializers.py:516 +#: part/serializers.py:495 msgid "Selected company is not a valid manufacturer" msgstr "所選公司不是一個有效的製造商" -#: part/serializers.py:527 +#: part/serializers.py:506 msgid "Manufacturer part matching this MPN already exists" msgstr "與此製造商零件編號 (MPN) 的相匹配的製造商零件已存在" -#: part/serializers.py:534 +#: part/serializers.py:513 msgid "Supplier part matching this SKU already exists" msgstr "匹配此庫存單位 (SKU) 的供應商零件已存在" -#: part/serializers.py:813 +#: part/serializers.py:799 msgid "Category Name" msgstr "類別名稱" -#: part/serializers.py:842 +#: part/serializers.py:828 msgid "Building" msgstr "正在生產" -#: part/serializers.py:843 +#: part/serializers.py:829 msgid "Quantity of this part currently being in production" msgstr "此零件目前生產中數量" -#: part/serializers.py:850 +#: part/serializers.py:836 msgid "Outstanding quantity of this part scheduled to be built" msgstr "此零件排程待製造未完成數量" -#: part/serializers.py:870 stock/serializers.py:1048 stock/serializers.py:1231 -#: users/ruleset.py:32 +#: part/serializers.py:856 stock/serializers.py:1264 stock/serializers.py:1480 +#: users/ruleset.py:33 msgid "Stock Items" msgstr "庫存項" -#: part/serializers.py:874 +#: part/serializers.py:860 msgid "Revisions" msgstr "修訂" -#: part/serializers.py:878 part/serializers.py:1177 +#: part/serializers.py:864 part/serializers.py:1190 #: templates/email/low_stock_notification.html:16 #: templates/email/part_event_notification.html:17 msgid "Total Stock" msgstr "庫存總量" -#: part/serializers.py:886 +#: part/serializers.py:872 msgid "Unallocated Stock" msgstr "未分配的庫存" -#: part/serializers.py:894 +#: part/serializers.py:880 msgid "Variant Stock" msgstr "變體庫存" -#: part/serializers.py:969 +#: part/serializers.py:956 msgid "Duplicate Part" msgstr "重複零件" -#: part/serializers.py:970 +#: part/serializers.py:957 msgid "Copy initial data from another Part" msgstr "從另一個零件複製初始數據" -#: part/serializers.py:976 +#: part/serializers.py:962 +msgid "Copy Image" +msgstr "複製圖片" + +#: part/serializers.py:963 +msgid "Copy image from original part" +msgstr "從原零件複製圖片" + +#: part/serializers.py:968 +msgid "Copy BOM" +msgstr "複製物料清單" + +#: part/serializers.py:969 +msgid "Copy bill of materials from original part" +msgstr "從原始零件複製材料清單" + +#: part/serializers.py:974 +msgid "Copy Notes" +msgstr "複製備註" + +#: part/serializers.py:975 +msgid "Copy notes from original part" +msgstr "從原始零件複製備註" + +#: part/serializers.py:980 +msgid "Copy Tests" +msgstr "複製測試模板" + +#: part/serializers.py:981 +msgid "Copy test templates from original part" +msgstr "從原始零件複製測試模板" + +#: part/serializers.py:988 msgid "Initial Stock" msgstr "初始庫存" -#: part/serializers.py:977 +#: part/serializers.py:989 msgid "Create Part with initial stock quantity" msgstr "創建具有初始庫存數量的零件" -#: part/serializers.py:983 +#: part/serializers.py:995 msgid "Supplier Information" msgstr "供應商信息" -#: part/serializers.py:984 +#: part/serializers.py:996 msgid "Add initial supplier information for this part" msgstr "添加此零件的初始供應商信息" -#: part/serializers.py:993 +#: part/serializers.py:1005 msgid "Copy Category Parameters" msgstr "複製類別參數" -#: part/serializers.py:994 +#: part/serializers.py:1006 msgid "Copy parameter templates from selected part category" msgstr "從選擇的零件複製參數模版" -#: part/serializers.py:999 +#: part/serializers.py:1011 msgid "Existing Image" msgstr "現有的圖片" -#: part/serializers.py:1000 +#: part/serializers.py:1012 msgid "Filename of an existing part image" msgstr "現有零件圖片的文件名" -#: part/serializers.py:1017 +#: part/serializers.py:1029 msgid "Image file does not exist" msgstr "圖片不存在" -#: part/serializers.py:1149 +#: part/serializers.py:1162 msgid "Validate entire Bill of Materials" msgstr "驗證整個物料清單" -#: part/serializers.py:1183 part/serializers.py:1779 +#: part/serializers.py:1196 part/serializers.py:1805 msgid "Can Build" msgstr "可以創建" -#: part/serializers.py:1200 +#: part/serializers.py:1213 msgid "Required for Build Orders" msgstr "生產工單需求數" -#: part/serializers.py:1205 +#: part/serializers.py:1218 msgid "Allocated to Build Orders" msgstr "已分配至生產工單" -#: part/serializers.py:1212 +#: part/serializers.py:1225 msgid "Required for Sales Orders" msgstr "銷售訂單需求數" -#: part/serializers.py:1216 +#: part/serializers.py:1229 msgid "Allocated to Sales Orders" msgstr "已分配至銷售訂單" -#: part/serializers.py:1276 +#: part/serializers.py:1289 msgid "Part IPN" msgstr "零件 IPN" -#: part/serializers.py:1283 +#: part/serializers.py:1296 msgid "Part Description" msgstr "零件描述" -#: part/serializers.py:1327 +#: part/serializers.py:1340 msgid "Select a part to generate stocktake information for that part (and any variant parts)" msgstr "選擇一個零件以產生該零件 (及其任何變體零件) 的盤點資訊" -#: part/serializers.py:1337 +#: part/serializers.py:1350 msgid "Select a category to include all parts within that category (and subcategories)" msgstr "選擇一個類別以包含該類別 (及其子類別) 內的所有零件" -#: part/serializers.py:1347 +#: part/serializers.py:1360 msgid "Select a location to include all parts with stock in that location (including sub-locations)" msgstr "選擇一個位置以包含該位置 (及其子位置) 內所有有庫存的零件" -#: part/serializers.py:1354 +#: part/serializers.py:1367 msgid "Generate Stocktake Entries" msgstr "產生盤點項目" -#: part/serializers.py:1355 +#: part/serializers.py:1368 msgid "Save stocktake entries for the selected parts" msgstr "儲存選定零件的盤點項目" -#: part/serializers.py:1362 +#: part/serializers.py:1375 msgid "Generate Report" msgstr "產製報表" -#: part/serializers.py:1363 +#: part/serializers.py:1376 msgid "Generate a stocktake report for the selected parts" msgstr "產製選定零件的庫存報表" -#: part/serializers.py:1466 +#: part/serializers.py:1481 msgid "Minimum Price" msgstr "最低價格" -#: part/serializers.py:1467 +#: part/serializers.py:1482 msgid "Override calculated value for minimum price" msgstr "覆蓋已計算的最低價格值" -#: part/serializers.py:1474 +#: part/serializers.py:1489 msgid "Minimum price currency" msgstr "最低價格貨幣" -#: part/serializers.py:1481 +#: part/serializers.py:1496 msgid "Maximum Price" msgstr "最高價格" -#: part/serializers.py:1482 +#: part/serializers.py:1497 msgid "Override calculated value for maximum price" msgstr "覆蓋已計算的最高價格值" -#: part/serializers.py:1489 +#: part/serializers.py:1504 msgid "Maximum price currency" msgstr "最高價格貨幣" -#: part/serializers.py:1518 +#: part/serializers.py:1533 msgid "Update" msgstr "更新" -#: part/serializers.py:1519 +#: part/serializers.py:1534 msgid "Update pricing for this part" msgstr "更新這個零件的價格" -#: part/serializers.py:1542 +#: part/serializers.py:1557 #, python-brace-format msgid "Could not convert from provided currencies to {default_currency}" msgstr "無法將所提供的貨幣轉換為 {default_currency}" -#: part/serializers.py:1549 +#: part/serializers.py:1564 msgid "Minimum price must not be greater than maximum price" msgstr "最低價格不能高於最高價格。" -#: part/serializers.py:1552 +#: part/serializers.py:1567 msgid "Maximum price must not be less than minimum price" msgstr "最高價格不能低於最低價格" -#: part/serializers.py:1689 +#: part/serializers.py:1705 msgid "Amount required for this item (can include units)" msgstr "" -#: part/serializers.py:1706 +#: part/serializers.py:1732 msgid "Select the parent assembly" msgstr "選擇父裝配" -#: part/serializers.py:1741 +#: part/serializers.py:1767 msgid "Select the component part" msgstr "選擇零部件" -#: part/serializers.py:1861 +#: part/serializers.py:1887 msgid "Invalid quantity format" msgstr "" -#: part/serializers.py:1989 +#: part/serializers.py:2016 msgid "Select part to copy BOM from" msgstr "選擇要複製物料清單的零件" -#: part/serializers.py:1997 +#: part/serializers.py:2024 msgid "Remove Existing Data" msgstr "移除現有數據" -#: part/serializers.py:1998 +#: part/serializers.py:2025 msgid "Remove existing BOM items before copying" msgstr "複製前刪除現有的物料清單項目" -#: part/serializers.py:2003 +#: part/serializers.py:2030 msgid "Include Inherited" msgstr "包含繼承的" -#: part/serializers.py:2004 +#: part/serializers.py:2031 msgid "Include BOM items which are inherited from templated parts" msgstr "包含從模板零件繼承的物料清單項目" -#: part/serializers.py:2009 +#: part/serializers.py:2036 msgid "Skip Invalid Rows" msgstr "跳過無效行" -#: part/serializers.py:2010 +#: part/serializers.py:2037 msgid "Enable this option to skip invalid rows" msgstr "啓用此選項以跳過無效行" -#: part/serializers.py:2015 +#: part/serializers.py:2042 msgid "Copy Substitute Parts" msgstr "複製替代品零件" -#: part/serializers.py:2016 +#: part/serializers.py:2043 msgid "Copy substitute parts when duplicate BOM items" msgstr "複製物料清單項目時複製替代品零件" -#: part/tasks.py:42 +#: part/tasks.py:43 msgid "Low stock notification" msgstr "低庫存通知" -#: part/tasks.py:44 +#: part/tasks.py:45 #, python-brace-format msgid "The available stock for {part.name} has fallen below the configured minimum level" msgstr "可用的 {part.name}庫存已經跌到設置的最低值" -#: part/tasks.py:74 +#: part/tasks.py:75 msgid "Stale stock notification" msgstr "庫存即將過期通知" -#: part/tasks.py:78 +#: part/tasks.py:79 msgid "You have 1 stock item approaching its expiry date" msgstr "有 1 個庫存項目即將到期" -#: part/tasks.py:80 +#: part/tasks.py:81 #, python-brace-format msgid "You have {item_count} stock items approaching their expiry dates" msgstr "有 {item_count} 個庫存項目即將到期" -#: part/tasks.py:89 +#: part/tasks.py:90 msgid "No expiry date" msgstr "未設定到期日" -#: part/tasks.py:96 +#: part/tasks.py:97 msgid "Expired {abs(days_diff)} days ago" msgstr "已於 {abs(days_diff)} 天前到期" -#: part/tasks.py:99 +#: part/tasks.py:100 msgid "Expires today" msgstr "今日到期" -#: part/tasks.py:102 +#: part/tasks.py:103 #, python-brace-format msgid "{days_until_expiry} days" msgstr "尚餘 {days_until_expiry} 天" @@ -7011,7 +7451,7 @@ msgstr "範例" msgid "Installed" msgstr "已安裝" -#: plugin/api.py:190 +#: plugin/api.py:193 msgid "Plugin cannot be deleted as it is currently active" msgstr "插件不能被刪除,因為它當前處於激活狀態" @@ -7023,23 +7463,23 @@ msgstr "未指定操作" msgid "No matching action found" msgstr "未找到指定操作" -#: plugin/base/barcodes/api.py:212 +#: plugin/base/barcodes/api.py:214 msgid "No match found for barcode data" msgstr "未找到匹配條形碼數據" -#: plugin/base/barcodes/api.py:216 +#: plugin/base/barcodes/api.py:218 msgid "Match found for barcode data" msgstr "找到匹配條形碼數據" -#: plugin/base/barcodes/api.py:254 plugin/base/barcodes/serializers.py:77 +#: plugin/base/barcodes/api.py:256 plugin/base/barcodes/serializers.py:77 msgid "Model is not supported" msgstr "不支持模型" -#: plugin/base/barcodes/api.py:259 +#: plugin/base/barcodes/api.py:261 msgid "Model instance not found" msgstr "找不到模型實例" -#: plugin/base/barcodes/api.py:288 +#: plugin/base/barcodes/api.py:290 msgid "Barcode matches existing item" msgstr "條形碼匹配現有項目" @@ -7055,51 +7495,67 @@ msgstr "沒有找到匹配的供應商零件" msgid "Multiple matching supplier parts found" msgstr "找到多個匹配的供應商零件" -#: plugin/base/barcodes/api.py:451 plugin/base/barcodes/api.py:678 +#: plugin/base/barcodes/api.py:448 plugin/base/barcodes/api.py:508 +msgid "You do not have the required permissions for purchase orders" +msgstr "" + +#: plugin/base/barcodes/api.py:458 plugin/base/barcodes/api.py:761 msgid "No matching plugin found for barcode data" msgstr "沒有找到匹配條碼數據的插件" -#: plugin/base/barcodes/api.py:461 +#: plugin/base/barcodes/api.py:468 msgid "Matched supplier part" msgstr "匹配的供應商零件" -#: plugin/base/barcodes/api.py:529 +#: plugin/base/barcodes/api.py:543 msgid "Item has already been received" msgstr "項目已被接收" -#: plugin/base/barcodes/api.py:577 +#: plugin/base/barcodes/api.py:611 +msgid "Purchase order Found\\rNo supplier Part Match" +msgstr "" + +#: plugin/base/barcodes/api.py:617 +msgid "Supplier Part Found\\rNo Purchase Order Match" +msgstr "" + +#: plugin/base/barcodes/api.py:653 msgid "No plugin match for supplier barcode" msgstr "供應商條碼未匹配任何模組" -#: plugin/base/barcodes/api.py:626 +#: plugin/base/barcodes/api.py:704 msgid "Multiple matching line items found" msgstr "找到多個匹配的行項目" -#: plugin/base/barcodes/api.py:629 +#: plugin/base/barcodes/api.py:707 plugin/base/barcodes/mixins.py:393 msgid "No matching line item found" msgstr "未找到匹配的行項目" -#: plugin/base/barcodes/api.py:675 +#: plugin/base/barcodes/api.py:749 +msgid "You do not have the required permissions for sales orders" +msgstr "" + +#: plugin/base/barcodes/api.py:758 msgid "No sales order provided" msgstr "未提供銷售訂單" -#: plugin/base/barcodes/api.py:684 +#: plugin/base/barcodes/api.py:767 msgid "Barcode does not match an existing stock item" msgstr "條形碼與現有的庫存項不匹配" -#: plugin/base/barcodes/api.py:700 +#: plugin/base/barcodes/api.py:783 msgid "Stock item does not match line item" msgstr "庫存項與行項目不匹配" -#: plugin/base/barcodes/api.py:730 +#: plugin/base/barcodes/api.py:813 msgid "Insufficient stock available" msgstr "可用庫存不足" -#: plugin/base/barcodes/api.py:743 +#: plugin/base/barcodes/api.py:826 msgid "Stock item allocated to sales order" msgstr "庫存項已分配到銷售訂單" -#: plugin/base/barcodes/api.py:746 +#: plugin/base/barcodes/api.py:829 msgid "Not enough information" msgstr "沒有足夠的信息" @@ -7108,23 +7564,23 @@ msgstr "沒有足夠的信息" msgid "Found matching item" msgstr "找到匹配項目" -#: plugin/base/barcodes/mixins.py:375 +#: plugin/base/barcodes/mixins.py:397 msgid "Supplier part does not match line item" msgstr "供應商零件與行項目不匹配" -#: plugin/base/barcodes/mixins.py:378 +#: plugin/base/barcodes/mixins.py:402 msgid "Line item is already completed" msgstr "行項目已完成" -#: plugin/base/barcodes/mixins.py:415 +#: plugin/base/barcodes/mixins.py:440 msgid "Further information required to receive line item" msgstr "需要更多信息以接收行項目" -#: plugin/base/barcodes/mixins.py:423 +#: plugin/base/barcodes/mixins.py:448 msgid "Received purchase order line item" msgstr "已收到採購訂單行項目" -#: plugin/base/barcodes/mixins.py:430 +#: plugin/base/barcodes/mixins.py:455 msgid "Failed to receive line item" msgstr "接收行項目失敗" @@ -7261,21 +7717,21 @@ msgid "Provides native support for barcodes" msgstr "提供條形碼本地支持" #: plugin/builtin/barcodes/inventree_barcode.py:30 -#: plugin/builtin/events/auto_create_builds.py:30 +#: plugin/builtin/events/auto_create_builds.py:31 #: plugin/builtin/events/auto_issue_orders.py:19 #: plugin/builtin/exporter/bom_exporter.py:74 #: plugin/builtin/exporter/inventree_exporter.py:17 #: plugin/builtin/exporter/parameter_exporter.py:32 -#: plugin/builtin/exporter/stocktake_exporter.py:47 -#: plugin/builtin/integration/core_notifications.py:25 -#: plugin/builtin/integration/core_notifications.py:69 -#: plugin/builtin/integration/core_notifications.py:125 +#: plugin/builtin/exporter/stocktake_exporter.py:53 +#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:71 +#: plugin/builtin/integration/core_notifications.py:131 #: plugin/builtin/integration/currency_exchange.py:21 #: plugin/builtin/integration/machine_types.py:17 #: plugin/builtin/integration/part_notifications.py:21 #: plugin/builtin/labels/inventree_label.py:27 #: plugin/builtin/labels/inventree_machine.py:64 -#: plugin/builtin/labels/label_sheet.py:72 +#: plugin/builtin/labels/label_sheet.py:73 #: plugin/builtin/suppliers/digikey.py:20 plugin/builtin/suppliers/lcsc.py:22 #: plugin/builtin/suppliers/mouser.py:20 plugin/builtin/suppliers/tme.py:22 msgid "InvenTree contributors" @@ -7305,11 +7761,11 @@ msgstr "短條形碼前綴" msgid "Customize the prefix used for short barcodes, may be useful for environments with multiple InvenTree instances" msgstr "自定義用於短條形碼的前綴,可能對有多個InvenTree實例的環境有用。" -#: plugin/builtin/events/auto_create_builds.py:28 +#: plugin/builtin/events/auto_create_builds.py:29 msgid "Auto Create Builds" msgstr "自動建立生產單" -#: plugin/builtin/events/auto_create_builds.py:31 +#: plugin/builtin/events/auto_create_builds.py:32 msgid "Automatically create build orders for assemblies" msgstr "自動為裝配件建立生產工單" @@ -7507,74 +7963,82 @@ msgid "Include Variant Items" msgstr "包含變體項目" #: plugin/builtin/exporter/stocktake_exporter.py:32 -msgid "Include part variant stock in pricing calculations" -msgstr "價格計算納入零件變體庫存" +msgid "Include part variant stock in stocktake data" +msgstr "" -#: plugin/builtin/exporter/stocktake_exporter.py:44 +#: plugin/builtin/exporter/stocktake_exporter.py:37 +msgid "Exclude Zero Stock Entries" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:38 +msgid "Exclude parts with zero stock from the exported dataset" +msgstr "" + +#: plugin/builtin/exporter/stocktake_exporter.py:50 msgid "Part Stocktake Exporter" msgstr "零件盤點匯出器" -#: plugin/builtin/exporter/stocktake_exporter.py:45 +#: plugin/builtin/exporter/stocktake_exporter.py:51 msgid "Exporter for part stocktake data" msgstr "匯出零件盤點資料的工具" -#: plugin/builtin/exporter/stocktake_exporter.py:108 +#: plugin/builtin/exporter/stocktake_exporter.py:117 msgid "Minimum Unit Cost" msgstr "最低單位成本" -#: plugin/builtin/exporter/stocktake_exporter.py:109 +#: plugin/builtin/exporter/stocktake_exporter.py:118 msgid "Maximum Unit Cost" msgstr "最高單位成本" -#: plugin/builtin/exporter/stocktake_exporter.py:110 +#: plugin/builtin/exporter/stocktake_exporter.py:119 msgid "Minimum Total Cost" msgstr "最低總成本" -#: plugin/builtin/exporter/stocktake_exporter.py:111 +#: plugin/builtin/exporter/stocktake_exporter.py:120 msgid "Maximum Total Cost" msgstr "最高總成本" -#: plugin/builtin/integration/core_notifications.py:23 +#: plugin/builtin/integration/core_notifications.py:24 msgid "InvenTree UI Notifications" msgstr "InvenTree 介面通知" -#: plugin/builtin/integration/core_notifications.py:26 +#: plugin/builtin/integration/core_notifications.py:27 msgid "Integrated UI notification methods" msgstr "整合的介面通知方式" -#: plugin/builtin/integration/core_notifications.py:67 +#: plugin/builtin/integration/core_notifications.py:69 msgid "InvenTree Email Notifications" msgstr "InvenTree 電子郵件通知" -#: plugin/builtin/integration/core_notifications.py:70 +#: plugin/builtin/integration/core_notifications.py:72 msgid "Integrated email notification methods" msgstr "整合的電郵通知方式" -#: plugin/builtin/integration/core_notifications.py:75 +#: plugin/builtin/integration/core_notifications.py:77 msgid "Allow email notifications" msgstr "允許電子郵件通知" -#: plugin/builtin/integration/core_notifications.py:76 +#: plugin/builtin/integration/core_notifications.py:78 msgid "Allow email notifications to be sent to this user" msgstr "允許將電子郵件通知寄送給此使用者" -#: plugin/builtin/integration/core_notifications.py:123 +#: plugin/builtin/integration/core_notifications.py:129 msgid "InvenTree Slack Notifications" msgstr "InvenTree Slack 通知" -#: plugin/builtin/integration/core_notifications.py:126 +#: plugin/builtin/integration/core_notifications.py:132 msgid "Integrated Slack notification methods" msgstr "整合的 Slack 通知方式" -#: plugin/builtin/integration/core_notifications.py:131 +#: plugin/builtin/integration/core_notifications.py:137 msgid "Slack incoming webhook URL" msgstr "Slack 傳入 Webhook URL" -#: plugin/builtin/integration/core_notifications.py:132 +#: plugin/builtin/integration/core_notifications.py:138 msgid "URL that is used to send messages to a slack channel" msgstr "用於發送消息到slack頻道的 URL" -#: plugin/builtin/integration/core_notifications.py:162 +#: plugin/builtin/integration/core_notifications.py:168 msgid "Open link" msgstr "打開鏈接" @@ -7628,12 +8092,12 @@ msgid "Provides native support for printing PDF labels" msgstr "為打印 PDF 標籤提供本機支持" #: plugin/builtin/labels/inventree_label.py:33 -#: plugin/builtin/labels/label_sheet.py:78 +#: plugin/builtin/labels/label_sheet.py:79 msgid "Debug mode" msgstr "Debug模式" #: plugin/builtin/labels/inventree_label.py:34 -#: plugin/builtin/labels/label_sheet.py:79 +#: plugin/builtin/labels/label_sheet.py:80 msgid "Enable debug mode - returns raw HTML instead of PDF" msgstr "啓用Debug模式 - 返回原始的 HTML 而不是 PDF" @@ -7653,55 +8117,55 @@ msgstr "最近使用" msgid "Options" msgstr "選項" -#: plugin/builtin/labels/label_sheet.py:30 +#: plugin/builtin/labels/label_sheet.py:31 msgid "Page size for the label sheet" msgstr "標籤頁大小" -#: plugin/builtin/labels/label_sheet.py:35 +#: plugin/builtin/labels/label_sheet.py:36 msgid "Skip Labels" msgstr "跳過標籤" -#: plugin/builtin/labels/label_sheet.py:36 +#: plugin/builtin/labels/label_sheet.py:37 msgid "Skip this number of labels when printing label sheets" msgstr "打印標籤頁時跳過標籤的數量" -#: plugin/builtin/labels/label_sheet.py:43 +#: plugin/builtin/labels/label_sheet.py:44 msgid "Border" msgstr "邊框" -#: plugin/builtin/labels/label_sheet.py:44 +#: plugin/builtin/labels/label_sheet.py:45 msgid "Print a border around each label" msgstr "打印每個標籤的邊框" -#: plugin/builtin/labels/label_sheet.py:49 report/models.py:392 +#: plugin/builtin/labels/label_sheet.py:50 report/models.py:397 msgid "Landscape" msgstr "橫屏模式" -#: plugin/builtin/labels/label_sheet.py:50 +#: plugin/builtin/labels/label_sheet.py:51 msgid "Print the label sheet in landscape mode" msgstr "在橫屏模式下打印標籤表" -#: plugin/builtin/labels/label_sheet.py:55 +#: plugin/builtin/labels/label_sheet.py:56 msgid "Page Margin" msgstr "頁邊距" -#: plugin/builtin/labels/label_sheet.py:56 +#: plugin/builtin/labels/label_sheet.py:57 msgid "Margin around the page in mm" msgstr "頁面四周邊距(毫米)" -#: plugin/builtin/labels/label_sheet.py:69 +#: plugin/builtin/labels/label_sheet.py:70 msgid "InvenTree Label Sheet Printer" msgstr "庫存樹標籤工作表" -#: plugin/builtin/labels/label_sheet.py:70 +#: plugin/builtin/labels/label_sheet.py:71 msgid "Arrays multiple labels onto a single sheet" msgstr "單張紙上的組合多個標籤" -#: plugin/builtin/labels/label_sheet.py:122 +#: plugin/builtin/labels/label_sheet.py:123 msgid "Label is too large for page size" msgstr "標籤大過頁面" -#: plugin/builtin/labels/label_sheet.py:161 +#: plugin/builtin/labels/label_sheet.py:162 msgid "No labels were generated" msgstr "沒有生成標籤" @@ -7753,77 +8217,85 @@ msgstr "為掃描 TME 條形碼提供支持" msgid "The Supplier which acts as 'TME'" msgstr "作為‘TME’的供應商" -#: plugin/installer.py:240 plugin/installer.py:344 plugin/serializers.py:169 +#: plugin/installer.py:44 +msgid "Pip is not installed in the current environment" +msgstr "" + +#: plugin/installer.py:243 plugin/installer.py:348 plugin/serializers.py:169 #: plugin/serializers.py:275 msgid "Only superuser accounts can administer plugins" msgstr "只有超級使用者帳號可以管理外掛程式" -#: plugin/installer.py:243 +#: plugin/installer.py:246 msgid "Plugin installation is disabled" msgstr "插件安裝已禁用" -#: plugin/installer.py:273 +#: plugin/installer.py:267 +msgid "Invalid URL and no package name provided" +msgstr "" + +#: plugin/installer.py:276 msgid "No package name or URL provided for installation" msgstr "未提供要安裝的套件名稱或 URL" -#: plugin/installer.py:277 +#: plugin/installer.py:280 msgid "Invalid characters in package name or URL" msgstr "套件名稱或 URL 中包含無效字元" -#: plugin/installer.py:287 +#: plugin/installer.py:291 msgid "Installed plugin successfully" msgstr "插件安裝成功" -#: plugin/installer.py:292 +#: plugin/installer.py:296 #, python-brace-format msgid "Installed plugin into {path}" msgstr "插件安裝到 {path}" -#: plugin/installer.py:318 +#: plugin/installer.py:322 msgid "Plugin was not found in registry" msgstr "在插件倉庫中找不到插件" -#: plugin/installer.py:321 +#: plugin/installer.py:325 msgid "Plugin is not a packaged plugin" msgstr "插件不是一個打包的插件" -#: plugin/installer.py:324 +#: plugin/installer.py:328 msgid "Plugin package name not found" msgstr "找不到插件包名稱" -#: plugin/installer.py:327 +#: plugin/installer.py:331 msgid "Only staff users can administer plugins" msgstr "只有員工用户可以管理插件" -#: plugin/installer.py:347 +#: plugin/installer.py:351 msgid "Plugin uninstalling is disabled" msgstr "插件卸載已禁用" -#: plugin/installer.py:351 +#: plugin/installer.py:355 msgid "Plugin cannot be uninstalled as it is currently active" msgstr "插件無法卸載,因為它目前處於激活狀態" -#: plugin/installer.py:357 +#: plugin/installer.py:361 msgid "Plugin cannot be uninstalled as it is mandatory" msgstr "不可解除安裝此模組(屬於強制)" -#: plugin/installer.py:362 +#: plugin/installer.py:366 msgid "Plugin cannot be uninstalled as it is a sample plugin" msgstr "不可解除安裝此模組(範例模組)" -#: plugin/installer.py:367 +#: plugin/installer.py:371 msgid "Plugin cannot be uninstalled as it is a built-in plugin" msgstr "不可解除安裝此模組(內建模組)" -#: plugin/installer.py:371 +#: plugin/installer.py:375 msgid "Plugin is not installed" msgstr "模組尚未安裝" -#: plugin/installer.py:389 +#: plugin/installer.py:393 msgid "Plugin installation not found" msgstr "找不到模組安裝紀錄" -#: plugin/installer.py:405 +#: plugin/installer.py:409 msgid "Uninstalled plugin successfully" msgstr "插件卸載成功" @@ -7871,25 +8343,25 @@ msgstr "強制模組" msgid "Package Plugin" msgstr "軟件包插件" -#: plugin/models.py:301 plugin/models.py:347 +#: plugin/models.py:301 plugin/models.py:384 msgid "Plugin" msgstr "插件" -#: plugin/plugin.py:388 +#: plugin/plugin.py:389 msgid "No author found" msgstr "未找到作者" -#: plugin/registry.py:786 +#: plugin/registry.py:825 #, python-brace-format msgid "Plugin '{p}' is not compatible with the current InvenTree version {v}" msgstr "插件 '{p}' 與當前 InvenTree 版本{v} 不兼容" -#: plugin/registry.py:789 +#: plugin/registry.py:828 #, python-brace-format msgid "Plugin requires at least version {v}" msgstr "插件所需最低版本 {v}" -#: plugin/registry.py:791 +#: plugin/registry.py:830 #, python-brace-format msgid "Plugin requires at most version {v}" msgstr "插件所需最高版本 {v}" @@ -8114,176 +8586,184 @@ msgstr "刪除配置" msgid "Delete the plugin configuration from the database" msgstr "從數據庫中刪除插件配置" -#: plugin/serializers.py:299 +#: plugin/serializers.py:292 +msgid "Indicates if the setting is overridden by configuration" +msgstr "" + +#: plugin/serializers.py:312 msgid "The user for which this setting applies" msgstr "此設定所適用的使用者" -#: report/api.py:44 report/serializers.py:125 report/serializers.py:175 +#: report/api.py:45 report/serializers.py:123 report/serializers.py:183 msgid "Items" msgstr "項目" -#: report/api.py:115 +#: report/api.py:116 msgid "Plugin not found" msgstr "插件未找到" -#: report/api.py:117 +#: report/api.py:118 msgid "Plugin does not support label printing" msgstr "插件不支持標籤打印" -#: report/api.py:165 +#: report/api.py:170 report/api.py:279 +msgid "You do not have permission to view this model type" +msgstr "" + +#: report/api.py:174 msgid "Invalid label dimensions" msgstr "無效的標籤尺寸" -#: report/api.py:183 report/api.py:272 +#: report/api.py:192 report/api.py:290 msgid "No valid items provided to template" msgstr "沒有有效的項目提供到模板" -#: report/helpers.py:43 +#: report/helpers.py:44 msgid "A4" msgstr "A4" -#: report/helpers.py:44 +#: report/helpers.py:45 msgid "A3" msgstr "A3" -#: report/helpers.py:45 +#: report/helpers.py:46 msgid "Legal" msgstr "法律" -#: report/helpers.py:46 +#: report/helpers.py:47 msgid "Letter" msgstr "字母" -#: report/models.py:128 +#: report/models.py:131 msgid "Template file with this name already exists" msgstr "已存在具有此名稱的模板" -#: report/models.py:220 +#: report/models.py:223 msgid "Template name" msgstr "模版名稱" -#: report/models.py:226 +#: report/models.py:229 msgid "Template description" msgstr "模板説明" -#: report/models.py:232 +#: report/models.py:235 msgid "Revision number (auto-increments)" msgstr "修訂編號 (自動增量)" -#: report/models.py:238 +#: report/models.py:241 msgid "Attach to Model on Print" msgstr "打印時附加到模型" -#: report/models.py:240 +#: report/models.py:243 msgid "Save report output as an attachment against linked model instance when printing" msgstr "打印時將報告輸出保存為附件與鏈接模型實例" -#: report/models.py:286 +#: report/models.py:291 msgid "Filename Pattern" msgstr "文件名樣式" -#: report/models.py:287 +#: report/models.py:292 msgid "Pattern for generating filenames" msgstr "生成文件名模式" -#: report/models.py:292 +#: report/models.py:297 msgid "Template is enabled" msgstr "模板已啓用" -#: report/models.py:299 +#: report/models.py:304 msgid "Target model type for template" msgstr "模版的目標模型類型" -#: report/models.py:319 +#: report/models.py:324 msgid "Filters" msgstr "篩選器" -#: report/models.py:320 +#: report/models.py:325 msgid "Template query filters (comma-separated list of key=value pairs)" msgstr "模版查詢篩選器 (逗號分隔的鍵值對列表)" -#: report/models.py:379 report/models.py:700 +#: report/models.py:384 report/models.py:718 msgid "Template file" msgstr "模板包文件" -#: report/models.py:387 +#: report/models.py:392 msgid "Page size for PDF reports" msgstr "PDF 報告的頁面大小" -#: report/models.py:393 +#: report/models.py:398 msgid "Render report in landscape orientation" msgstr "橫向渲染報告" -#: report/models.py:398 +#: report/models.py:403 msgid "Merge" msgstr "合併" -#: report/models.py:399 +#: report/models.py:404 msgid "Render a single report against selected items" msgstr "針對所選項目產出合併單一報告" -#: report/models.py:466 +#: report/models.py:471 #, python-brace-format msgid "Report generated from template {self.name}" msgstr "由模板 {self.name} 產生的報告" -#: report/models.py:576 report/models.py:615 report/models.py:616 +#: report/models.py:581 report/models.py:620 msgid "Template syntax error" msgstr "模板語法錯誤" -#: report/models.py:583 report/models.py:622 +#: report/models.py:588 report/models.py:627 msgid "Error rendering report" msgstr "報告渲染錯誤" -#: report/models.py:643 +#: report/models.py:655 msgid "Error generating report" msgstr "生成報告錯誤" -#: report/models.py:674 +#: report/models.py:686 msgid "Error merging report outputs" msgstr "合併報告輸出時發生錯誤" -#: report/models.py:706 +#: report/models.py:724 msgid "Width [mm]" msgstr "寬度 [mm]" -#: report/models.py:707 +#: report/models.py:725 msgid "Label width, specified in mm" msgstr "標籤寬度,以毫米為單位。" -#: report/models.py:713 +#: report/models.py:731 msgid "Height [mm]" msgstr "高度 [mm]" -#: report/models.py:714 +#: report/models.py:732 msgid "Label height, specified in mm" msgstr "標籤高度,以毫米為單位。" -#: report/models.py:828 +#: report/models.py:846 msgid "Error printing labels" msgstr "列印標籤時發生錯誤" -#: report/models.py:847 +#: report/models.py:865 msgid "Snippet" msgstr "代碼片段" -#: report/models.py:848 +#: report/models.py:866 msgid "Report snippet file" msgstr "報告代碼片段文件" -#: report/models.py:855 +#: report/models.py:873 msgid "Snippet file description" msgstr "代碼片段文件描述" -#: report/models.py:873 +#: report/models.py:891 msgid "Asset" msgstr "資產" -#: report/models.py:874 +#: report/models.py:892 msgid "Report asset file" msgstr "報告資產文件" -#: report/models.py:881 +#: report/models.py:899 msgid "Asset file description" msgstr "資產文件描述" @@ -8291,23 +8771,23 @@ msgstr "資產文件描述" msgid "User must be authenticated to save report templates" msgstr "使用者必須經過驗證才能儲存報告範本" -#: report/serializers.py:118 +#: report/serializers.py:116 msgid "Select report template" msgstr "選擇報表模板" -#: report/serializers.py:126 report/serializers.py:176 +#: report/serializers.py:124 report/serializers.py:184 msgid "List of item primary keys to include in the report" msgstr "要包含在報告中的項目主鍵列表" -#: report/serializers.py:159 +#: report/serializers.py:167 msgid "Select label template" msgstr "選擇標籤模板" -#: report/serializers.py:167 +#: report/serializers.py:175 msgid "Printing Plugin" msgstr "打印插件" -#: report/serializers.py:168 +#: report/serializers.py:176 msgid "Select plugin to use for label printing" msgstr "選擇用於標籤打印的插件" @@ -8338,13 +8818,10 @@ msgstr "所需材料" #: report/templates/report/inventree_stock_report_merge.html:106 #: report/templates/report/inventree_test_report.html:84 #: report/templates/report/inventree_test_report.html:162 +#: report/templates/report/inventree_transfer_order_report.html:37 msgid "Part image" msgstr "零件圖像" -#: report/templates/report/inventree_build_order_report.html:121 -msgid "Issued" -msgstr "已派發" - #: report/templates/report/inventree_build_order_report.html:146 msgid "Required For" msgstr "需要給" @@ -8380,8 +8857,8 @@ msgstr "總計" #: report/templates/report/inventree_return_order_report.html:25 #: report/templates/report/inventree_sales_order_shipment_report.html:45 #: report/templates/report/inventree_stock_report_merge.html:88 -#: report/templates/report/inventree_test_report.html:88 stock/models.py:1114 -#: stock/serializers.py:164 templates/email/stale_stock_notification.html:21 +#: report/templates/report/inventree_test_report.html:88 stock/models.py:1222 +#: stock/serializers.py:169 templates/email/stale_stock_notification.html:21 msgid "Serial Number" msgstr "序列號" @@ -8405,7 +8882,7 @@ msgstr "庫存項測試報告" #: report/templates/report/inventree_stock_report_merge.html:97 #: report/templates/report/inventree_test_report.html:153 -#: stock/serializers.py:655 +#: stock/serializers.py:662 msgid "Installed Items" msgstr "已安裝的項目" @@ -8438,810 +8915,922 @@ msgstr "無結果 (必填)" msgid "No result" msgstr "沒有結果" -#: report/templatetags/report.py:166 +#: report/templates/report/inventree_transfer_order_report.html:28 +msgid "Transferred" +msgstr "" + +#: report/templatetags/report.py:191 msgid "Invalid media file path" msgstr "無效的媒體檔案路徑" -#: report/templatetags/report.py:185 +#: report/templatetags/report.py:210 msgid "Invalid static file path" msgstr "無效的靜態檔案路徑" -#: report/templatetags/report.py:287 +#: report/templatetags/report.py:312 msgid "Asset file not found" msgstr "找不到資產檔案" -#: report/templatetags/report.py:345 report/templatetags/report.py:461 +#: report/templatetags/report.py:373 report/templatetags/report.py:499 msgid "Image file not found" msgstr "找不到圖片文件" -#: report/templatetags/report.py:430 +#: report/templatetags/report.py:463 msgid "No image file specified" msgstr "未指定影像檔案" -#: report/templatetags/report.py:455 +#: report/templatetags/report.py:493 msgid "part_image tag requires a Part instance" msgstr "parpart_image 標籤需要一個零件實例" -#: report/templatetags/report.py:553 +#: report/templatetags/report.py:585 msgid "company_image tag requires a Company instance" msgstr "公司_圖片標籤需要一個公司實例" -#: stock/api.py:287 +#: stock/api.py:327 msgid "Filter by location depth" msgstr "按位置深度篩選" -#: stock/api.py:307 +#: stock/api.py:347 msgid "Filter by top-level locations" msgstr "按頂級位置篩選" -#: stock/api.py:322 +#: stock/api.py:362 msgid "Include sub-locations in filtered results" msgstr "在篩選結果中包含子地點" -#: stock/api.py:343 stock/serializers.py:1227 +#: stock/api.py:383 stock/serializers.py:1476 msgid "Parent Location" msgstr "上級地點" -#: stock/api.py:344 +#: stock/api.py:384 msgid "Filter by parent location" msgstr "按上級位置篩選" -#: stock/api.py:604 +#: stock/api.py:664 msgid "Part name (case insensitive)" msgstr "零件名稱(不分大小寫)" -#: stock/api.py:610 +#: stock/api.py:670 msgid "Part name contains (case insensitive)" msgstr "零件名稱包含(不分大小寫)" -#: stock/api.py:616 +#: stock/api.py:676 msgid "Part name (regex)" msgstr "零件名稱(正則)" -#: stock/api.py:621 +#: stock/api.py:681 msgid "Part IPN (case insensitive)" msgstr "零件 IPN(不分大小寫)" -#: stock/api.py:627 +#: stock/api.py:687 msgid "Part IPN contains (case insensitive)" msgstr "零件 IPN 包含(不分大小寫)" -#: stock/api.py:633 +#: stock/api.py:693 msgid "Part IPN (regex)" msgstr "零件 IPN(正則)" -#: stock/api.py:645 +#: stock/api.py:705 msgid "Minimum stock" msgstr "最小庫存" -#: stock/api.py:649 +#: stock/api.py:709 msgid "Maximum stock" msgstr "最大庫存" -#: stock/api.py:652 +#: stock/api.py:712 msgid "Status Code" msgstr "狀態代碼" -#: stock/api.py:692 +#: stock/api.py:756 msgid "External Location" msgstr "外部地點" -#: stock/api.py:791 +#: stock/api.py:855 msgid "Consumed by Build Order" msgstr "被生產工單消耗" -#: stock/api.py:801 +#: stock/api.py:865 msgid "Installed in other stock item" msgstr "已安裝於其他庫存項" -#: stock/api.py:890 +#: stock/api.py:945 msgid "Part Tree" msgstr "零件樹" -#: stock/api.py:912 +#: stock/api.py:974 msgid "Updated before" msgstr "更新時間早於" -#: stock/api.py:916 +#: stock/api.py:978 msgid "Updated after" msgstr "更新時間晚於" -#: stock/api.py:920 +#: stock/api.py:982 msgid "Stocktake Before" msgstr "盤點日期早於" -#: stock/api.py:924 +#: stock/api.py:986 msgid "Stocktake After" msgstr "盤點日期晚於" -#: stock/api.py:929 +#: stock/api.py:990 +msgid "Has Stocktake Date" +msgstr "" + +#: stock/api.py:1001 msgid "Expiry date before" msgstr "過期日期前" -#: stock/api.py:933 +#: stock/api.py:1005 msgid "Expiry date after" msgstr "過期日期後" -#: stock/api.py:936 stock/serializers.py:660 +#: stock/api.py:1008 stock/serializers.py:667 msgid "Stale" msgstr "過期" -#: stock/api.py:962 -msgid "Provide a StockItem PK to exclude that item and all its descendants" -msgstr "提供一個 StockItem PK 以排除該項目及其所有子項目" - -#: stock/api.py:980 +#: stock/api.py:1032 msgid "Cascade Locations" msgstr "級聯位置" -#: stock/api.py:981 +#: stock/api.py:1033 msgid "If true, include items in child locations of the given location" msgstr "若為 true,則包含給定位置的子位置中的項目" -#: stock/api.py:987 +#: stock/api.py:1039 msgid "Filter by numeric Location ID or the literal 'null'" msgstr "依數字位置 ID 或常值 'null' 篩選" -#: stock/api.py:1087 +#: stock/api.py:1141 msgid "Quantity is required" msgstr "請先輸入數量" -#: stock/api.py:1092 +#: stock/api.py:1146 msgid "Valid part must be supplied" msgstr "必須提供有效的零件" -#: stock/api.py:1123 +#: stock/api.py:1177 msgid "The given supplier part does not exist" msgstr "給定的供應商零件不存在" -#: stock/api.py:1133 +#: stock/api.py:1187 msgid "The supplier part has a pack size defined, but flag use_pack_size not set" msgstr "供應商零件有定義的包裝大小,但 use_pack_size 標誌未設置" -#: stock/api.py:1165 +#: stock/api.py:1219 msgid "Serial numbers cannot be supplied for a non-trackable part" msgstr "不能為不可跟蹤的零件提供序列號" -#: stock/api.py:1409 +#: stock/api.py:1464 msgid "Include Installed" msgstr "包含已安裝" -#: stock/api.py:1411 +#: stock/api.py:1466 msgid "If true, include test results for items installed underneath the given stock item" msgstr "若為 true,則包含安裝在給定庫存項目下方的項目的測試結果" -#: stock/api.py:1418 +#: stock/api.py:1473 msgid "Filter by numeric Stock Item ID" msgstr "使用數字庫存品項 ID 做過濾" -#: stock/api.py:1439 +#: stock/api.py:1494 #, python-brace-format msgid "Stock item with ID {id} does not exist" msgstr "庫存品項 ID {id} 不存在" -#: stock/api.py:1516 +#: stock/api.py:1568 msgid "Include Part Variants" msgstr "包括零件變數" -#: stock/api.py:1546 +#: stock/api.py:1598 msgid "Date after" msgstr "日前之後" -#: stock/api.py:1550 +#: stock/api.py:1602 msgid "Date before" msgstr "日期之前" -#: stock/models.py:73 +#: stock/models.py:76 msgid "Stock Location type" msgstr "庫存地點類型" -#: stock/models.py:74 +#: stock/models.py:77 msgid "Stock Location types" msgstr "庫存地點類型" -#: stock/models.py:100 +#: stock/models.py:103 msgid "Default icon for all locations that have no icon set (optional)" msgstr "為所有沒有圖標的位置設置默認圖標(可選)" -#: stock/models.py:147 stock/models.py:1076 +#: stock/models.py:151 stock/models.py:1184 msgid "Stock Location" msgstr "庫存地點" -#: stock/models.py:148 users/ruleset.py:31 +#: stock/models.py:152 users/ruleset.py:32 msgid "Stock Locations" msgstr "庫存地點" -#: stock/models.py:197 stock/models.py:1241 +#: stock/models.py:199 stock/models.py:1356 msgid "Owner" msgstr "所有者" -#: stock/models.py:198 stock/models.py:1242 +#: stock/models.py:200 stock/models.py:1357 msgid "Select Owner" msgstr "選擇所有者" -#: stock/models.py:206 +#: stock/models.py:208 msgid "Stock items may not be directly located into a structural stock locations, but may be located to child locations." msgstr "庫存項可能不直接位於結構庫存地點,但可能位於其子地點。" -#: stock/models.py:213 users/models.py:495 +#: stock/models.py:215 users/models.py:493 msgid "External" msgstr "外部" -#: stock/models.py:214 +#: stock/models.py:216 msgid "This is an external stock location" msgstr "這是一個外部庫存地點" -#: stock/models.py:220 +#: stock/models.py:222 msgid "Location type" msgstr "位置類型" -#: stock/models.py:224 +#: stock/models.py:226 msgid "Stock location type of this location" msgstr "該位置的庫存地點類型" -#: stock/models.py:296 +#: stock/models.py:299 msgid "You cannot make this stock location structural because some stock items are already located into it!" msgstr "您不能將此庫存地點設置為結構性,因為某些庫存項已經位於它!" -#: stock/models.py:537 +#: stock/models.py:416 +msgid "Oldest stock first (FIFO)" +msgstr "" + +#: stock/models.py:417 +msgid "Newest stock first (LIFO)" +msgstr "" + +#: stock/models.py:418 +msgid "Smallest quantity first" +msgstr "" + +#: stock/models.py:419 +msgid "Largest quantity first" +msgstr "" + +#: stock/models.py:420 +msgid "Soonest expiry date first" +msgstr "" + +#: stock/models.py:582 msgid "Serialized stock items cannot be deleted" msgstr "" -#: stock/models.py:674 +#: stock/models.py:791 #, python-brace-format msgid "{field} does not exist" msgstr "{field} 不存在" -#: stock/models.py:687 +#: stock/models.py:804 msgid "Part must be specified" msgstr "必須指定零件" -#: stock/models.py:924 +#: stock/models.py:1024 msgid "Stock items cannot be located into structural stock locations!" msgstr "庫存項不能存放在結構性庫存地點!" -#: stock/models.py:945 +#: stock/models.py:1053 msgid "Editing of serial numbers is not allowed - this item has already been assigned a serial number" msgstr "" -#: stock/models.py:962 stock/serializers.py:469 +#: stock/models.py:1070 stock/serializers.py:478 msgid "Stock item cannot be created for virtual parts" msgstr "無法為虛擬零件創建庫存項" -#: stock/models.py:979 +#: stock/models.py:1087 #, python-brace-format msgid "Part type ('{self.supplier_part.part}') must be {self.part}" msgstr "零件類型 ('{self.supplier_part.part}') 必須為 {self.part}" -#: stock/models.py:989 stock/models.py:1002 +#: stock/models.py:1097 stock/models.py:1110 msgid "Quantity must be 1 for item with a serial number" msgstr "有序列號的項目的數量必須是1" -#: stock/models.py:992 +#: stock/models.py:1100 msgid "Serial number cannot be set if quantity greater than 1" msgstr "如果數量大於1,則不能設置序列號" -#: stock/models.py:1014 +#: stock/models.py:1122 msgid "Item cannot belong to itself" msgstr "項目不能屬於其自身" -#: stock/models.py:1019 +#: stock/models.py:1127 msgid "Item must have a build reference if is_building=True" msgstr "如果is_building=True,則項必須具有構建引用" -#: stock/models.py:1032 +#: stock/models.py:1140 msgid "Build reference does not point to the same part object" msgstr "構建引用未指向同一零件對象" -#: stock/models.py:1046 +#: stock/models.py:1154 msgid "Parent Stock Item" msgstr "母庫存項目" -#: stock/models.py:1058 +#: stock/models.py:1166 msgid "Base part" msgstr "基礎零件" -#: stock/models.py:1068 +#: stock/models.py:1176 msgid "Select a matching supplier part for this stock item" msgstr "為此庫存項目選擇匹配的供應商零件" -#: stock/models.py:1080 +#: stock/models.py:1188 msgid "Where is this stock item located?" msgstr "這個庫存物品在哪裏?" -#: stock/models.py:1088 stock/serializers.py:1682 +#: stock/models.py:1196 stock/serializers.py:1936 msgid "Packaging this stock item is stored in" msgstr "包裝此庫存物品存儲在" -#: stock/models.py:1094 +#: stock/models.py:1202 msgid "Installed In" msgstr "安裝於" -#: stock/models.py:1099 +#: stock/models.py:1207 msgid "Is this item installed in another item?" msgstr "此項目是否安裝在另一個項目中?" -#: stock/models.py:1118 +#: stock/models.py:1226 msgid "Serial number for this item" msgstr "此項目的序列號" -#: stock/models.py:1135 stock/serializers.py:1667 +#: stock/models.py:1243 stock/serializers.py:1921 msgid "Batch code for this stock item" msgstr "此庫存項的批號" -#: stock/models.py:1140 +#: stock/models.py:1248 msgid "Stock Quantity" msgstr "庫存數量" -#: stock/models.py:1150 +#: stock/models.py:1258 msgid "Source Build" msgstr "源代碼構建" -#: stock/models.py:1153 +#: stock/models.py:1261 msgid "Build for this stock item" msgstr "為此庫存項目構建" -#: stock/models.py:1160 +#: stock/models.py:1268 msgid "Consumed By" msgstr "消費者" -#: stock/models.py:1163 +#: stock/models.py:1271 msgid "Build order which consumed this stock item" msgstr "構建消耗此庫存項的生產訂單" -#: stock/models.py:1172 +#: stock/models.py:1280 msgid "Source Purchase Order" msgstr "採購訂單來源" -#: stock/models.py:1176 +#: stock/models.py:1284 msgid "Purchase order for this stock item" msgstr "此庫存商品的採購訂單" -#: stock/models.py:1182 +#: stock/models.py:1290 msgid "Destination Sales Order" msgstr "目的地銷售訂單" -#: stock/models.py:1193 +#: stock/models.py:1301 msgid "Expiry date for stock item. Stock will be considered expired after this date" msgstr "庫存物品的到期日。在此日期之後,庫存將被視為過期" -#: stock/models.py:1211 +#: stock/models.py:1321 +msgid "Date that this stock item was created" +msgstr "" + +#: stock/models.py:1326 msgid "Delete on deplete" msgstr "耗盡時刪除" -#: stock/models.py:1212 +#: stock/models.py:1327 msgid "Delete this Stock Item when stock is depleted" msgstr "當庫存耗盡時刪除此庫存項" -#: stock/models.py:1233 +#: stock/models.py:1348 msgid "Single unit purchase price at time of purchase" msgstr "購買時一個單位的價格" -#: stock/models.py:1264 +#: stock/models.py:1379 msgid "Converted to part" msgstr "轉換為零件" -#: stock/models.py:1466 +#: stock/models.py:1593 msgid "Quantity exceeds available stock" msgstr "數量超過可用庫存" -#: stock/models.py:1917 +#: stock/models.py:1903 +msgid "Invalid quantity value" +msgstr "" + +#: stock/models.py:1966 stock/models.py:2478 +msgid "Cannot assign stock to structural location" +msgstr "無法將庫存分配到結構位置" + +#: stock/models.py:2125 stock/serializers.py:1096 +msgid "Quantity must not exceed available stock quantity" +msgstr "" + +#: stock/models.py:2131 +msgid "Serialized stock item must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2136 +msgid "No BOM lines provided" +msgstr "" + +#: stock/models.py:2145 +msgid "Stock item with installed items must be disassembled in its entirety" +msgstr "" + +#: stock/models.py:2431 msgid "Part is not set as trackable" msgstr "零件未設置為可跟蹤" -#: stock/models.py:1923 +#: stock/models.py:2437 msgid "Quantity must be integer" msgstr "數量必須是整數" -#: stock/models.py:1931 +#: stock/models.py:2449 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({self.quantity})" msgstr "數量不得超過現有庫存量 ({self.quantity})" -#: stock/models.py:1937 +#: stock/models.py:2455 msgid "Serial numbers must be provided as a list" msgstr "序列號需以清單提供" -#: stock/models.py:1942 +#: stock/models.py:2460 msgid "Quantity does not match serial numbers" msgstr "數量不匹配序列號" -#: stock/models.py:1960 -msgid "Cannot assign stock to structural location" -msgstr "無法將庫存分配到結構位置" - -#: stock/models.py:2077 stock/models.py:3047 +#: stock/models.py:2606 stock/models.py:3851 msgid "Test template does not exist" msgstr "測試模板不存在" -#: stock/models.py:2095 +#: stock/models.py:2624 msgid "Stock item has been assigned to a sales order" msgstr "庫存項已分配到銷售訂單" -#: stock/models.py:2099 +#: stock/models.py:2628 msgid "Stock item is installed in another item" msgstr "庫存項已安裝在另一個項目中" -#: stock/models.py:2102 +#: stock/models.py:2631 msgid "Stock item contains other items" msgstr "庫存項包含其他項目" -#: stock/models.py:2105 +#: stock/models.py:2634 msgid "Stock item has been assigned to a customer" msgstr "庫存項已分配給客户" -#: stock/models.py:2108 stock/models.py:2294 +#: stock/models.py:2637 stock/models.py:2888 msgid "Stock item is currently in production" msgstr "庫存項目前正在生產" -#: stock/models.py:2111 +#: stock/models.py:2640 msgid "Serialized stock cannot be merged" msgstr "序列化的庫存不能合併" -#: stock/models.py:2118 stock/serializers.py:1537 +#: stock/models.py:2647 stock/serializers.py:1790 msgid "Duplicate stock items" msgstr "複製庫存項" -#: stock/models.py:2122 +#: stock/models.py:2651 msgid "Stock items must refer to the same part" msgstr "庫存項必須指相同零件" -#: stock/models.py:2130 +#: stock/models.py:2659 msgid "Stock items must refer to the same supplier part" msgstr "庫存項必須是同一供應商的零件" -#: stock/models.py:2135 +#: stock/models.py:2664 msgid "Stock status codes must match" msgstr "庫存狀態碼必須匹配" -#: stock/models.py:2435 +#: stock/models.py:3092 msgid "StockItem cannot be moved as it is not in stock" msgstr "庫存項不能移動,因為它沒有庫存" -#: stock/models.py:2929 +#: stock/models.py:3731 msgid "Stock Item Tracking" msgstr "庫存項跟蹤" -#: stock/models.py:2979 +#: stock/models.py:3781 msgid "Entry notes" msgstr "條目註釋" -#: stock/models.py:3019 +#: stock/models.py:3821 msgid "Stock Item Test Result" msgstr "庫存項測試結果" -#: stock/models.py:3050 +#: stock/models.py:3854 msgid "Value must be provided for this test" msgstr "必須為此測試提供值" -#: stock/models.py:3054 +#: stock/models.py:3858 msgid "Attachment must be uploaded for this test" msgstr "測試附件必須上傳" -#: stock/models.py:3059 +#: stock/models.py:3863 msgid "Invalid value for this test" msgstr "此測試的值無效" -#: stock/models.py:3083 +#: stock/models.py:3887 msgid "Test result" msgstr "測試結果" -#: stock/models.py:3090 +#: stock/models.py:3894 msgid "Test output value" msgstr "測試輸出值" -#: stock/models.py:3098 stock/serializers.py:259 +#: stock/models.py:3902 stock/serializers.py:264 msgid "Test result attachment" msgstr "測驗結果附件" -#: stock/models.py:3102 +#: stock/models.py:3906 msgid "Test notes" msgstr "測試備註" -#: stock/models.py:3110 +#: stock/models.py:3914 msgid "Test station" msgstr "測試站" -#: stock/models.py:3111 +#: stock/models.py:3915 msgid "The identifier of the test station where the test was performed" msgstr "進行測試的測試站的標識符" -#: stock/models.py:3117 +#: stock/models.py:3921 msgid "Started" msgstr "已開始" -#: stock/models.py:3118 +#: stock/models.py:3922 msgid "The timestamp of the test start" msgstr "測試開始的時間戳" -#: stock/models.py:3124 +#: stock/models.py:3928 msgid "Finished" msgstr "已完成" -#: stock/models.py:3125 +#: stock/models.py:3929 msgid "The timestamp of the test finish" msgstr "測試結束的時間戳" -#: stock/serializers.py:85 +#: stock/serializers.py:90 msgid "Generated batch code" msgstr "生成批量代碼" -#: stock/serializers.py:94 +#: stock/serializers.py:99 msgid "Select build order" msgstr "選擇生產訂單" -#: stock/serializers.py:103 +#: stock/serializers.py:108 msgid "Select stock item to generate batch code for" msgstr "選擇要生成批量代碼的庫存項" -#: stock/serializers.py:112 +#: stock/serializers.py:117 msgid "Select location to generate batch code for" msgstr "選擇要生成批量代碼的位置" -#: stock/serializers.py:121 +#: stock/serializers.py:126 msgid "Select part to generate batch code for" msgstr "選擇要生成批量代碼的零件" -#: stock/serializers.py:130 +#: stock/serializers.py:135 msgid "Select purchase order" msgstr "選擇採購訂單" -#: stock/serializers.py:137 +#: stock/serializers.py:142 msgid "Enter quantity for batch code" msgstr "輸入批量代碼的數量" -#: stock/serializers.py:163 +#: stock/serializers.py:168 msgid "Generated serial number" msgstr "生成的序列號" -#: stock/serializers.py:173 +#: stock/serializers.py:178 msgid "Select part to generate serial number for" msgstr "選擇要生成序列號的零件" -#: stock/serializers.py:181 +#: stock/serializers.py:186 msgid "Quantity of serial numbers to generate" msgstr "要生成的序列號的數量" -#: stock/serializers.py:246 +#: stock/serializers.py:251 msgid "Test template for this result" msgstr "此結果的測試模板" -#: stock/serializers.py:289 +#: stock/serializers.py:294 msgid "No matching test found for this part" msgstr "未找到與此零件相符的測試" -#: stock/serializers.py:293 +#: stock/serializers.py:298 msgid "Template ID or test name must be provided" msgstr "必須提供模板 ID 或測試名稱" -#: stock/serializers.py:303 +#: stock/serializers.py:308 msgid "The test finished time cannot be earlier than the test started time" msgstr "測試完成時間不能早於測試開始時間" -#: stock/serializers.py:427 +#: stock/serializers.py:436 msgid "Parent Item" msgstr "父項" -#: stock/serializers.py:428 +#: stock/serializers.py:437 msgid "Parent stock item" msgstr "父庫存項" -#: stock/serializers.py:454 +#: stock/serializers.py:463 msgid "Use pack size when adding: the quantity defined is the number of packs" msgstr "添加時使用包裝尺寸:定義的數量是包裝的數量" -#: stock/serializers.py:456 +#: stock/serializers.py:465 msgid "Use pack size" msgstr "使用包裝數" -#: stock/serializers.py:463 stock/serializers.py:729 +#: stock/serializers.py:472 stock/serializers.py:736 msgid "Enter serial numbers for new items" msgstr "輸入新項目的序列號" -#: stock/serializers.py:571 +#: stock/serializers.py:578 msgid "Supplier Part Number" msgstr "供應商零件編號" -#: stock/serializers.py:652 users/models.py:185 +#: stock/serializers.py:659 users/models.py:183 msgid "Expired" msgstr "已過期" -#: stock/serializers.py:658 +#: stock/serializers.py:665 msgid "Child Items" msgstr "子項目" -#: stock/serializers.py:662 +#: stock/serializers.py:669 msgid "Tracking Items" msgstr "跟蹤項目" -#: stock/serializers.py:668 +#: stock/serializers.py:675 msgid "Purchase price of this stock item, per unit or pack" msgstr "此庫存商品的購買價格,單位或包裝" -#: stock/serializers.py:706 +#: stock/serializers.py:713 msgid "Enter number of stock items to serialize" msgstr "輸入要序列化的庫存項目數量" -#: stock/serializers.py:714 stock/serializers.py:757 stock/serializers.py:795 -#: stock/serializers.py:933 +#: stock/serializers.py:721 stock/serializers.py:764 stock/serializers.py:802 +#: stock/serializers.py:955 stock/serializers.py:1089 stock/serializers.py:1130 msgid "No stock item provided" msgstr "未提供庫存項" -#: stock/serializers.py:722 +#: stock/serializers.py:729 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({q})" msgstr "數量不得超過現有庫存量 ({q})" -#: stock/serializers.py:740 stock/serializers.py:1494 stock/serializers.py:1815 -#: stock/serializers.py:1864 +#: stock/serializers.py:747 stock/serializers.py:1747 stock/serializers.py:2148 +#: stock/serializers.py:2257 msgid "Destination stock location" msgstr "目標庫存位置" -#: stock/serializers.py:760 +#: stock/serializers.py:767 msgid "Serial numbers cannot be assigned to this part" msgstr "此零件不能分配序列號" -#: stock/serializers.py:780 +#: stock/serializers.py:787 msgid "Serial numbers already exist" msgstr "序列號已存在" -#: stock/serializers.py:830 +#: stock/serializers.py:843 msgid "Select stock item to install" msgstr "選擇要安裝的庫存項目" -#: stock/serializers.py:837 +#: stock/serializers.py:850 msgid "Quantity to Install" msgstr "安裝數量" -#: stock/serializers.py:838 +#: stock/serializers.py:851 msgid "Enter the quantity of items to install" msgstr "輸入要安裝的項目數量" -#: stock/serializers.py:843 stock/serializers.py:923 stock/serializers.py:1065 +#: stock/serializers.py:856 stock/serializers.py:936 stock/serializers.py:1281 msgid "Add transaction note (optional)" msgstr "添加交易記錄 (可選)" -#: stock/serializers.py:851 +#: stock/serializers.py:864 msgid "Quantity to install must be at least 1" msgstr "安裝數量必須至少為1" -#: stock/serializers.py:859 +#: stock/serializers.py:872 stock/serializers.py:1133 msgid "Stock item is unavailable" msgstr "庫存項不可用" -#: stock/serializers.py:870 +#: stock/serializers.py:883 msgid "Selected part is not in the Bill of Materials" msgstr "所選零件不在物料清單中" -#: stock/serializers.py:883 +#: stock/serializers.py:896 msgid "Quantity to install must not exceed available quantity" msgstr "安裝數量不得超過可用數量" -#: stock/serializers.py:918 +#: stock/serializers.py:931 msgid "Destination location for uninstalled item" msgstr "已卸載項目的目標位置" -#: stock/serializers.py:956 -msgid "Select part to convert stock item into" -msgstr "選擇要將庫存項目轉換為的零件" - -#: stock/serializers.py:969 -msgid "Selected part is not a valid option for conversion" -msgstr "所選零件不是有效的轉換選項" - -#: stock/serializers.py:986 -msgid "Cannot convert stock item with assigned SupplierPart" -msgstr "無法轉換已分配供應商零件的庫存項" - -#: stock/serializers.py:1020 +#: stock/serializers.py:979 msgid "Stock item status code" msgstr "庫存項狀態代碼" -#: stock/serializers.py:1049 +#: stock/serializers.py:1015 +msgid "BOM line which defines the component part to break out" +msgstr "" + +#: stock/serializers.py:1024 +msgid "Quantity of the component part to create" +msgstr "" + +#: stock/serializers.py:1040 +msgid "Destination location for the component items" +msgstr "" + +#: stock/serializers.py:1044 +msgid "Status code for the component items" +msgstr "" + +#: stock/serializers.py:1053 +msgid "Unit purchase price for the component items (leave blank for automatic cost allocation)" +msgstr "" + +#: stock/serializers.py:1081 +msgid "Number of assemblies to disassemble" +msgstr "" + +#: stock/serializers.py:1108 +msgid "Default destination location for the component items" +msgstr "" + +#: stock/serializers.py:1154 +msgid "BOM item is not valid for the selected stock item" +msgstr "" + +#: stock/serializers.py:1158 +msgid "Duplicate BOM items provided" +msgstr "" + +#: stock/serializers.py:1199 +msgid "Select part to convert stock item into" +msgstr "選擇要將庫存項目轉換為的零件" + +#: stock/serializers.py:1212 +msgid "Selected part is not a valid option for conversion" +msgstr "所選零件不是有效的轉換選項" + +#: stock/serializers.py:1229 +msgid "Cannot convert stock item with assigned SupplierPart" +msgstr "無法轉換已分配供應商零件的庫存項" + +#: stock/serializers.py:1265 msgid "Select stock items to change status" msgstr "選擇要更改狀態的庫存項目" -#: stock/serializers.py:1055 +#: stock/serializers.py:1271 msgid "No stock items selected" msgstr "未選擇庫存商品" -#: stock/serializers.py:1162 stock/serializers.py:1233 +#: stock/serializers.py:1389 stock/serializers.py:1482 msgid "Sublocations" msgstr "轉租" -#: stock/serializers.py:1228 +#: stock/serializers.py:1407 +msgid "Delete Stock Items" +msgstr "" + +#: stock/serializers.py:1408 +msgid "Delete all stock items contained within this location" +msgstr "" + +#: stock/serializers.py:1413 +msgid "Delete Sublocations" +msgstr "" + +#: stock/serializers.py:1414 +msgid "Delete all sub-locations contained within this location" +msgstr "" + +#: stock/serializers.py:1477 msgid "Parent stock location" msgstr "上級庫存地點" -#: stock/serializers.py:1366 +#: stock/serializers.py:1615 msgid "Part must be salable" msgstr "零件必須可銷售" -#: stock/serializers.py:1370 +#: stock/serializers.py:1619 msgid "Item is allocated to a sales order" msgstr "物料已分配到銷售訂單" -#: stock/serializers.py:1374 +#: stock/serializers.py:1623 +msgid "Item is allocated to a transfer order" +msgstr "" + +#: stock/serializers.py:1627 msgid "Item is allocated to a build order" msgstr "項目被分配到生產訂單中" -#: stock/serializers.py:1398 +#: stock/serializers.py:1651 msgid "Customer to assign stock items" msgstr "客户分配庫存項目" -#: stock/serializers.py:1404 +#: stock/serializers.py:1657 msgid "Selected company is not a customer" msgstr "所選公司不是客户" -#: stock/serializers.py:1412 +#: stock/serializers.py:1665 msgid "Stock assignment notes" msgstr "庫存分配説明" -#: stock/serializers.py:1422 stock/serializers.py:1710 +#: stock/serializers.py:1675 stock/serializers.py:1997 msgid "A list of stock items must be provided" msgstr "必須提供庫存物品清單" -#: stock/serializers.py:1501 +#: stock/serializers.py:1754 msgid "Stock merging notes" msgstr "庫存合併説明" -#: stock/serializers.py:1506 +#: stock/serializers.py:1759 msgid "Allow mismatched suppliers" msgstr "允許不匹配的供應商" -#: stock/serializers.py:1507 +#: stock/serializers.py:1760 msgid "Allow stock items with different supplier parts to be merged" msgstr "允許合併具有不同供應商零件的庫存項目" -#: stock/serializers.py:1512 +#: stock/serializers.py:1765 msgid "Allow mismatched status" msgstr "允許不匹配的狀態" -#: stock/serializers.py:1513 +#: stock/serializers.py:1766 msgid "Allow stock items with different status codes to be merged" msgstr "允許合併具有不同狀態代碼的庫存項目" -#: stock/serializers.py:1523 +#: stock/serializers.py:1776 msgid "At least two stock items must be provided" msgstr "必須提供至少兩件庫存物品" -#: stock/serializers.py:1590 +#: stock/serializers.py:1843 msgid "No Change" msgstr "無更改" -#: stock/serializers.py:1628 +#: stock/serializers.py:1882 msgid "StockItem primary key value" msgstr "庫存項主鍵值" -#: stock/serializers.py:1641 +#: stock/serializers.py:1895 msgid "Stock item is not in stock" msgstr "庫存項無庫存" -#: stock/serializers.py:1644 +#: stock/serializers.py:1898 msgid "Stock item is already in stock" msgstr "庫存項已在庫" -#: stock/serializers.py:1658 +#: stock/serializers.py:1912 msgid "Quantity must not be negative" msgstr "數量不可為負" -#: stock/serializers.py:1700 -msgid "Stock transaction notes" -msgstr "庫存交易記錄" - -#: stock/serializers.py:1870 +#: stock/serializers.py:1942 stock/serializers.py:2272 msgid "Merge into existing stock" msgstr "合併至現有庫存" -#: stock/serializers.py:1871 +#: stock/serializers.py:1944 +msgid "Merge this item into existing stock at the destination if possible" +msgstr "" + +#: stock/serializers.py:1963 +msgid "Stock transaction notes" +msgstr "庫存交易記錄" + +#: stock/serializers.py:2020 +msgid "Set stock location for counted items (optional)" +msgstr "" + +#: stock/serializers.py:2273 msgid "Merge returned items into existing stock items if possible" msgstr "可行時將退回項目併入現有庫存" -#: stock/serializers.py:1914 +#: stock/serializers.py:2316 msgid "Next Serial Number" msgstr "下一個序列號" -#: stock/serializers.py:1920 +#: stock/serializers.py:2322 msgid "Previous Serial Number" msgstr "上一個序列號" @@ -9342,42 +9931,50 @@ msgid "Merged stock items" msgstr "合併的庫存項" #: stock/status_codes.py:79 +msgid "Disassembled into components" +msgstr "" + +#: stock/status_codes.py:80 +msgid "Created from disassembly" +msgstr "" + +#: stock/status_codes.py:83 msgid "Converted to variant" msgstr "轉換為變體" -#: stock/status_codes.py:82 +#: stock/status_codes.py:86 msgid "Build order output created" msgstr "已創建生產訂單產出" -#: stock/status_codes.py:83 +#: stock/status_codes.py:87 msgid "Build order output completed" msgstr "生產訂單已出產" -#: stock/status_codes.py:84 +#: stock/status_codes.py:88 msgid "Build order output rejected" msgstr "生產訂單產出被拒絕" -#: stock/status_codes.py:85 +#: stock/status_codes.py:89 msgid "Consumed by build order" msgstr "被工單消耗的" -#: stock/status_codes.py:88 +#: stock/status_codes.py:92 msgid "Shipped against Sales Order" msgstr "按銷售訂單出貨" -#: stock/status_codes.py:91 +#: stock/status_codes.py:95 msgid "Received against Purchase Order" msgstr "按採購訂單接收" -#: stock/status_codes.py:94 +#: stock/status_codes.py:98 msgid "Returned against Return Order" msgstr "按退貨訂單退回" -#: stock/status_codes.py:97 +#: stock/status_codes.py:101 msgid "Sent to customer" msgstr "寄送給客户" -#: stock/status_codes.py:98 +#: stock/status_codes.py:102 msgid "Returned from customer" msgstr "從客户端退回" @@ -9527,19 +10124,19 @@ msgstr "用户" msgid "Select which users are assigned to this group" msgstr "選擇分配給此組的用户" -#: users/admin.py:137 +#: users/admin.py:136 msgid "Personal info" msgstr "個人信息" -#: users/admin.py:139 +#: users/admin.py:138 msgid "Permissions" msgstr "權限" -#: users/admin.py:142 +#: users/admin.py:141 msgid "Important dates" msgstr "重要日期" -#: users/authentication.py:30 users/models.py:151 +#: users/authentication.py:30 users/models.py:149 msgid "Token has been revoked" msgstr "令牌已被撤銷" @@ -9547,279 +10144,283 @@ msgstr "令牌已被撤銷" msgid "Token has expired" msgstr "令牌已過期" -#: users/models.py:94 +#: users/models.py:92 msgid "API Token" msgstr "API 令牌" -#: users/models.py:95 +#: users/models.py:93 msgid "API Tokens" msgstr "API 令牌" -#: users/models.py:131 +#: users/models.py:129 msgid "Token Name" msgstr "令牌名稱" -#: users/models.py:132 +#: users/models.py:130 msgid "Custom token name" msgstr "自定義令牌名稱" -#: users/models.py:138 +#: users/models.py:136 msgid "Token expiry date" msgstr "令牌過期日期" -#: users/models.py:146 +#: users/models.py:144 msgid "Last Seen" msgstr "最近一次在線" -#: users/models.py:147 +#: users/models.py:145 msgid "Last time the token was used" msgstr "最近使用令牌的時間" -#: users/models.py:151 +#: users/models.py:149 msgid "Revoked" msgstr "撤銷" -#: users/models.py:227 +#: users/models.py:225 msgid "Permission set" msgstr "權限設置" -#: users/models.py:240 +#: users/models.py:238 msgid "View" msgstr "查看" -#: users/models.py:240 +#: users/models.py:238 msgid "Permission to view items" msgstr "查看項目的權限" -#: users/models.py:244 +#: users/models.py:242 msgid "Add" msgstr "添加" -#: users/models.py:244 +#: users/models.py:242 msgid "Permission to add items" msgstr "添加項目的權限" -#: users/models.py:248 +#: users/models.py:246 msgid "Change" msgstr "更改" -#: users/models.py:250 +#: users/models.py:248 msgid "Permissions to edit items" msgstr "編輯項目的權限" -#: users/models.py:254 +#: users/models.py:252 msgid "Delete" msgstr "刪除" -#: users/models.py:256 +#: users/models.py:254 msgid "Permission to delete items" msgstr "刪除項目的權限" -#: users/models.py:493 +#: users/models.py:491 msgid "Bot" msgstr "機器人" -#: users/models.py:494 +#: users/models.py:492 msgid "Internal" msgstr "內部" -#: users/models.py:496 +#: users/models.py:494 msgid "Guest" msgstr "訪客" -#: users/models.py:505 +#: users/models.py:503 msgid "Language" msgstr "語言 LANG" -#: users/models.py:506 +#: users/models.py:504 msgid "Preferred language for the user" msgstr "使用者偏好語言" -#: users/models.py:511 +#: users/models.py:509 msgid "Theme" msgstr "主題" -#: users/models.py:512 +#: users/models.py:510 msgid "Settings for the web UI as JSON - do not edit manually!" msgstr "Web 介面設定(JSON,請勿手動編輯)" -#: users/models.py:517 +#: users/models.py:515 msgid "Widgets" msgstr "小工具" -#: users/models.py:519 +#: users/models.py:517 msgid "Settings for the dashboard widgets as JSON - do not edit manually!" msgstr "儀表板小工具設定(JSON,請勿手動編輯)" -#: users/models.py:526 +#: users/models.py:524 msgid "Display Name" msgstr "顯示名稱" -#: users/models.py:527 +#: users/models.py:525 msgid "Chosen display name for the user" msgstr "使用者自選顯示名稱" -#: users/models.py:533 +#: users/models.py:531 msgid "Position" msgstr "職稱" -#: users/models.py:534 +#: users/models.py:532 msgid "Main job title or position" msgstr "主要職稱或職位" -#: users/models.py:541 +#: users/models.py:539 msgid "User status message" msgstr "使用者狀態訊息" -#: users/models.py:548 +#: users/models.py:546 msgid "User location information" msgstr "使用者位置資訊" -#: users/models.py:553 +#: users/models.py:551 msgid "User is actively using the system" msgstr "使用者目前活躍" -#: users/models.py:560 +#: users/models.py:558 msgid "Preferred contact information for the user" msgstr "使用者偏好聯絡資訊" -#: users/models.py:566 +#: users/models.py:564 msgid "User Type" msgstr "使用者類型" -#: users/models.py:567 +#: users/models.py:565 msgid "Which type of user is this?" msgstr "此為哪種類型的使用者?" -#: users/models.py:573 +#: users/models.py:571 msgid "Organisation" msgstr "組織" -#: users/models.py:574 +#: users/models.py:572 msgid "Users primary organisation/affiliation" msgstr "使用者主要所屬組織" -#: users/models.py:582 +#: users/models.py:580 msgid "Primary Group" msgstr "主要群組" -#: users/models.py:583 +#: users/models.py:581 msgid "Primary group for the user" msgstr "使用者的主要群組" -#: users/ruleset.py:27 +#: users/ruleset.py:28 msgid "Admin" msgstr "管理員" -#: users/ruleset.py:30 +#: users/ruleset.py:31 msgid "Bills of Material" msgstr "" -#: users/ruleset.py:34 +#: users/ruleset.py:35 msgid "Purchase Orders" msgstr "採購訂單" -#: users/ruleset.py:35 +#: users/ruleset.py:36 msgid "Sales Orders" msgstr "銷售訂單" -#: users/ruleset.py:36 +#: users/ruleset.py:37 msgid "Return Orders" msgstr "退貨訂單" -#: users/serializers.py:186 +#: users/ruleset.py:38 +msgid "Transfer Orders" +msgstr "" + +#: users/serializers.py:196 msgid "Username" msgstr "用户名" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First Name" msgstr "名" -#: users/serializers.py:189 +#: users/serializers.py:199 msgid "First name of the user" msgstr "用户的名字(不包括姓氏)" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last Name" msgstr "姓" -#: users/serializers.py:193 +#: users/serializers.py:203 msgid "Last name of the user" msgstr "用户的姓氏" -#: users/serializers.py:197 +#: users/serializers.py:207 msgid "Email address of the user" msgstr "用户的電子郵件地址" -#: users/serializers.py:240 +#: users/serializers.py:250 msgid "User must be authenticated" msgstr "使用者必須經過驗證" -#: users/serializers.py:249 +#: users/serializers.py:259 msgid "Only a superuser can create a token for another user" msgstr "只有超級使用者可以為其他使用者建立權杖" -#: users/serializers.py:329 +#: users/serializers.py:339 msgid "Administrator" msgstr "管理員" -#: users/serializers.py:330 +#: users/serializers.py:340 msgid "Does this user have administrative permissions" msgstr "此使用者是否具有管理權限" -#: users/serializers.py:335 users/serializers.py:424 +#: users/serializers.py:345 users/serializers.py:463 msgid "Superuser" msgstr "超級用户" -#: users/serializers.py:335 users/serializers.py:425 +#: users/serializers.py:345 users/serializers.py:464 msgid "Is this user a superuser" msgstr "此用户是否為超級用户" -#: users/serializers.py:339 users/serializers.py:432 +#: users/serializers.py:349 users/serializers.py:471 msgid "Is this user account active" msgstr "此用户帳户是否已激活" -#: users/serializers.py:351 +#: users/serializers.py:361 msgid "Only a superuser can adjust this field" msgstr "僅超級使用者可調整此欄位" -#: users/serializers.py:379 +#: users/serializers.py:389 msgid "Password" msgstr "密碼" -#: users/serializers.py:380 +#: users/serializers.py:390 msgid "Password for the user" msgstr "使用者密碼" -#: users/serializers.py:386 +#: users/serializers.py:396 msgid "Override warning" msgstr "忽略警告" -#: users/serializers.py:387 +#: users/serializers.py:397 msgid "Override the warning about password rules" msgstr "忽略密碼規則警告" -#: users/serializers.py:417 +#: users/serializers.py:456 msgid "Staff" msgstr "員工" -#: users/serializers.py:418 +#: users/serializers.py:457 msgid "Does this user have staff permissions" msgstr "此使用者是否具有員工權限" -#: users/serializers.py:468 +#: users/serializers.py:507 msgid "You do not have permission to create users" msgstr "您沒有建立使用者的權限" -#: users/serializers.py:489 +#: users/serializers.py:528 msgid "Your account has been created." msgstr "您的帳號已經建立完成。" -#: users/serializers.py:491 +#: users/serializers.py:530 msgid "Please use the password reset function to login" msgstr "請使用重設密碼功能來登入" -#: users/serializers.py:497 +#: users/serializers.py:536 msgid "Welcome to InvenTree" msgstr "歡迎使用 InvenTree" diff --git a/src/backend/InvenTree/machine/api.py b/src/backend/InvenTree/machine/api.py index bea28dfcfd..bc78c7737c 100644 --- a/src/backend/InvenTree/machine/api.py +++ b/src/backend/InvenTree/machine/api.py @@ -3,6 +3,7 @@ from django.urls import include, path, re_path from drf_spectacular.utils import extend_schema +from rest_framework import permissions from rest_framework.exceptions import NotFound from rest_framework.response import Response from rest_framework.views import APIView @@ -142,7 +143,10 @@ class MachineRestart(APIView): - POST: restart machine by pk """ - permission_classes = [InvenTree.permissions.IsAuthenticatedOrReadScope] + permission_classes = [ + permissions.IsAuthenticated, + InvenTree.permissions.IsStaffOrReadOnlyScope, + ] @extend_schema( request=None, responses={200: MachineSerializers.MachineRestartSerializer()} diff --git a/src/backend/InvenTree/machine/machine_types/label_printer.py b/src/backend/InvenTree/machine/machine_types/label_printer.py index f598f5dd55..e8b1e28129 100644 --- a/src/backend/InvenTree/machine/machine_types/label_printer.py +++ b/src/backend/InvenTree/machine/machine_types/label_printer.py @@ -207,6 +207,10 @@ class LabelPrinterBaseDriver(BaseDriver): ``` """ + def __init__(self, machine=None, *args, **kwargs): + """Initialize the printing options serializer.""" + super().__init__(*args, **kwargs) + copies = serializers.IntegerField( default=1, label=_('Copies'), @@ -267,4 +271,4 @@ class LabelPrinterMachine(BaseMachineType): if not location_pk: return None - return StockLocation.objects.get(pk=location_pk) + return StockLocation.objects.filter(pk=location_pk).first() diff --git a/src/backend/InvenTree/machine/migrations/0002_alter_machineconfig_id.py b/src/backend/InvenTree/machine/migrations/0002_alter_machineconfig_id.py new file mode 100644 index 0000000000..5d3aac8bea --- /dev/null +++ b/src/backend/InvenTree/machine/migrations/0002_alter_machineconfig_id.py @@ -0,0 +1,28 @@ +"""Migration to store MachineConfig UUID primary keys as char(32) on MySQL / MariaDB. + +On MariaDB 10.7+, Django 5.x writes 36-character (hyphenated) UUID values, +but databases migrated under older Django / MariaDB versions retain char(32) +columns, causing machine creation to fail with "Data too long for column 'id'". + +See: https://github.com/inventree/InvenTree/issues/12270 +""" + +import uuid + +from django.db import migrations + +import InvenTree.fields + + +class Migration(migrations.Migration): + dependencies = [('machine', '0001_initial')] + + operations = [ + migrations.AlterField( + model_name='machineconfig', + name='id', + field=InvenTree.fields.InvenTreeUUIDField( + default=uuid.uuid4, editable=False, primary_key=True, serialize=False + ), + ), + ] diff --git a/src/backend/InvenTree/machine/models.py b/src/backend/InvenTree/machine/models.py index b81b1c7a00..f1f1896a85 100755 --- a/src/backend/InvenTree/machine/models.py +++ b/src/backend/InvenTree/machine/models.py @@ -10,6 +10,7 @@ from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ import common.models +import InvenTree.fields from machine import registry from machine.machine_type import BaseMachineType @@ -17,7 +18,9 @@ from machine.machine_type import BaseMachineType class MachineConfig(models.Model): """A Machine objects represents a physical machine.""" - id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + id = InvenTree.fields.InvenTreeUUIDField( + primary_key=True, default=uuid.uuid4, editable=False + ) name = models.CharField( unique=True, diff --git a/src/backend/InvenTree/machine/test_api.py b/src/backend/InvenTree/machine/test_api.py index 32a2809d2f..eb2e7584a9 100644 --- a/src/backend/InvenTree/machine/test_api.py +++ b/src/backend/InvenTree/machine/test_api.py @@ -287,14 +287,23 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase): active=True, ) + restart_url = reverse('api-machine-restart', kwargs={'pk': machine.pk}) + + # Non-staff users must not be able to restart a machine + self.user.is_staff = False + self.user.save() + self.post(restart_url, expected_code=403) + + # Restore staff access + self.user.is_staff = True + self.user.save() + # verify machine status before restart response = self.get(reverse('api-machine-detail', kwargs={'pk': machine.pk})) self.assertEqual(response.data['status_text'], '') # restart the machine - response = self.post( - reverse('api-machine-restart', kwargs={'pk': machine.pk}), expected_code=200 - ) + self.post(restart_url, expected_code=200) # verify machine status after restart response = self.get(reverse('api-machine-detail', kwargs={'pk': machine.pk})) diff --git a/src/backend/InvenTree/machine/tests.py b/src/backend/InvenTree/machine/tests.py index 120ab004b9..2feeb6c12e 100755 --- a/src/backend/InvenTree/machine/tests.py +++ b/src/backend/InvenTree/machine/tests.py @@ -62,7 +62,7 @@ class TestDriverMachineInterface(TestMachineRegistryMixin, TestCase): # Check state now self.assertEqual(len(registry.get_machine_types()), 1) - self.assertEqual(len(registry.get_driver_types()), 3) + self.assertEqual(len(registry.get_driver_types()), 4) self.assertEqual(len(registry.get_machines()), 0) # Check for expected machine registry errors @@ -79,6 +79,7 @@ class TestDriverMachineInterface(TestMachineRegistryMixin, TestCase): for slug in [ 'sample-printer-driver', 'test-label-printer-api', + 'test-label-printer-options', 'test-label-printer-error', ]: instance = registry.get_driver_instance(slug) @@ -171,6 +172,8 @@ class TestLabelPrinterMachineType(InvenTreeAPITestCase): fixtures = ['category', 'part', 'location', 'stock'] + roles = ['part.view'] + def test_registration(self): """Test that the machine is correctly registered from the plugin.""" PLG_KEY = 'label-printer-test-plugin' @@ -185,23 +188,22 @@ class TestLabelPrinterMachineType(InvenTreeAPITestCase): else: self.assertIsNone(machine) - def create_machine(self): + def create_machine(self, driver_key): """Create a new label printing machine.""" registry.initialize(main=True) PLG_KEY = 'label-printer-test-plugin' - DRIVER_KEY = 'test-label-printer-api' # Ensure that the driver is initialized plg_registry.set_plugin_state(PLG_KEY, True) - driver = registry.get_driver_instance(DRIVER_KEY) + driver = registry.get_driver_instance(driver_key) self.assertIsNotNone(driver) machine_config = MachineConfig.objects.create( name='Test Label Printer', machine_type='label-printer', - driver=DRIVER_KEY, + driver=driver_key, active=True, ) @@ -216,7 +218,7 @@ class TestLabelPrinterMachineType(InvenTreeAPITestCase): """Test arbitrary function calls against a machine.""" from machine.registry import call_machine_function - machine = self.create_machine() + machine = self.create_machine('test-label-printer-api') with self.assertRaises(AttributeError): call_machine_function(machine.pk, 'fake_function', custom_arg=123) @@ -229,7 +231,7 @@ class TestLabelPrinterMachineType(InvenTreeAPITestCase): """Test the print label method.""" plugin_ref = 'inventreelabelmachine' - machine = self.create_machine() + machine = self.create_machine('test-label-printer-api') # setup the label app apps.get_app_config('report').create_default_labels() @@ -295,6 +297,100 @@ class TestLabelPrinterMachineType(InvenTreeAPITestCase): self.assertIn('is not a valid choice', str(response.data['machine'])) + def test_printing_options_serializer(self): + """Test the printing options serializer.""" + plugin_ref = 'inventreelabelmachine' + + machine = self.create_machine('test-label-printer-options') + machine.set_setting('LABEL', 'D', '18') + + # setup the label app + apps.get_app_config('report').create_default_labels() + plg_registry.reload_plugins() + + config = cast(PluginConfig, plg_registry.get_plugin(plugin_ref).plugin_config()) + config.active = True + config.save() + + parts = Part.objects.all()[:2] + template = LabelTemplate.objects.filter(enabled=True, model_type='part').first() + assert template + + url = reverse('api-label-print') + + # Test print using machine defaults (LABEL: 18) + with self.assertLogs('inventree', level='WARNING') as cm: + self.post( + url, + { + 'plugin': config.key, + 'items': [a.pk for a in parts], + 'template': template.pk, + 'machine': str(machine.pk), + }, + expected_code=201, + ) + + # Check for expected messages + messages = [ + 'Printing Label: TestingLabelPrinterDriverOptions', + f'machine: {machine.pk}', + f'label: {template.pk}', + f'item: {parts[0].pk}', + f'item: {parts[1].pk}', + 'options: label: 18', + ] + + for message in messages: + result = False + for item in cm.records: + if message in str(item): + result = True + break + + self.assertTrue(result, f'Message not found: {message}') + + # Test print using print options (label: 24) + with self.assertLogs('inventree', level='WARNING') as cm: + self.post( + url, + { + 'plugin': config.key, + 'items': [a.pk for a in parts], + 'template': template.pk, + 'machine': str(machine.pk), + 'driver_options': {'label': '24'}, + }, + expected_code=201, + ) + + # Check for expected messages + messages = [ + 'Printing Label: TestingLabelPrinterDriverOptions', + f'machine: {machine.pk}', + f'label: {template.pk}', + f'item: {parts[0].pk}', + f'item: {parts[1].pk}', + 'options: label: 24', + ] + + for message in messages: + result = False + for item in cm.records: + if message in str(item): + result = True + break + + self.assertTrue(result, f'Message not found: {message}') + + def test_location_invalid_pk(self): + """Test that location property returns None for an invalid PK without raising.""" + machine = self.create_machine('test-label-printer-api') + + machine.set_setting('LOCATION', 'M', 999999) + + self.assertIsNone(machine.location) + class AdminTest(AdminTestCase): """Tests for the admin interface integration.""" diff --git a/src/backend/InvenTree/order/admin.py b/src/backend/InvenTree/order/admin.py index 875ebdb763..0a9d402878 100644 --- a/src/backend/InvenTree/order/admin.py +++ b/src/backend/InvenTree/order/admin.py @@ -94,7 +94,14 @@ class PurchaseOrderLineItemAdmin(admin.ModelAdmin): list_display = ('order', 'part', 'quantity', 'reference') - search_fields = ('reference',) + search_fields = [ + 'part__part__name', + 'part__part__description', + 'part__SKU', + 'order__reference', + 'order__supplier__name', + 'reference', + ] autocomplete_fields = ('order', 'part', 'destination') diff --git a/src/backend/InvenTree/order/api.py b/src/backend/InvenTree/order/api.py index d8637baa66..9ca3108b85 100644 --- a/src/backend/InvenTree/order/api.py +++ b/src/backend/InvenTree/order/api.py @@ -6,6 +6,7 @@ from typing import cast from django.conf import settings from django.contrib.auth import authenticate, login from django.contrib.auth.models import User +from django.db import transaction from django.db.models import F, Q from django.http.response import JsonResponse from django.urls import include, path, re_path @@ -22,6 +23,7 @@ from rest_framework.exceptions import NotFound from rest_framework.response import Response import build.models +import common.filters import common.models import common.serializers import common.settings @@ -30,7 +32,13 @@ import stock.models as stock_models import stock.serializers as stock_serializers from data_exporter.mixins import DataExportViewMixin from generic.states.api import StatusView -from InvenTree.api import BulkUpdateMixin, ListCreateDestroyAPIView, ParameterListMixin +from InvenTree.api import ( + BulkDeleteMixin, + BulkUpdateMixin, + ListCreateDestroyAPIView, + ParameterListMixin, + meta_path, +) from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.filters import SEARCH_ORDER_FILTER, InvenTreeDateFilter from InvenTree.helpers import current_date, str2bool @@ -96,9 +104,7 @@ class OrderCreateMixin: serializer = self.get_serializer(data=self.clean_data(request.data)) serializer.is_valid(raise_exception=True) - item = serializer.save() - item.created_by = request.user - item.save() + serializer.save(created_by=request.user) headers = self.get_success_headers(serializer.data) return Response( @@ -271,6 +277,8 @@ class OrderFilter(FilterSet): return queryset.filter(q1 | q2 | q3 | q4).distinct() + tags = common.filters.TagsFilter() + class LineItemFilter(FilterSet): """Base class for custom API filters for order line item list(s).""" @@ -676,19 +684,34 @@ class PurchaseOrderLineItemList( # possibly merge duplicate items line_item = None - if data.get('merge_items', True): - other_line = models.PurchaseOrderLineItem.objects.filter( - part=data.get('part'), - order=data.get('order'), - target_date=data.get('target_date'), - destination=data.get('destination'), - ).first() + merge_items = data.get( + 'merge_items', + common.settings.get_global_setting( + 'PURCHASEORDER_MERGE_LINE_ITEMS', backup_value=True + ), + ) - if other_line is not None: - other_line.quantity += Decimal(data.get('quantity', 0)) - other_line.save() + if merge_items: + with transaction.atomic(): + # Lock the matching row, so concurrent line creations cannot + # both read the same starting quantity (lost update) + other_line = ( + models.PurchaseOrderLineItem.objects + .select_for_update() + .filter( + part=data.get('part'), + order=data.get('order'), + target_date=data.get('target_date'), + destination=data.get('destination'), + ) + .first() + ) - line_item = other_line + if other_line is not None: + other_line.quantity += Decimal(data.get('quantity', 0)) + other_line.save() + + line_item = other_line # otherwise create a new line item if line_item is None: @@ -728,7 +751,6 @@ class PurchaseOrderLineItemList( 'reference', 'SKU', 'IPN', - 'total_price', 'target_date', 'order', 'status', @@ -754,7 +776,7 @@ class PurchaseOrderLineItemDetail( class PurchaseOrderExtraLineList( - GeneralExtraLineList, OutputOptionsMixin, ListCreateAPI + GeneralExtraLineList, OutputOptionsMixin, ListCreateDestroyAPIView ): """API endpoint for accessing a list of PurchaseOrderExtraLine objects.""" @@ -1046,7 +1068,10 @@ class SalesOrderLineItemOutputOptions(OutputConfiguration): class SalesOrderLineItemList( - SalesOrderLineItemMixin, DataExportViewMixin, OutputOptionsMixin, ListCreateAPI + SalesOrderLineItemMixin, + DataExportViewMixin, + OutputOptionsMixin, + ListCreateDestroyAPIView, ): """API endpoint for accessing a list of SalesOrderLineItem objects.""" @@ -1069,6 +1094,8 @@ class SalesOrderLineItemList( 'sale_price', 'target_date', 'line', + 'status', + 'shipment_date', ] ordering_field_aliases = { @@ -1077,6 +1104,8 @@ class SalesOrderLineItemList( 'IPN': 'part__IPN', 'order': 'order__reference', 'line': ['line_int', 'line', 'part__name'], + 'status': 'order__status', + 'shipment_date': 'order__shipment_date', } search_fields = ['part__name', 'quantity', 'reference'] @@ -1090,7 +1119,9 @@ class SalesOrderLineItemDetail( output_options = SalesOrderLineItemOutputOptions -class SalesOrderExtraLineList(GeneralExtraLineList, OutputOptionsMixin, ListCreateAPI): +class SalesOrderExtraLineList( + GeneralExtraLineList, OutputOptionsMixin, ListCreateDestroyAPIView +): """API endpoint for accessing a list of SalesOrderExtraLine objects.""" queryset = models.SalesOrderExtraLine.objects.all() @@ -1165,6 +1196,50 @@ class SalesOrderAllocate(SalesOrderContextMixin, CreateAPI): serializer_class = serializers.SalesOrderShipmentAllocationSerializer +class SalesOrderAutoAllocate(SalesOrderContextMixin, CreateAPI): + """API endpoint to automatically allocate stock against a SalesOrder. + + - Offloads work to a background task and returns task detail + """ + + serializer_class = serializers.SalesOrderAutoAllocationSerializer + + @extend_schema(responses={200: common.serializers.TaskDetailSerializer}) + def post(self, *args, **kwargs): + """Validate parameters and offload auto-allocation to a background task.""" + from InvenTree.tasks import offload_task + from order.tasks import auto_allocate_sales_order + + order_obj = self.get_object() + serializer = self.get_serializer(data=self.request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + + # Extract related models from the validated data + location = data.get('location') + exclude_location = data.get('exclude_location') + shipment = data.get('shipment') + line_items = data.get('line_items', []) + + # Offload to the background worker + # Note: We provide the model ID values, not the model instances + task_id = offload_task( + auto_allocate_sales_order, + order_obj.pk, + location_id=location.pk if location else None, + exclude_location_id=exclude_location.pk if exclude_location else None, + shipment_id=shipment.pk if shipment else None, + line_ids=[item.pk for item in line_items] if line_items else None, + interchangeable=data['interchangeable'], + stock_sort_by=data['stock_sort_by'], + serialized_stock=data['serialized_stock'], + group='sales_order', + ) + + response = common.serializers.TaskDetailSerializer.from_task(task_id).data + return Response(response, status=response['http_status']) + + class SalesOrderAllocationFilter(FilterSet): """Custom filterset for the SalesOrderAllocationList endpoint.""" @@ -1295,7 +1370,12 @@ class SalesOrderAllocationOutputOptions(OutputConfiguration): class SalesOrderAllocationList( - SalesOrderAllocationMixin, BulkUpdateMixin, OutputOptionsMixin, ListAPI + SalesOrderAllocationMixin, + BulkDeleteMixin, + BulkUpdateMixin, + DataExportViewMixin, + OutputOptionsMixin, + ListAPI, ): """API endpoint for listing SalesOrderAllocation objects.""" @@ -1303,6 +1383,10 @@ class SalesOrderAllocationList( filter_backends = SEARCH_ORDER_FILTER output_options = SalesOrderAllocationOutputOptions + def filter_delete_queryset(self, queryset, request): + """Prevent deletion of allocations that have already been shipped.""" + return queryset.filter(shipment__shipment_date__isnull=True) + ordering_fields = [ 'quantity', 'part', @@ -1390,6 +1474,8 @@ class SalesOrderShipmentFilter(FilterSet): return queryset.filter(q1 | q2).distinct() + tags = common.filters.TagsFilter() + class SalesOrderShipmentMixin: """Mixin class for SalesOrderShipment endpoints.""" @@ -1706,7 +1792,11 @@ class ReturnOrderLineItemOutputOptions(OutputConfiguration): class ReturnOrderLineItemList( - ReturnOrderLineItemMixin, DataExportViewMixin, OutputOptionsMixin, ListCreateAPI + ReturnOrderLineItemMixin, + BulkUpdateMixin, + DataExportViewMixin, + OutputOptionsMixin, + ListCreateDestroyAPIView, ): """API endpoint for accessing a list of ReturnOrderLineItemList objects.""" @@ -1749,7 +1839,9 @@ class ReturnOrderLineItemDetail( output_options = ReturnOrderLineItemOutputOptions -class ReturnOrderExtraLineList(GeneralExtraLineList, OutputOptionsMixin, ListCreateAPI): +class ReturnOrderExtraLineList( + GeneralExtraLineList, OutputOptionsMixin, ListCreateDestroyAPIView +): """API endpoint for accessing a list of ReturnOrderExtraLine objects.""" queryset = models.ReturnOrderExtraLine.objects.all() @@ -2244,7 +2336,10 @@ class TransferOrderLineItemOutputOptions(OutputConfiguration): class TransferOrderLineItemList( - TransferOrderLineItemMixin, DataExportViewMixin, OutputOptionsMixin, ListCreateAPI + TransferOrderLineItemMixin, + DataExportViewMixin, + OutputOptionsMixin, + ListCreateDestroyAPIView, ): """API endpoint for accessing a list of TransferOrderLineItem objects.""" @@ -2474,6 +2569,7 @@ order_api_urls = [ name='api-po-complete', ), path('issue/', PurchaseOrderIssue.as_view(), name='api-po-issue'), + meta_path(models.PurchaseOrder), path( 'receive/', PurchaseOrderReceive.as_view(), @@ -2500,8 +2596,14 @@ order_api_urls = [ include([ path( '/', - PurchaseOrderLineItemDetail.as_view(), - name='api-po-line-detail', + include([ + meta_path(models.PurchaseOrderLineItem), + path( + '', + PurchaseOrderLineItemDetail.as_view(), + name='api-po-line-detail', + ), + ]), ), path('', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'), ]), @@ -2512,8 +2614,14 @@ order_api_urls = [ include([ path( '/', - PurchaseOrderExtraLineDetail.as_view(), - name='api-po-extra-line-detail', + include([ + meta_path(models.PurchaseOrderExtraLine), + path( + '', + PurchaseOrderExtraLineDetail.as_view(), + name='api-po-extra-line-detail', + ), + ]), ), path( '', PurchaseOrderExtraLineList.as_view(), name='api-po-extra-line-list' @@ -2535,6 +2643,7 @@ order_api_urls = [ SalesOrderShipmentComplete.as_view(), name='api-so-shipment-ship', ), + meta_path(models.SalesOrderShipment), path( '', SalesOrderShipmentDetail.as_view(), @@ -2563,6 +2672,11 @@ order_api_urls = [ SalesOrderAllocateSerials.as_view(), name='api-so-allocate-serials', ), + path( + 'auto-allocate/', + SalesOrderAutoAllocate.as_view(), + name='api-so-auto-allocate', + ), path('hold/', SalesOrderHold.as_view(), name='api-so-hold'), path('cancel/', SalesOrderCancel.as_view(), name='api-so-cancel'), path('issue/', SalesOrderIssue.as_view(), name='api-so-issue'), @@ -2571,6 +2685,7 @@ order_api_urls = [ SalesOrderComplete.as_view(), name='api-so-complete', ), + meta_path(models.SalesOrder), # SalesOrder detail endpoint path('', SalesOrderDetail.as_view(), name='api-so-detail'), ]), @@ -2592,8 +2707,14 @@ order_api_urls = [ include([ path( '/', - SalesOrderLineItemDetail.as_view(), - name='api-so-line-detail', + include([ + meta_path(models.SalesOrderLineItem), + path( + '', + SalesOrderLineItemDetail.as_view(), + name='api-so-line-detail', + ), + ]), ), path('', SalesOrderLineItemList.as_view(), name='api-so-line-list'), ]), @@ -2604,8 +2725,14 @@ order_api_urls = [ include([ path( '/', - SalesOrderExtraLineDetail.as_view(), - name='api-so-extra-line-detail', + include([ + meta_path(models.SalesOrderExtraLine), + path( + '', + SalesOrderExtraLineDetail.as_view(), + name='api-so-extra-line-detail', + ), + ]), ), path('', SalesOrderExtraLineList.as_view(), name='api-so-extra-line-list'), ]), @@ -2651,6 +2778,7 @@ order_api_urls = [ ReturnOrderReceive.as_view(), name='api-return-order-receive', ), + meta_path(models.ReturnOrder), path( '', ReturnOrderDetail.as_view(), name='api-return-order-detail' ), @@ -2673,8 +2801,14 @@ order_api_urls = [ include([ path( '/', - ReturnOrderLineItemDetail.as_view(), - name='api-return-order-line-detail', + include([ + meta_path(models.ReturnOrderLineItem), + path( + '', + ReturnOrderLineItemDetail.as_view(), + name='api-return-order-line-detail', + ), + ]), ), # Return order line item status code information path( @@ -2694,8 +2828,14 @@ order_api_urls = [ include([ path( '/', - ReturnOrderExtraLineDetail.as_view(), - name='api-return-order-extra-line-detail', + include([ + meta_path(models.ReturnOrderExtraLine), + path( + '', + ReturnOrderExtraLineDetail.as_view(), + name='api-return-order-extra-line-detail', + ), + ]), ), path( '', @@ -2742,6 +2882,7 @@ order_api_urls = [ TransferOrderIssue.as_view(), name='api-transfer-order-issue', ), + meta_path(models.TransferOrder), path( '', TransferOrderDetail.as_view(), @@ -2759,8 +2900,14 @@ order_api_urls = [ include([ path( '/', - TransferOrderLineItemDetail.as_view(), - name='api-transfer-order-line-detail', + include([ + meta_path(models.TransferOrderLineItem), + path( + '', + TransferOrderLineItemDetail.as_view(), + name='api-transfer-order-line-detail', + ), + ]), ), path( '', diff --git a/src/backend/InvenTree/order/events.py b/src/backend/InvenTree/order/events.py index 4f17e26e35..dfb0e950cf 100644 --- a/src/backend/InvenTree/order/events.py +++ b/src/backend/InvenTree/order/events.py @@ -20,7 +20,7 @@ class SalesOrderEvents(BaseEventEnum): """Event enumeration for the SalesOrder models.""" ISSUED = 'salesorder.issued' - HOLD = 'salesorder.onhold' + HOLD = 'salesorder.hold' COMPLETED = 'salesorder.completed' CANCELLED = 'salesorder.cancelled' @@ -38,6 +38,8 @@ class ReturnOrderEvents(BaseEventEnum): CANCELLED = 'returnorder.cancelled' HOLD = 'returnorder.hold' + OVERDUE = 'order.overdue_return_order' + class TransferOrderEvents(BaseEventEnum): """Event enumeration for the PurchaseOrder models.""" diff --git a/src/backend/InvenTree/order/fixtures/sales_order.yaml b/src/backend/InvenTree/order/fixtures/sales_order.yaml index dfffb25fd4..9d32bd2d3b 100644 --- a/src/backend/InvenTree/order/fixtures/sales_order.yaml +++ b/src/backend/InvenTree/order/fixtures/sales_order.yaml @@ -38,6 +38,14 @@ customer: 5 status: 60 # Returned +- model: order.salesorder + pk: 6 + fields: + reference: 'ABC128' + description: "One sales order, please" + customer: 5 + status: 30 # Complete + # 1 x R_4K7_0603 - model: order.salesorderlineitem pk: 1 diff --git a/src/backend/InvenTree/order/migrations/0120_purchaseorder_tags_returnorder_tags_salesorder_tags_and_more.py b/src/backend/InvenTree/order/migrations/0120_purchaseorder_tags_returnorder_tags_salesorder_tags_and_more.py new file mode 100644 index 0000000000..cd027f68e7 --- /dev/null +++ b/src/backend/InvenTree/order/migrations/0120_purchaseorder_tags_returnorder_tags_salesorder_tags_and_more.py @@ -0,0 +1,73 @@ +# Generated by Django 5.2.14 on 2026-06-03 10:07 + +import taggit.managers +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("order", "0119_transferorderlineitem_line_int"), + ( + "taggit", + "0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx", + ), + ] + + operations = [ + migrations.AddField( + model_name="purchaseorder", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + migrations.AddField( + model_name="returnorder", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + migrations.AddField( + model_name="salesorder", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + migrations.AddField( + model_name="salesordershipment", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + migrations.AddField( + model_name="transferorder", + name="tags", + field=taggit.managers.TaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/src/backend/InvenTree/order/migrations/0121_add_line_item_discount.py b/src/backend/InvenTree/order/migrations/0121_add_line_item_discount.py new file mode 100644 index 0000000000..f5f9371e75 --- /dev/null +++ b/src/backend/InvenTree/order/migrations/0121_add_line_item_discount.py @@ -0,0 +1,119 @@ +# Generated by Django 5.2.15 on 2026-07-14 02:18 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("order", "0120_purchaseorder_tags_returnorder_tags_salesorder_tags_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="purchaseorderextraline", + name="discount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text="Discount percentage applied to this line item (0-100)", + max_digits=5, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + verbose_name="Discount", + ), + ), + migrations.AddField( + model_name="purchaseorderlineitem", + name="discount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text="Discount percentage applied to this line item (0-100)", + max_digits=5, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + verbose_name="Discount", + ), + ), + migrations.AddField( + model_name="returnorderextraline", + name="discount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text="Discount percentage applied to this line item (0-100)", + max_digits=5, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + verbose_name="Discount", + ), + ), + migrations.AddField( + model_name="returnorderlineitem", + name="discount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text="Discount percentage applied to this line item (0-100)", + max_digits=5, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + verbose_name="Discount", + ), + ), + migrations.AddField( + model_name="salesorderextraline", + name="discount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text="Discount percentage applied to this line item (0-100)", + max_digits=5, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + verbose_name="Discount", + ), + ), + migrations.AddField( + model_name="salesorderlineitem", + name="discount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text="Discount percentage applied to this line item (0-100)", + max_digits=5, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + verbose_name="Discount", + ), + ), + migrations.AddField( + model_name="transferorderlineitem", + name="discount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text="Discount percentage applied to this line item (0-100)", + max_digits=5, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + verbose_name="Discount", + ), + ), + ] diff --git a/src/backend/InvenTree/order/models.py b/src/backend/InvenTree/order/models.py index 5973f4292b..12fbd889f7 100644 --- a/src/backend/InvenTree/order/models.py +++ b/src/backend/InvenTree/order/models.py @@ -1,13 +1,15 @@ """Order model definitions.""" +import copy from decimal import Decimal from typing import Any, Optional, TypedDict from django.contrib.auth.models import User from django.core.exceptions import ValidationError -from django.core.validators import MinValueValidator +from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models, transaction from django.db.models import F, Q, QuerySet, Sum +from django.db.models.base import ModelState from django.db.models.functions import Coalesce from django.db.models.signals import post_delete, post_save from django.dispatch.dispatcher import receiver @@ -35,7 +37,15 @@ from common.currency import currency_code_default from common.notifications import InvenTreeNotificationBodies from common.settings import get_global_setting from company.models import Address, Company, Contact, SupplierPart -from generic.states import StateTransitionMixin, StatusCodeMixin +from generic.states import ( + RETURN_VALUE, + Deprecations, + StateTransitionMixin, + StatusCodeMixin, + can_proceed, + deprecated, + inventree_transition, +) from generic.states.fields import InvenTreeCustomStatusModelField from InvenTree.exceptions import log_error from InvenTree.fields import ( @@ -44,6 +54,7 @@ from InvenTree.fields import ( RoundingDecimalField, ) from InvenTree.helpers import decimal2string, pui_url +from InvenTree.helpers_db import bulk_create_and_fetch from InvenTree.helpers_model import notify_responsible from order.events import ( PurchaseOrderEvents, @@ -63,7 +74,8 @@ from order.status_codes import ( TransferOrderStatusGroups, ) from part import models as PartModels -from plugin.events import trigger_event +from plugin.events import bulk_trigger_event, trigger_event +from stock.events import StockEvents from stock.status_codes import StockHistoryCode, StockStatus logger = structlog.get_logger('inventree') @@ -156,7 +168,11 @@ class TotalPriceMixin(models.Model): continue try: - total += line.quantity * convert_money(line.price, target_currency) + total += ( + line.quantity + * convert_money(line.price, target_currency) + * (1 - line.discount / 100) + ) except MissingRate: log_error('order.calculate_total_price') logger.exception("Missing exchange rate for '%s'", target_currency) @@ -170,7 +186,11 @@ class TotalPriceMixin(models.Model): continue try: - total += line.quantity * convert_money(line.price, target_currency) + total += ( + line.quantity + * convert_money(line.price, target_currency) + * (1 - line.discount / 100) + ) except MissingRate: # Record the error, try to press on @@ -272,7 +292,7 @@ class ReturnOrderReportContext(report.mixins.BaseReportContext, TypedDict): customer: Optional[Company] -class TransferOrderReportContext(report.mixins.BaseReportContext, TypedDict): +class TransferOrderReportContext(BaseOrderReportContext, TypedDict): """Context for the transfer order model. Attributes: @@ -300,6 +320,7 @@ class Order( InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNotesMixin, + InvenTree.models.InvenTreeTagsMixin, report.mixins.InvenTreeReportMixin, InvenTree.models.MetadataMixin, InvenTree.models.ReferenceIndexingMixin, @@ -468,8 +489,9 @@ class Order( ) @property - def is_overdue(self): - """Method to determine if this order is overdue. + @report.mixins.report_attribute() + def is_overdue(self) -> bool: + """Determine if this order is overdue. Makes use of the overdue_filter() method to avoid code duplication """ @@ -577,18 +599,36 @@ class Order( ) @property - def company(self): - """Return the company associated with this order. + @report.mixins.report_attribute() + def company(self) -> Optional[Company]: + """The company associated with this order. This method must be implemented by any subclass, as the 'company' field may be named differently for different order types (e.g. supplier vs customer). """ raise NotImplementedError(f'company() method not implemented for {__class__}') @property - def order_address(self): - """Return the Address associated with this order.""" + @report.mixins.report_attribute() + def order_address(self) -> Optional[Address]: + """The Address associated with this order.""" return self.address or self.company.primary_address + @property + @report.mixins.report_attribute() + def status_text(self) -> str: + """Return the text representation of the current status. This will consider any custom status.""" + if self.get_custom_status() is not None: + from generic.states.custom import ( + get_logical_value as get_custom_state_logical_value, + ) + + custom_status = get_custom_state_logical_value( + self.get_custom_status(), model=self._meta.model_name + ) + return custom_status.label + else: + return self.status_class.label(self.get_status()) + @classmethod def get_status_class(cls): """Return the enumeration class which represents the 'status' field for this model.""" @@ -623,7 +663,8 @@ class PurchaseOrder(TotalPriceMixin, Order): def report_context(self) -> PurchaseOrderReportContext: """Return report context data for this PurchaseOrder.""" return_ctx = super().report_context() - return_ctx.update({'supplier': self.supplier}) + + return_ctx.update({'supplier': self.supplier}) # ty:ignore[invalid-key] return return_ctx def get_absolute_url(self) -> str: @@ -691,11 +732,6 @@ class PurchaseOrder(TotalPriceMixin, Order): help_text=_('Purchase order status'), ) - @property - def status_text(self): - """Return the text representation of the status field.""" - return PurchaseOrderStatus.text(self.status) - supplier = models.ForeignKey( Company, on_delete=models.SET_NULL, @@ -792,7 +828,9 @@ class PurchaseOrder(TotalPriceMixin, Order): if group: # Check if there is already a matching line item (for this PurchaseOrder) - matches = self.lines.filter(part=supplier_part) + # Lock the matching row, so concurrent additions cannot both read + # the same starting quantity (lost update) + matches = self.lines.select_for_update().filter(part=supplier_part) if matches.count() > 0: line = matches.first() @@ -822,92 +860,113 @@ class PurchaseOrder(TotalPriceMixin, Order): return line - # region state changes - def _action_place(self, *args, **kwargs): - """Marks the PurchaseOrder as PLACED. + # region fsm + @inventree_transition( + field=status, + source=[PurchaseOrderStatus.PENDING, PurchaseOrderStatus.ON_HOLD], + target=PurchaseOrderStatus.PLACED, + event=PurchaseOrderEvents.PLACED, + ) + def place_order(self): + """Transition this PurchaseOrder to PLACED status. - Order must be currently PENDING. + The order must currently be PENDING or ON_HOLD. """ - if self.can_issue: - self.status = PurchaseOrderStatus.PLACED.value - self.issue_date = InvenTree.helpers.current_date() - self.save() + self.issue_date = InvenTree.helpers.current_date() - trigger_event(PurchaseOrderEvents.PLACED, id=self.pk) + notify_responsible( + self, + PurchaseOrder, + exclude=self.created_by, + content=InvenTreeNotificationBodies.NewOrder, + extra_users=self.subscribed_users(), + ) - # Notify users that the order has been placed - notify_responsible( - self, - PurchaseOrder, - exclude=self.created_by, - content=InvenTreeNotificationBodies.NewOrder, - extra_users=self.subscribed_users(), - ) - - def _action_complete(self, *args, **kwargs): - """Marks the PurchaseOrder as COMPLETE. - - Order must be currently PLACED. - """ - if self.status == PurchaseOrderStatus.PLACED: - self.status = PurchaseOrderStatus.COMPLETE.value - self.complete_date = InvenTree.helpers.current_date() - - self.save() - - unique_parts = set() - - # Schedule pricing update for any referenced parts - for line in self.lines.all().prefetch_related('part__part'): - # Ensure we only check 'unique' parts - if line.part and line.part.part: - unique_parts.add(line.part.part) - - for part in unique_parts: - part.schedule_pricing_update(create=True, refresh=False) - - trigger_event(PurchaseOrderEvents.COMPLETED, id=self.pk) - - @transaction.atomic + @deprecated('Use place_order() instead', version='1.5.0') def issue_order(self): - """Equivalent to 'place_order'.""" + """Equivalent to place_order().""" return self.place_order() @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_issue(self) -> bool: - """Return True if this order can be issued.""" - return self.status in [ - PurchaseOrderStatus.PENDING.value, - PurchaseOrderStatus.ON_HOLD.value, - ] + """Return True if this order can be issued (placed).""" + return can_proceed(self.place_order) - @transaction.atomic - def place_order(self): - """Attempt to transition to PLACED status.""" - return self.handle_transition( - self.status, PurchaseOrderStatus.PLACED.value, self, self._action_place - ) - - @transaction.atomic + @inventree_transition( + field=status, + source=PurchaseOrderStatus.PLACED, + target=PurchaseOrderStatus.COMPLETE, + event=PurchaseOrderEvents.COMPLETED, + ) def complete_order(self): - """Attempt to transition to COMPLETE status.""" - return self.handle_transition( - self.status, PurchaseOrderStatus.COMPLETE.value, self, self._action_complete - ) + """Transition this PurchaseOrder to COMPLETE status. - @transaction.atomic + The order must currently be PLACED. + """ + self.complete_date = InvenTree.helpers.current_date() + + unique_parts = set() + + for line in self.lines.all().prefetch_related('part__part'): + if line.part and line.part.part: + unique_parts.add(line.part.part) + + for part in unique_parts: + part.schedule_pricing_update(create=True, refresh=False) + + @inventree_transition( + field=status, + source=[PurchaseOrderStatus.PENDING, PurchaseOrderStatus.PLACED], + target=PurchaseOrderStatus.ON_HOLD, + event=PurchaseOrderEvents.HOLD, + ) def hold_order(self): - """Attempt to transition to ON_HOLD status.""" - return self.handle_transition( - self.status, PurchaseOrderStatus.ON_HOLD.value, self, self._action_hold + """Transition this PurchaseOrder to ON_HOLD status. + + The order must currently be PENDING or PLACED. + """ + + @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') + def can_hold(self) -> bool: + """Return True if this order can be placed on hold.""" + return can_proceed(self.hold_order) + + @inventree_transition( + field=status, + source=[ + PurchaseOrderStatus.PENDING, + PurchaseOrderStatus.ON_HOLD, + PurchaseOrderStatus.PLACED, + ], + target=PurchaseOrderStatus.CANCELLED, + event=PurchaseOrderEvents.CANCELLED, + ) + def cancel_order(self): + """Transition this PurchaseOrder to CANCELLED status. + + The order must currently be open (PENDING, ON_HOLD, or PLACED). + """ + notify_responsible( + self, + PurchaseOrder, + exclude=self.created_by, + content=InvenTreeNotificationBodies.OrderCanceled, + extra_users=self.subscribed_users(), ) - @transaction.atomic - def cancel_order(self): - """Attempt to transition to CANCELLED status.""" - return self.handle_transition( - self.status, PurchaseOrderStatus.CANCELLED.value, self, self._action_cancel - ) + @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') + def can_cancel(self) -> bool: + """A PurchaseOrder can only be cancelled while it is open. + + - Status is PLACED + - Status is PENDING (or ON_HOLD) + """ + return can_proceed(self.cancel_order) + + # endregion fsm @property def is_pending(self) -> bool: @@ -919,50 +978,6 @@ class PurchaseOrder(TotalPriceMixin, Order): """Return True if the PurchaseOrder is 'open'.""" return self.status in PurchaseOrderStatusGroups.OPEN - @property - def can_cancel(self) -> bool: - """A PurchaseOrder can only be cancelled under the following circumstances. - - - Status is PLACED - - Status is PENDING (or ON_HOLD) - """ - return self.status in PurchaseOrderStatusGroups.OPEN - - def _action_cancel(self, *args, **kwargs): - """Marks the PurchaseOrder as CANCELLED.""" - if self.can_cancel: - self.status = PurchaseOrderStatus.CANCELLED.value - self.save() - - trigger_event(PurchaseOrderEvents.CANCELLED, id=self.pk) - - # Notify users that the order has been canceled - notify_responsible( - self, - PurchaseOrder, - exclude=self.created_by, - content=InvenTreeNotificationBodies.OrderCanceled, - extra_users=self.subscribed_users(), - ) - - @property - def can_hold(self) -> bool: - """Return True if this order can be placed on hold.""" - return self.status in [ - PurchaseOrderStatus.PENDING.value, - PurchaseOrderStatus.PLACED.value, - ] - - def _action_hold(self, *args, **kwargs): - """Mark this purchase order as 'on hold'.""" - if self.can_hold: - self.status = PurchaseOrderStatus.ON_HOLD.value - self.save() - - trigger_event(PurchaseOrderEvents.HOLD, id=self.pk) - - # endregion - def pending_line_items(self) -> QuerySet: """Return a list of pending line items for this order. @@ -1036,6 +1051,12 @@ class PurchaseOrder(TotalPriceMixin, Order): # List of line items to update line_items_to_update: list[PurchaseOrderLineItem] = [] + # Set of users to notify (subscribers to any received part) + notify_users = set() + + # Cache of subscribers per part, to avoid repeated queries for the same part + part_subscribers_cache: dict[int, list] = {} + convert_purchase_price = get_global_setting('PURCHASEORDER_CONVERT_CURRENCY') default_currency = currency_code_default() @@ -1045,9 +1066,14 @@ class PurchaseOrder(TotalPriceMixin, Order): # Cache the custom status options for the StockItem model custom_stock_status_values = stock.models.StockItem.STATUS_CLASS.custom_values() - line_items = PurchaseOrderLineItem.objects.filter( - pk__in=line_items_ids - ).prefetch_related('part', 'part__part', 'order') + # Lock the line item rows, so that concurrent receipts against the same + # lines cannot both read the same 'received' value (lost update) + line_items = ( + PurchaseOrderLineItem.objects + .select_for_update() + .filter(pk__in=line_items_ids) + .prefetch_related('part', 'part__part', 'order') + ) # Map order line items to their corresponding stock items line_item_map = {line.pk: line for line in line_items} @@ -1094,6 +1120,13 @@ class PurchaseOrder(TotalPriceMixin, Order): line.received += quantity line_items_to_update.append(line) + # Track subscribers to this part, to notify them later + # (cache the result per-part, as multiple lines may reference the same part) + if base_part.pk not in part_subscribers_cache: + part_subscribers_cache[base_part.pk] = base_part.get_subscribers() + + notify_users.update(part_subscribers_cache[base_part.pk]) + # Extract optional serial numbers serials = item.get('serials', None) @@ -1171,8 +1204,10 @@ class PurchaseOrder(TotalPriceMixin, Order): stock_data['is_building'] = False # Increase the 'completed' quantity for the build order - build_order.completed += stock_quantity - build_order.save() + # Increment at the database level to prevent lost updates + build_order.completed = F('completed') + stock_quantity + build_order.save(update_fields=['completed']) + build_order.refresh_from_db(fields=['completed']) elif build_order.status == BuildStatus.CANCELLED: # A 'cancelled' build order is ignored pass @@ -1188,20 +1223,18 @@ class PurchaseOrder(TotalPriceMixin, Order): serials=serials, **stock_data ) - for item in new_items: - item.set_status(status, custom_values=custom_stock_status_values) - stock_items.append(item) + for new_item in new_items: + new_item.set_status( + status, custom_values=custom_stock_status_values + ) + # run validation for serialized items plugin.validate_batch_code + new_item.validate_batch_code() + # run validation for serialized items plugin.validate_model_instance + new_item.run_plugin_validation() + stock_items.append(new_item) else: - new_item = stock.models.StockItem( - **stock_data, - serial='', - tree_id=stock.models.StockItem.getNextTreeID(), - parent=None, - level=0, - lft=1, - rght=2, - ) + new_item = stock.models.StockItem(**stock_data, serial='', parent=None) new_item.set_status(status, custom_values=custom_stock_status_values) @@ -1212,18 +1245,19 @@ class PurchaseOrder(TotalPriceMixin, Order): # Bulk create new stock items if len(bulk_create_items) > 0: - stock.models.StockItem.objects.bulk_create( - bulk_create_items, batch_size=250 + # bulk_create() bypasses save()/clean() methods, so manual validation is required for each item + for item in bulk_create_items: + # run validation for items plugin.validate_batch_code + item.validate_batch_code() + # run validation for items plugin.validate_model_instance + item.run_plugin_validation() + + # Bulk create the stock items and fetch the newly created instances + new_items = list( + bulk_create_and_fetch(stock.models.StockItem, bulk_create_items) ) - # Fetch them back again - tree_ids = [item.tree_id for item in bulk_create_items] - - created_items = stock.models.StockItem.objects.filter( - tree_id__in=tree_ids, level=0, lft=1, rght=2, purchase_order=self - ).prefetch_related('location') - - stock_items.extend(created_items) + stock_items.extend(new_items) # Generate a new tracking entry for each stock item for item in stock_items: @@ -1269,7 +1303,7 @@ class PurchaseOrder(TotalPriceMixin, Order): PurchaseOrder, exclude=user, content=InvenTreeNotificationBodies.ItemsReceived, - extra_users=line.part.part.get_subscribers(), + extra_users=notify_users, ) # Return a list of the created stock items @@ -1317,6 +1351,18 @@ class PurchaseOrder(TotalPriceMixin, Order): ) +STOCK_SORT_CHOICES = stock.models.STOCK_SORT_CHOICES +STOCK_SORT_DEFAULT = stock.models.STOCK_SORT_DEFAULT + +SERIALIZED_STOCK_CHOICES = [ + ('any', _('Allow any stock (serialized or unserialized)')), + ('serialized', _('Serialized stock only')), + ('unserialized', _('Unserialized stock only')), +] + +SERIALIZED_STOCK_DEFAULT = 'any' + + class SalesOrder(TotalPriceMixin, Order): """A SalesOrder represents a list of goods shipped outwards to a customer.""" @@ -1338,7 +1384,8 @@ class SalesOrder(TotalPriceMixin, Order): def report_context(self) -> SalesOrderReportContext: """Generate report context data for this SalesOrder.""" return_ctx = super().report_context() - return_ctx.update({'customer': self.customer}) + + return_ctx.update({'customer': self.customer}) # ty:ignore[invalid-key] return return_ctx def get_absolute_url(self) -> str: @@ -1419,11 +1466,6 @@ class SalesOrder(TotalPriceMixin, Order): help_text=_('Sales order status'), ) - @property - def status_text(self) -> str: - """Return the text representation of the status field.""" - return SalesOrderStatus.text(self.status) - customer_reference = models.CharField( max_length=64, blank=True, @@ -1469,6 +1511,233 @@ class SalesOrder(TotalPriceMixin, Order): """Return true if any lines in the order are over-allocated.""" return any(line.is_overallocated() for line in self.lines.all()) + @transaction.atomic + def auto_allocate_stock( + self, + location: Optional[stock.models.StockLocation] = None, + exclude_location: Optional[stock.models.StockLocation] = None, + shipment: Optional['SalesOrderShipment'] = None, + line_ids: Optional[list] = None, + **kwargs, + ): + """Automatically allocate stock items against this SalesOrder. + + For each unallocated line item, finds available stock for + the line's part, filtered and sorted according to the supplied kwargs, then + creates SalesOrderAllocation records in bulk. + + Arguments: + location: If provided, only consider stock within this location tree. + exclude_location: If provided, exclude stock within this location tree. + shipment: Optional shipment to assign allocations to. + line_ids: If provided, only allocate against these specific line item PKs. + + Kwargs: + interchangeable (bool): If True (default), consume stock from multiple + items/locations to satisfy a line. If False, only allocate when a + single item can cover the full remaining quantity. + """ + stock_sort_by = kwargs.get('stock_sort_by', STOCK_SORT_DEFAULT) + interchangeable = kwargs.get('interchangeable', True) + serialized_stock = kwargs.get('serialized_stock', SERIALIZED_STOCK_DEFAULT) + + new_allocations = [] + + lines = self.lines.all() + if line_ids: + lines = lines.filter(pk__in=line_ids) + + for line_item in lines: + if not line_item.part: + continue + + if line_item.part.virtual: + continue + + unallocated = line_item.quantity - line_item.allocated_quantity() + + if unallocated <= 0: + continue + + available_stock = stock.models.StockItem.objects.filter( + stock.models.StockItem.IN_STOCK_FILTER, part=line_item.part + ) + + if location: + sublocations = location.get_descendants(include_self=True) + available_stock = available_stock.filter( + location__in=list(sublocations) + ) + + if exclude_location: + sublocations = exclude_location.get_descendants(include_self=True) + available_stock = available_stock.exclude( + location__in=list(sublocations) + ) + + if serialized_stock == 'serialized': + available_stock = available_stock.filter( + serial__isnull=False, quantity=1 + ).exclude(serial='') + elif serialized_stock == 'unserialized': + available_stock = available_stock.filter( + Q(serial__isnull=True) | Q(serial='') + ) + + # Handle NULL expiry_date last when sorting by expiry. + if stock_sort_by == stock.models.StockSortOrder.EXPIRY_SOONEST: + available_stock = available_stock.order_by( + F('expiry_date').asc(nulls_last=True) + ) + else: + available_stock = available_stock.order_by(stock_sort_by) + + stock_count = available_stock.count() + + if stock_count == 0: + continue + + if not interchangeable and stock_count > 1: + # Only allocate when a single item can fully cover the requirement. + single = next( + ( + s + for s in available_stock + if s.unallocated_quantity() >= unallocated + ), + None, + ) + if single is None: + continue + available_stock = [single] + + for stock_item in available_stock: + available_qty = stock_item.unallocated_quantity() + + if available_qty <= 0: + continue + + quantity = min(unallocated, available_qty) + + new_allocations.append( + SalesOrderAllocation( + line=line_item, + item=stock_item, + quantity=quantity, + shipment=shipment, + ) + ) + + unallocated -= quantity + + if unallocated <= 0: + break + + SalesOrderAllocation.objects.bulk_create(new_allocations, batch_size=250) + + @transaction.atomic + def allocate_serial_numbers( + self, + line_item: 'SalesOrderLineItem', + quantity: int, + serial_numbers: str, + shipment: Optional['SalesOrderShipment'] = None, + ) -> list['SalesOrderAllocation']: + """Allocate stock items against this SalesOrder, by serial number. + + Arguments: + line_item: The SalesOrderLineItem to allocate against + quantity: The number of serial numbers expected + serial_numbers: A string of serial numbers to allocate (e.g. "1,2,3-5") + shipment: Optional shipment to assign the allocations to + + Raises: + ValidationError: If the line item does not belong to this order, + the serial numbers cannot be parsed, or any of the requested + serial numbers do not exist or are unavailable for allocation. + """ + if line_item.order != self: + raise ValidationError(_('Line item is not associated with this order')) + + part = line_item.part + + serials = InvenTree.helpers.extract_serial_numbers( + serial_numbers, quantity, part.get_latest_serial_number(), part=part + ) + + serials = [str(serial).strip() for serial in serials] + + serials_not_exist = set() + serials_unavailable = set() + stock_items_to_allocate = [] + + # Bulk-fetch every candidate StockItem in a single query, keyed by serial, + # rather than querying once per requested serial number + candidate_items = {} + + for item in stock.models.StockItem.objects.filter( + part=part, serial__in=serials, quantity=1 + ): + candidate_items.setdefault(item.serial, item) + + for serial in serials: + stock_item = candidate_items.get(serial) + + if stock_item is None: + serials_not_exist.add(serial) + continue + + if get_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS'): + if ( + stock_item.hasRequiredTests() + and not stock_item.passedAllRequiredTests() + ): + serials_unavailable.add(serial) + continue + + if not stock_item.in_stock: + serials_unavailable.add(serial) + continue + + # Lock the StockItem row, so that concurrent allocation requests are + # serialized against each other, and re-validate the unallocated + # quantity against the now-current (and now-locked) state + if not stock_item.lock_quantity(): + serials_unavailable.add(serial) + continue + + if stock_item.unallocated_quantity() < 1: + serials_unavailable.add(serial) + continue + + # At this point, the serial number is valid, and can be added to the list + stock_items_to_allocate.append(stock_item) + + if len(serials_not_exist) > 0: + error_msg = _('No match found for the following serial numbers') + error_msg += ': ' + error_msg += ','.join(sorted(serials_not_exist)) + + raise ValidationError({'serial_numbers': error_msg}) + + if len(serials_unavailable) > 0: + error_msg = _('The following serial numbers are unavailable') + error_msg += ': ' + error_msg += ','.join(sorted(serials_unavailable)) + + raise ValidationError({'serial_numbers': error_msg}) + + allocations = [ + SalesOrderAllocation( + line=line_item, item=stock_item, quantity=1, shipment=shipment + ) + for stock_item in stock_items_to_allocate + ] + + SalesOrderAllocation.objects.bulk_create(allocations, batch_size=250) + + return allocations + def is_completed(self) -> bool: """Check if this order is "shipped" (all line items delivered). @@ -1529,68 +1798,74 @@ class SalesOrder(TotalPriceMixin, Order): return True - # region state changes + # region fsm + @deprecated("Use 'issue_order' instead", version='1.5.0') def place_order(self): """Deprecated version of 'issue_order'.""" - self.issue_order() + return self.issue_order() + + @inventree_transition( + field=status, + source=[SalesOrderStatus.PENDING, SalesOrderStatus.ON_HOLD], + target=SalesOrderStatus.IN_PROGRESS, + event=SalesOrderEvents.ISSUED, + ) + def issue_order(self): + """Transition this SalesOrder to IN_PROGRESS status. + + The order must currently be PENDING or ON_HOLD. + """ + self.issue_date = InvenTree.helpers.current_date() + + notify_responsible( + self, + SalesOrder, + exclude=self.created_by, + content=InvenTreeNotificationBodies.NewOrder, + extra_users=self.subscribed_users(), + ) @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_issue(self) -> bool: """Return True if this order can be issued.""" - return self.status in [ - SalesOrderStatus.PENDING.value, - SalesOrderStatus.ON_HOLD.value, - ] + return can_proceed(self.issue_order) - def _action_place(self, *args, **kwargs): - """Change this order from 'PENDING' to 'IN_PROGRESS'.""" - if self.can_issue: - self.status = SalesOrderStatus.IN_PROGRESS.value - self.issue_date = InvenTree.helpers.current_date() - self.save() + @inventree_transition( + field=status, + source=[SalesOrderStatus.PENDING, SalesOrderStatus.IN_PROGRESS], + target=SalesOrderStatus.ON_HOLD, + event=SalesOrderEvents.HOLD, + ) + def hold_order(self): + """Transition this SalesOrder to ON_HOLD status. - trigger_event(SalesOrderEvents.ISSUED, id=self.pk) - - # Notify users that the order has been placed - notify_responsible( - self, - SalesOrder, - exclude=self.created_by, - content=InvenTreeNotificationBodies.NewOrder, - extra_users=self.subscribed_users(), - ) + The order must currently be PENDING or IN_PROGRESS. + """ @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_hold(self) -> bool: """Return True if this order can be placed on hold.""" - return self.status in [ - SalesOrderStatus.PENDING.value, - SalesOrderStatus.IN_PROGRESS.value, - ] + return can_proceed(self.hold_order) - def _action_hold(self, *args, **kwargs): - """Mark this sales order as 'on hold'.""" - if self.can_hold: - self.status = SalesOrderStatus.ON_HOLD.value - self.save() + def _ship_complete_action(self, user=None, **kwargs) -> SalesOrderStatus: + """Shared logic for ship_order and complete_order. - trigger_event(SalesOrderEvents.HOLD, id=self.pk) - - @transaction.atomic - def _action_complete(self, *args, **kwargs): - """Mark this order as "complete.""" - user = kwargs.pop('user', None) + Returns the target state (SHIPPED or COMPLETE) based on global settings + and the current order state. + Raises: + TransitionNotAllowed: if business-logic preconditions are not met. + """ if not self.can_complete(**kwargs): - return False + raise ValidationError('Order cannot be shipped or completed at this time') bypass_shipped = InvenTree.helpers.str2bool( get_global_setting('SALESORDER_SHIP_COMPLETE') ) - # Update line items for line in self.lines.all(): - # Mark any "virtual" parts as shipped at this point if line.part and line.part.virtual and line.shipped != line.quantity: line.shipped = line.quantity line.save() @@ -1598,46 +1873,73 @@ class SalesOrder(TotalPriceMixin, Order): if line.part: line.part.schedule_pricing_update(create=True) - if bypass_shipped or self.status == SalesOrderStatus.SHIPPED: - self.status = SalesOrderStatus.COMPLETE.value - else: - self.status = SalesOrderStatus.SHIPPED.value - if self.shipment_date is None: self.shipped_by = user self.shipment_date = InvenTree.helpers.current_date() - self.save() - trigger_event(SalesOrderEvents.COMPLETED, id=self.pk) - return True + if bypass_shipped or self.status == SalesOrderStatus.SHIPPED: + return SalesOrderStatus.COMPLETE + else: + return SalesOrderStatus.SHIPPED - @property - def can_cancel(self) -> bool: - """Return True if this order can be cancelled.""" - return self.is_open + @inventree_transition( + field=status, + source=[ + SalesOrderStatus.PENDING, + SalesOrderStatus.IN_PROGRESS, + SalesOrderStatus.ON_HOLD, + SalesOrderStatus.SHIPPED, + ], + target=RETURN_VALUE(SalesOrderStatus.SHIPPED, SalesOrderStatus.COMPLETE), + ) + def ship_order(self, user=None, **kwargs): + """Attempt to ship or complete this SalesOrder. - def _action_cancel(self, *args, **kwargs): - """Cancel this order (only if it is "open"). - - Executes: - - Mark the order as 'cancelled' - - Delete any StockItems which have been allocated + The order must currently be PENDING, IN_PROGRESS, ON_HOLD, or already SHIPPED. + Depending on global settings, the order will transition to SHIPPED or COMPLETE. """ - if not self.can_cancel: - return False + return self._ship_complete_action(user=user, **kwargs) - self.status = SalesOrderStatus.CANCELLED.value - self.save() + @inventree_transition( + field=status, + source=[ + SalesOrderStatus.PENDING, + SalesOrderStatus.IN_PROGRESS, + SalesOrderStatus.ON_HOLD, + SalesOrderStatus.SHIPPED, + ], + target=RETURN_VALUE(SalesOrderStatus.SHIPPED, SalesOrderStatus.COMPLETE), + ) + def complete_order(self, user=None, **kwargs): + """Attempt to complete this SalesOrder. + The order must currently be IN_PROGRESS, ON_HOLD, or SHIPPED. + Depending on global settings, the order will transition to SHIPPED or COMPLETE. + """ + return self._ship_complete_action(user=user, **kwargs) + + @inventree_transition( + field=status, + source=[ + SalesOrderStatus.PENDING, + SalesOrderStatus.ON_HOLD, + SalesOrderStatus.IN_PROGRESS, + SalesOrderStatus.SHIPPED, + ], + target=SalesOrderStatus.CANCELLED, + event=SalesOrderEvents.CANCELLED, + ) + def cancel_order(self): + """Transition this SalesOrder to CANCELLED status. + + Deletes all pending stock allocations. + """ for line in self.lines.all(): for allocation in line.allocations.all(): allocation.delete() - trigger_event(SalesOrderEvents.CANCELLED, id=self.pk) - - # Notify users that the order has been canceled notify_responsible( self, SalesOrder, @@ -1646,54 +1948,13 @@ class SalesOrder(TotalPriceMixin, Order): extra_users=self.subscribed_users(), ) - return True + @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') + def can_cancel(self) -> bool: + """Return True if this order can be cancelled.""" + return can_proceed(self.cancel_order) - @transaction.atomic - def issue_order(self): - """Attempt to transition to IN_PROGRESS status.""" - return self.handle_transition( - self.status, SalesOrderStatus.IN_PROGRESS.value, self, self._action_place - ) - - @transaction.atomic - def ship_order(self, user, **kwargs): - """Attempt to transition to SHIPPED status.""" - return self.handle_transition( - self.status, - SalesOrderStatus.SHIPPED.value, - self, - self._action_complete, - user=user, - **kwargs, - ) - - @transaction.atomic - def complete_order(self, user, **kwargs): - """Attempt to transition to COMPLETED status.""" - return self.handle_transition( - self.status, - SalesOrderStatus.COMPLETE.value, - self, - self._action_complete, - user=user, - **kwargs, - ) - - @transaction.atomic - def hold_order(self): - """Attempt to transition to ON_HOLD status.""" - return self.handle_transition( - self.status, SalesOrderStatus.ON_HOLD.value, self, self._action_hold - ) - - @transaction.atomic - def cancel_order(self): - """Attempt to transition to CANCELLED status.""" - return self.handle_transition( - self.status, SalesOrderStatus.CANCELLED.value, self, self._action_cancel - ) - - # endregion + # endregion fsm @property def line_count(self) -> int: @@ -1854,11 +2115,20 @@ class OrderLineItem(InvenTree.models.InvenTreeMetadataModel): validators=[MinValueValidator(0)], ) + discount = models.DecimalField( + verbose_name=_('Discount'), + help_text=_('Discount percentage applied to this line item (0-100)'), + default=0, + max_digits=5, + decimal_places=2, + validators=[MinValueValidator(0), MaxValueValidator(100)], + ) + @property def total_line_price(self): - """Return the total price for this line item.""" + """Return the total price for this line item, after any discount is applied.""" if self.price: - return self.quantity * self.price + return self.quantity * self.price * (1 - self.discount / 100) line = models.CharField( max_length=20, @@ -2329,6 +2599,7 @@ class SalesOrderShipment( InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeBarcodeMixin, + InvenTree.models.InvenTreeTagsMixin, InvenTree.models.InvenTreeNotesMixin, report.mixins.InvenTreeReportMixin, InvenTree.models.MetadataMixin, @@ -2524,6 +2795,199 @@ class SalesOrderShipment( return True + @transaction.atomic + def complete_allocations( + self, allocations: QuerySet, user: Optional[User] = None + ) -> None: + """Complete a set of SalesOrderAllocation objects, marking their stock as shipped to the customer. + + Arguments: + allocations: QuerySet of SalesOrderAllocation objects to complete + user: The user completing the allocations + + Notes: + This unrolls what would otherwise be a per-allocation call, so that the underlying + StockItem, StockItemTracking, SalesOrderLineItem and SalesOrderAllocation writes can + be batched into a handful of bulk queries instead of several per allocation. + """ + import part.tasks + + order = self.order + customer = order.customer + + # Preselect related fields to avoid per-row database queries below + allocations = allocations.select_related('line', 'item', 'item__part') + + split_items = [] # (source_item, new_item, quantity) - stock to split off + shipped_items = [] # (target_item, quantity) - stock to mark as shipped + + # Canonical (mutable) copy of each distinct StockItem being drawn from - multiple + # allocations may draw from the same StockItem, so track running state + seen_stock_items: dict = {} + + # Track the lines which have already been processed, to avoid double counting + seen_lines: dict = {} + + # Allocations whose 'item' now points at a newly-split-off StockItem + allocations_to_update = [] + + for allocation in allocations: + stock_item = seen_stock_items.get(allocation.item_id) or allocation.item + quantity = allocation.quantity + + seen_stock_items[stock_item.pk] = stock_item + + if quantity < stock_item.quantity: + # Split off exactly the shipped quantity into a new StockItem, + # leaving the remainder in place as available stock + new_item = copy.copy(stock_item) + new_item._state = ModelState() + new_item.pk = None + new_item.quantity = quantity + new_item.parent = stock_item + + stock_item.quantity -= quantity + + target_item = new_item + split_items.append((stock_item, new_item, quantity)) + + allocation.item = new_item + allocations_to_update.append(allocation) + else: + target_item = stock_item + + # Resolve the final resting state of the target item now + target_item.sales_order = order + target_item.customer = customer + target_item.location = None + + shipped_items.append((target_item, quantity)) + + # Increase the "shipped" quantity for the associated line + line = seen_lines.get(allocation.line_id) or allocation.line + line.shipped += quantity + seen_lines[line.pk] = line + + # Nothing to do? + if not seen_stock_items: + return + + # Bulk-create the newly split-off stock items - this resolves their primary keys, + # which the tracking entries below need + new_stock_item_data = [new_item for _, new_item, _ in split_items] + + # Evaluate the queryset immediately (into a list) - otherwise, indexing into it + # below would re-query the database once per split item + new_stock_items = list( + bulk_create_and_fetch(stock.models.StockItem, new_stock_item_data) + ) + + # Backfill the newly created StockItem objects into the split_items list, + # then repoint every other reference to a placeholder (pk=None) copy at the + # newly persisted instance instead - shipped_items and allocations_to_update + # were populated with the pre-creation copies, which never gain a primary key + split_item_map = {} + + for i, (source, placeholder, quantity) in enumerate(split_items): + persisted = new_stock_items[i] + split_item_map[id(placeholder)] = persisted + split_items[i] = (source, persisted, quantity) + + shipped_items = [ + (split_item_map.get(id(item), item), quantity) + for item, quantity in shipped_items + ] + + for allocation in allocations_to_update: + allocation.item = split_item_map[id(allocation.item)] + + tracking_entries = [] + split_events = [] + customer_events = [] + + # Split stock items for "split_items" + for source_item, new_item, quantity in split_items: + tracking_entries.append( + stock.models.StockItemTracking( + item_id=new_item.pk, + part_id=new_item.part_id, + tracking_type=StockHistoryCode.SPLIT_FROM_PARENT.value, + user=user, + deltas={'stockitem': source_item.pk, 'quantity': float(quantity)}, + ) + ) + tracking_entries.append( + stock.models.StockItemTracking( + item_id=source_item.pk, + part_id=source_item.part_id, + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value, + user=user, + deltas={ + 'removed': float(quantity), + 'quantity': float(source_item.quantity), + }, + ) + ) + + split_events.append(((), {'id': new_item.pk, 'parent': source_item.pk})) + + # Ship stock items for "shipped_items" + for target_item, quantity in shipped_items: + deltas = {'quantity': float(quantity), 'salesorder': order.pk} + + if customer is not None: + deltas['customer'] = customer.pk + deltas['customer_name'] = customer.name + + tracking_entries.append( + stock.models.StockItemTracking( + item_id=target_item.pk, + part_id=target_item.part_id, + tracking_type=StockHistoryCode.SHIPPED_AGAINST_SALES_ORDER.value, + user=user, + deltas=deltas, + ) + ) + + customer_events.append(( + (), + {'id': target_item.pk, 'customer': customer.pk if customer else None}, + )) + + # Flush all StockItem field changes (quantity reductions, and shipment details) + stock.models.StockItem.objects.bulk_update( + seen_stock_items.values(), ['quantity'] + ) + stock.models.StockItem.objects.bulk_update( + [item for item, _ in shipped_items], ['sales_order', 'customer', 'location'] + ) + + stock.models.StockItemTracking.objects.bulk_create(tracking_entries) + + # Update sales order lines for "seen_lines" + SalesOrderLineItem.objects.bulk_update(seen_lines.values(), ['shipped']) + + # Repoint allocations onto their (possibly newly split) StockItem + if allocations_to_update: + SalesOrderAllocation.objects.bulk_update(allocations_to_update, ['item']) + + # Queue the ITEM_SPLIT / ITEM_ASSIGNED_TO_CUSTOMER plugin events in bulk, + # rather than one offload_task() call (and one OrmQ insert) per item + bulk_trigger_event(StockEvents.ITEM_SPLIT, split_events) + bulk_trigger_event(StockEvents.ITEM_ASSIGNED_TO_CUSTOMER, customer_events) + + # bulk_update()/bulk_create() above do not fire StockItem's post_save signal, + # which normally triggers a low-stock check for the affected part - so queue + # that check explicitly, once per distinct part touched by this call + touched_part_ids = {item.part_id for item in seen_stock_items.values()} + + InvenTree.tasks.bulk_offload_task( + part.tasks.notify_low_stock_if_required, + [((part_id,), {}) for part_id in touched_part_ids], + group='notification', + force_async=True, + ) + @transaction.atomic def complete_shipment(self, user, **kwargs): """Complete this particular shipment. @@ -2657,9 +3121,13 @@ class SalesOrderAllocation(models.Model): sales_allocation_count = self.item.sales_order_allocation_count( exclude_allocations={'pk': self.pk} ) + transfer_allocation_count = self.item.transfer_order_allocation_count() total_allocation = ( - build_allocation_count + sales_allocation_count + self.quantity + build_allocation_count + + sales_allocation_count + + transfer_allocation_count + + self.quantity ) if total_allocation > self.item.quantity: @@ -2726,27 +3194,18 @@ class SalesOrderAllocation(models.Model): """Return the PurchaseOrder associated with this allocation.""" return self.item.purchase_order - def complete_allocation(self, user): + def complete_allocation(self, user=None): """Complete this allocation (called when the parent SalesOrder is marked as "shipped"). - Executes: - - Determine if the referenced StockItem needs to be "split" (if allocated quantity != stock quantity) - - Mark the StockItem as belonging to the Customer (this will remove it from stock) + Retained for backwards compatibility with external callers (e.g. plugins) which + complete allocations one at a time - delegates to the bulk + SalesOrderShipment.complete_allocations() implementation. """ - order = self.line.order - - item = self.item.allocateToCustomer( - order.customer, quantity=self.quantity, order=order, user=user + self.shipment.complete_allocations( + SalesOrderAllocation.objects.filter(pk=self.pk), user=user ) - # Update the 'shipped' quantity - self.line.shipped += self.quantity - self.line.save() - - # Update our own reference to the StockItem - # (It may have changed if the stock was split) - self.item = item - self.save() + self.refresh_from_db() class ReturnOrder(TotalPriceMixin, Order): @@ -2777,7 +3236,8 @@ class ReturnOrder(TotalPriceMixin, Order): def report_context(self) -> ReturnOrderReportContext: """Generate report context data for this ReturnOrder.""" return_ctx = super().report_context() - return_ctx.update({'customer': self.customer}) + + return_ctx.update({'customer': self.customer}) # ty:ignore[invalid-key] return return_ctx def get_absolute_url(self): @@ -2890,111 +3350,98 @@ class ReturnOrder(TotalPriceMixin, Order): """Return True if this order is fully received.""" return not self.lines.filter(received_date=None).exists() + # region fsm + + @inventree_transition( + field=status, + source=[ReturnOrderStatus.PENDING, ReturnOrderStatus.IN_PROGRESS], + target=ReturnOrderStatus.ON_HOLD, + event=ReturnOrderEvents.HOLD, + ) + def hold_order(self): + """Transition this ReturnOrder to ON_HOLD status. + + The order must currently be PENDING or IN_PROGRESS. + """ + @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_hold(self): """Return True if this order can be placed on hold.""" - return self.status in [ - ReturnOrderStatus.PENDING.value, - ReturnOrderStatus.IN_PROGRESS.value, - ] + return can_proceed(self.hold_order) - def _action_hold(self, *args, **kwargs): - """Mark this order as 'on hold' (if allowed).""" - if self.can_hold: - self.status = ReturnOrderStatus.ON_HOLD.value - self.save() - - trigger_event(ReturnOrderEvents.HOLD, id=self.pk) + @inventree_transition( + field=status, + source=[ + ReturnOrderStatus.PENDING, + ReturnOrderStatus.ON_HOLD, + ReturnOrderStatus.IN_PROGRESS, + ], + target=ReturnOrderStatus.CANCELLED, + event=ReturnOrderEvents.CANCELLED, + ) + def cancel_order(self): + """Transition this ReturnOrder to CANCELLED status.""" + notify_responsible( + self, + ReturnOrder, + exclude=self.created_by, + content=InvenTreeNotificationBodies.OrderCanceled, + extra_users=self.subscribed_users(), + ) @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_cancel(self): """Return True if this order can be cancelled.""" - return self.status in ReturnOrderStatusGroups.OPEN + return can_proceed(self.cancel_order) - def _action_cancel(self, *args, **kwargs): - """Cancel this ReturnOrder (if not already cancelled).""" - if self.can_cancel: - self.status = ReturnOrderStatus.CANCELLED.value - self.save() + @inventree_transition( + field=status, + source=ReturnOrderStatus.IN_PROGRESS, + target=ReturnOrderStatus.COMPLETE, + event=ReturnOrderEvents.COMPLETED, + ) + def complete_order(self): + """Transition this ReturnOrder to COMPLETE status. - trigger_event(ReturnOrderEvents.CANCELLED, id=self.pk) - - # Notify users that the order has been canceled - notify_responsible( - self, - ReturnOrder, - exclude=self.created_by, - content=InvenTreeNotificationBodies.OrderCanceled, - extra_users=self.subscribed_users(), - ) - - def _action_complete(self, *args, **kwargs): - """Complete this ReturnOrder (if not already completed).""" - if self.status == ReturnOrderStatus.IN_PROGRESS.value: - self.status = ReturnOrderStatus.COMPLETE.value - self.complete_date = InvenTree.helpers.current_date() - self.save() - - trigger_event(ReturnOrderEvents.COMPLETED, id=self.pk) + The order must currently be IN_PROGRESS. + """ + self.complete_date = InvenTree.helpers.current_date() + @deprecated('Use issue_order directly', version='1.5.0') def place_order(self): - """Deprecated version of 'issue_order.""" - self.issue_order() + """Deprecated version of 'issue_order'.""" + return self.issue_order() @property - def can_issue(self): + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') + def can_issue(self) -> bool: """Return True if this order can be issued.""" - return self.status in [ - ReturnOrderStatus.PENDING.value, - ReturnOrderStatus.ON_HOLD.value, - ] + return can_proceed(self.issue_order) - def _action_place(self, *args, **kwargs): - """Issue this ReturnOrder (if currently pending).""" - if self.can_issue: - self.status = ReturnOrderStatus.IN_PROGRESS.value - self.issue_date = InvenTree.helpers.current_date() - self.save() - - trigger_event(ReturnOrderEvents.ISSUED, id=self.pk) - - # Notify users that the order has been placed - notify_responsible( - self, - ReturnOrder, - exclude=self.created_by, - content=InvenTreeNotificationBodies.NewOrder, - extra_users=self.subscribed_users(), - ) - - @transaction.atomic - def hold_order(self): - """Attempt to transition to ON_HOLD status.""" - return self.handle_transition( - self.status, ReturnOrderStatus.ON_HOLD.value, self, self._action_hold - ) - - @transaction.atomic + @inventree_transition( + field=status, + source=[ReturnOrderStatus.PENDING, ReturnOrderStatus.ON_HOLD], + target=ReturnOrderStatus.IN_PROGRESS, + event=ReturnOrderEvents.ISSUED, + ) def issue_order(self): - """Attempt to transition to IN_PROGRESS status.""" - return self.handle_transition( - self.status, ReturnOrderStatus.IN_PROGRESS.value, self, self._action_place - ) - - @transaction.atomic - def complete_order(self): - """Attempt to transition to COMPLETE status.""" - return self.handle_transition( - self.status, ReturnOrderStatus.COMPLETE.value, self, self._action_complete - ) - - @transaction.atomic - def cancel_order(self): - """Attempt to transition to CANCELLED status.""" - return self.handle_transition( - self.status, ReturnOrderStatus.CANCELLED.value, self, self._action_cancel + """Transition this ReturnOrder to IN_PROGRESS status. + + The order must currently be PENDING or ON_HOLD. + """ + self.issue_date = InvenTree.helpers.current_date() + + notify_responsible( + self, + ReturnOrder, + exclude=self.created_by, + content=InvenTreeNotificationBodies.NewOrder, + extra_users=self.subscribed_users(), ) + # endregion fsm # endregion @transaction.atomic @@ -3016,6 +3463,12 @@ class ReturnOrder(TotalPriceMixin, Order): - Adds a tracking entry to the StockItem - Removes the 'customer' reference from the StockItem """ + # Lock the line item row against concurrent receipt, and re-read it + # from the database. Without this, two simultaneous receipt requests + # can both observe received_date=None, and each would split / process + # the associated stock item. + line = ReturnOrderLineItem.objects.select_for_update().get(pk=line.pk) + # Prevent an item from being "received" multiple times if line.received_date is not None: logger.warning('receive_line_item called with item already returned') @@ -3207,7 +3660,7 @@ class TransferOrder(Order): REFERENCE_PATTERN_SETTING = 'TRANSFERORDER_REFERENCE_PATTERN' REQUIRE_RESPONSIBLE_SETTING = 'TRANSFERORDER_REQUIRE_RESPONSIBLE' STATUS_CLASS = TransferOrderStatus - # UNLOCK_SETTING = 'TRANSFERORDER_EDIT_COMPLETED_ORDERS' + UNLOCK_SETTING = 'TRANSFERORDER_EDIT_COMPLETED_ORDERS' class Meta: """Model meta options.""" @@ -3367,6 +3820,7 @@ class TransferOrder(Order): """Check if this order is "transferred" (all line items transferred).""" return all(line.is_completed() for line in self.lines.all()) + # region fsm def can_complete( self, raise_error: bool = False, allow_incomplete_lines: bool = False ) -> bool: @@ -3396,139 +3850,87 @@ class TransferOrder(Order): return True @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_issue(self) -> bool: """Return True if this order can be issued.""" - return self.status in [ - TransferOrderStatus.PENDING.value, - TransferOrderStatus.ON_HOLD.value, - ] + return can_proceed(self.issue_order) - @transaction.atomic + @inventree_transition( + field=status, + source=[TransferOrderStatus.PENDING, TransferOrderStatus.ON_HOLD], + target=TransferOrderStatus.ISSUED, + event=TransferOrderEvents.ISSUED, + ) def issue_order(self): - """Attempt to transition to PLACED status.""" - return self.handle_transition( - self.status, TransferOrderStatus.ISSUED.value, self, self._action_issue + """Transition this TransferOrder to ISSUED status. + + The order must currently be PENDING or ON_HOLD. + """ + self.issue_date = InvenTree.helpers.current_date() + + notify_responsible( + self, + TransferOrder, + exclude=self.created_by, + content=InvenTreeNotificationBodies.NewOrder, + extra_users=self.subscribed_users(), ) - # region state changes - def _action_issue(self, *args, **kwargs): - """Marks the TransferOrder as ISSUED. - - Order must be currently PENDING. - """ - if self.can_issue: - self.status = TransferOrderStatus.ISSUED.value - self.issue_date = InvenTree.helpers.current_date() - self.save() - - trigger_event(TransferOrderEvents.ISSUED, id=self.pk) - - # Notify users that the order has been issued - notify_responsible( - self, - TransferOrder, - exclude=self.created_by, - content=InvenTreeNotificationBodies.NewOrder, - extra_users=self.subscribed_users(), - ) - @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') def can_hold(self) -> bool: """Return True if this order can be placed on hold.""" - return self.status in [ - TransferOrderStatus.PENDING.value, - TransferOrderStatus.ISSUED.value, - ] + return can_proceed(self.hold_order) - def _action_hold(self, *args, **kwargs): - """Mark this transfer order as 'on hold'.""" - if self.can_hold: - self.status = TransferOrderStatus.ON_HOLD.value - self.save() - - trigger_event(TransferOrderEvents.HOLD, id=self.pk) - - @transaction.atomic - def _action_complete(self, *args, **kwargs): - """Marks the TransferOrder as COMPLETE. - - Order must be currently ISSUED. - """ - user = kwargs.pop('user', None) - - if not self.can_complete(raise_error=True, **kwargs): - return False - - if self.status == TransferOrderStatus.ISSUED: - for allocation in self.allocations(): - # execute each transfer - allocation.complete_allocation(user) - - self.status = TransferOrderStatus.COMPLETE.value - self.complete_date = InvenTree.helpers.current_date() - - self.save() - - trigger_event(TransferOrderEvents.COMPLETED, id=self.pk) - - return True - - @transaction.atomic - def complete_order(self, user, **kwargs): - """Attempt to transition to COMPLETE status.""" - return self.handle_transition( - self.status, - TransferOrderStatus.COMPLETE.value, - self, - self._action_complete, - user=user, - **kwargs, - ) - - @transaction.atomic + @inventree_transition( + field=status, + source=[TransferOrderStatus.PENDING, TransferOrderStatus.ISSUED], + target=TransferOrderStatus.ON_HOLD, + event=TransferOrderEvents.HOLD, + ) def hold_order(self): - """Attempt to transition to ON_HOLD status.""" - return self.handle_transition( - self.status, TransferOrderStatus.ON_HOLD.value, self, self._action_hold - ) + """Transition this TransferOrder to ON_HOLD status.""" - @transaction.atomic + @inventree_transition( + field=status, + source=TransferOrderStatus.ISSUED, + target=TransferOrderStatus.COMPLETE, + event=TransferOrderEvents.COMPLETED, + ) + def complete_order(self, user=None, **kwargs): + """Transition this TransferOrder to COMPLETE status. + + The order must currently be ISSUED and meet all completion requirements. + """ + if not user: + user = kwargs.pop('user', None) + + self.can_complete(raise_error=True, **kwargs) + + for allocation in self.allocations(): + allocation.complete_allocation(user) + + self.complete_date = InvenTree.helpers.current_date() + + @inventree_transition( + field=status, + source=[ + TransferOrderStatus.PENDING, + TransferOrderStatus.ON_HOLD, + TransferOrderStatus.ISSUED, + ], + target=TransferOrderStatus.CANCELLED, + event=TransferOrderEvents.CANCELLED, + ) def cancel_order(self): - """Attempt to transition to CANCELLED status.""" - return self.handle_transition( - self.status, TransferOrderStatus.CANCELLED.value, self, self._action_cancel - ) + """Transition this TransferOrder to CANCELLED status. - @property - def can_cancel(self) -> bool: - """A TransferOrder can only be cancelled under the following circumstances. - - - Status is ISSUED - - Status is PENDING (or ON_HOLD) + Deletes all pending stock allocations. """ - return self.status in TransferOrderStatusGroups.OPEN - - def _action_cancel(self, *args, **kwargs): - """Cancel this TransferOrder (only if we're allowed to). - - Executes: - - Mark the order as 'cancelled' - - Delete any StockItems which have been allocated - """ - if not self.can_cancel: - return False - - self.status = TransferOrderStatus.CANCELLED.value - self.save() - - # delete allocations for line in self.lines.all(): for allocation in line.allocations.all(): allocation.delete() - trigger_event(TransferOrderEvents.CANCELLED, id=self.pk) - - # Notify users that the order has been canceled notify_responsible( self, TransferOrder, @@ -3537,7 +3939,17 @@ class TransferOrder(Order): extra_users=self.subscribed_users(), ) - # endregion + @property + @deprecated(Deprecations.CAN_PROCEED, version='1.5.0') + def can_cancel(self) -> bool: + """A TransferOrder can only be cancelled while it is open. + + - Status is ISSUED + - Status is PENDING (or ON_HOLD) + """ + return can_proceed(self.cancel_order) + + # endregion fsm @property def line_count(self) -> int: @@ -3712,9 +4124,15 @@ class TransferOrderAllocation(models.Model): sales_allocation_count = self.item.sales_order_allocation_count( exclude_allocations={'pk': self.pk} ) + transfer_allocation_count = self.item.transfer_order_allocation_count( + exclude_allocations={'pk': self.pk} + ) total_allocation = ( - build_allocation_count + sales_allocation_count + self.quantity + build_allocation_count + + sales_allocation_count + + transfer_allocation_count + + self.quantity ) if total_allocation > self.item.quantity: @@ -3774,46 +4192,79 @@ class TransferOrderAllocation(models.Model): - Move the StockItem to the new location - Updates the transferred qty - If order is marked as "consume", reduce quantity rather than move + + Raises: + ValidationError: If the stock operation fails - the 'transferred' quantity + is only updated once the stock has actually been moved / consumed. """ order: TransferOrder = self.line.order self.item: stock.models.StockItem # for type hints self.line: TransferOrderLineItem # for type hints + # Lock the stock item's row and refresh its quantity, so the branch + # selected below (consume / split / move) is chosen using the current + # committed quantity rather than a stale in-memory copy + if not self.item.lock_quantity(): + raise ValidationError(_('Stock item no longer exists')) + # The allocation is the only thing linking this stock item to the transfer # As a result, we must keep the allocation present even after completion # This means allocations to transfer orders don't affect "available" stock # (otherwise it would permanently reduce available stock) + # The stock item may have been reduced since the allocation was made, + # so limit the transfer to the quantity which is actually available + transfer_quantity = min(self.quantity, self.item.quantity) + + if transfer_quantity <= 0: + # Nothing available to transfer (e.g. the item has since been depleted) + return + if order.consume: # rather than transferring the stock, we simply reduce its quantity to release it from tracked inventory # NOTE: if delete_on_deplete is enabled, this will result in the "transferred stock" panel being empty - # after completion. A more sophesticated immutable tracking that doesn't rely on allocations + # after completion. A more sophisticated immutable tracking that doesn't rely on allocations # would be helpful here - self.item.take_stock( - quantity=self.quantity, + if not self.item.take_stock( + quantity=transfer_quantity, user=user, code=StockHistoryCode.STOCK_REMOVE, transferorder=order, - ) - else: - if self.quantity < self.item.quantity: - # update our own reference to the StockItem which was split - self.item = self.item.splitStock( - quantity=self.quantity, - location=order.destination, - user=user, - transferorder=order, + ): + raise ValidationError( + _('Failed to consume stock item against transfer order') ) - self.save() - else: - # move item directly, we don't have to split - self.item.move( - location=order.destination, user=user, transferorder=order, notes='' + elif transfer_quantity < self.item.quantity: + new_item = self.item.splitStock( + quantity=transfer_quantity, + location=order.destination, + user=user, + transferorder=order, + ) + + if new_item is None: + raise ValidationError( + _('Failed to transfer stock item against transfer order') + ) + + # update our own reference to the StockItem which was split + self.item = new_item + self.save() + else: + # move item directly, we don't have to split + if not self.item.move( + location=order.destination, user=user, transferorder=order, notes='' + ): + raise ValidationError( + _('Failed to transfer stock item against transfer order') ) # Update the transferred qty - self.line.transferred += self.quantity - self.line.save() + # Note: use the quantity which was *actually* transferred + # Increment at the database level to prevent lost updates + self.line.transferred = F('transferred') + transfer_quantity + self.line.save(update_fields=['transferred']) + self.line.refresh_from_db(fields=['transferred']) def _touch_order_updated_at(instance): diff --git a/src/backend/InvenTree/order/serializers.py b/src/backend/InvenTree/order/serializers.py index c2d1b909ac..027d2e994d 100644 --- a/src/backend/InvenTree/order/serializers.py +++ b/src/backend/InvenTree/order/serializers.py @@ -26,19 +26,24 @@ from company.serializers import ( ContactSerializer, SupplierPartSerializer, ) +from data_exporter.mixins import DataExportSerializerMixin from generic.states.fields import InvenTreeCustomStatusSerializerMixin from importer.registry import register_importer from InvenTree.helpers import extract_serial_numbers, hash_barcode, normalize, str2bool from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.serializers import ( + CustomStatusSerializerMixin, + DuplicateOptionsSerializer, FilterableSerializerMixin, InvenTreeCurrencySerializer, InvenTreeDecimalField, InvenTreeModelSerializer, InvenTreeMoneySerializer, + InvenTreeTaggitSerializer, NotesFieldMixin, OptionalField, ) +from InvenTree.tasks import batch_offload_tasks from order.status_codes import ( PurchaseOrderStatusGroups, ReturnOrderLineStatus, @@ -47,6 +52,8 @@ from order.status_codes import ( TransferOrderStatusGroups, ) from part.serializers import PartBriefSerializer +from plugin.base.event.events import batch_events +from stock.models import batch_tracking_entries from stock.status_codes import StockStatus from users.serializers import OwnerSerializer, UserSerializer @@ -65,48 +72,18 @@ class TotalPriceMixin(serializers.Serializer): ) -class DuplicateOrderSerializer(serializers.Serializer): - """Serializer for specifying options when duplicating an order.""" - - class Meta: - """Metaclass options.""" - - fields = ['order_id', 'copy_lines', 'copy_extra_lines', 'copy_parameters'] - - order_id = serializers.IntegerField( - required=True, label=_('Order ID'), help_text=_('ID of the order to duplicate') - ) - - copy_lines = serializers.BooleanField( - required=False, - default=True, - label=_('Copy Lines'), - help_text=_('Copy line items from the original order'), - ) - - copy_extra_lines = serializers.BooleanField( - required=False, - default=True, - label=_('Copy Extra Lines'), - help_text=_('Copy extra line items from the original order'), - ) - - copy_parameters = serializers.BooleanField( - required=False, - default=True, - label=_('Copy Parameters'), - help_text=_('Copy order parameters from the original order'), - ) - - class AbstractOrderSerializer( - DataImportExportSerializerMixin, FilterableSerializerMixin, serializers.Serializer + CustomStatusSerializerMixin, + DataImportExportSerializerMixin, + InvenTreeTaggitSerializer, + FilterableSerializerMixin, + serializers.Serializer, ): """Abstract serializer class which provides fields common to all order types.""" - export_exclude_fields = ['notes', 'duplicate'] + export_exclude_fields = ['notes'] - import_exclude_fields = ['notes', 'duplicate'] + import_exclude_fields = ['notes'] # Number of line items in this order line_items = serializers.IntegerField( @@ -118,12 +95,17 @@ class AbstractOrderSerializer( read_only=True, allow_null=True, label=_('Completed Lines') ) - # Human-readable status text (read-only) - status_text = serializers.CharField(source='get_status_display', read_only=True) - # status field cannot be set directly status = serializers.IntegerField(read_only=True, label=_('Order Status')) + # can be set directly, but must be valid for the current order status + status_custom_key = serializers.IntegerField( + label=_('Custom Status Key'), + help_text=_('Update order status to a custom value for this logical value'), + allow_null=True, + default=None, + ) + # Reference string is *required* reference = serializers.CharField(required=True) @@ -171,6 +153,8 @@ class AbstractOrderSerializer( parameters = common.filters.enable_parameters_filter() + tags = common.filters.enable_tags_filter() + # Boolean field indicating if this order is overdue (Note: must be annotated) overdue = serializers.BooleanField(read_only=True, allow_null=True) @@ -182,18 +166,39 @@ class AbstractOrderSerializer( created_by = UserSerializer(read_only=True) - duplicate = DuplicateOrderSerializer( - label=_('Duplicate Order'), - help_text=_('Specify options for duplicating this order'), - required=False, - write_only=True, - ) + # Note: The 'duplicate' field must be defined by each concrete serializer class, + # as it requires a queryset specific to the order model type def validate_reference(self, reference): """Custom validation for the reference field.""" self.Meta.model.validate_reference_field(reference) return reference + def validate_status_custom_key(self, value): + """Validate the status_custom_key field. + + Ensure the custom status key is valid for the logical order status. + """ + if value is None: + return value + + from generic.states.custom import get_logical_value + + if not isinstance(value, int): + raise ValidationError(_('Custom status key must be an integer')) + + try: + custom_status = get_logical_value( + value, model=self.Meta.model._meta.model_name + ) + except: + raise ValidationError(_('Invalid custom status key')) + + if custom_status.logical_key is not self.instance.status: + raise ValidationError(_('Invalid custom status key for this order status')) + + return value + @staticmethod def annotate_queryset(queryset): """Add extra information to the queryset.""" @@ -235,6 +240,7 @@ class AbstractOrderSerializer( 'project_code_label', 'responsible_detail', 'parameters', + 'tags', *extra_fields, ] @@ -254,30 +260,21 @@ class AbstractOrderSerializer( instance = super().create(validated_data) if duplicate: - order_id = duplicate.get('order_id', None) - copy_lines = duplicate.get('copy_lines', True) - copy_extra_lines = duplicate.get('copy_extra_lines', True) - copy_parameters = duplicate.get('copy_parameters', True) + original = duplicate['original'] - try: - copy_from = instance.__class__.objects.get(pk=order_id) - except Exception: - # If the order ID is invalid, raise a validation error - raise ValidationError(_('Invalid order ID')) - - if copy_lines: - for line in copy_from.lines.all(): + if duplicate.get('copy_lines', False): + for line in original.lines.all(): instance.clean_line_item(line) line.save() - if copy_extra_lines: - for line in copy_from.extra_lines.all(): + if duplicate.get('copy_extra_lines', False): + for line in original.extra_lines.all(): line.pk = None line.order = instance line.save() - if copy_parameters: - instance.copy_parameters_from(copy_from) + if duplicate.get('copy_parameters', False): + instance.copy_parameters_from(original) return instance @@ -309,6 +306,8 @@ class AbstractLineItemSerializer(FilterableSerializerMixin, serializers.Serializ required=False, allow_null=True, label=_('Target Date') ) + discount = InvenTreeDecimalField(required=False) + project_code_label = common.filters.enable_project_label_filter() project_code_detail = common.filters.enable_project_code_filter() @@ -326,6 +325,7 @@ class AbstractExtraLineSerializer( 'pk', 'line', 'description', + 'discount', 'link', 'notes', 'order', @@ -335,6 +335,7 @@ class AbstractExtraLineSerializer( 'quantity', 'reference', 'target_date', + 'total_price', # Filterable detail fields 'order_detail', 'project_code_label', @@ -344,10 +345,16 @@ class AbstractExtraLineSerializer( quantity = serializers.FloatField() + discount = InvenTreeDecimalField(required=False) + price = InvenTreeMoneySerializer(allow_null=True) price_currency = InvenTreeCurrencySerializer() + total_price = InvenTreeMoneySerializer( + source='total_line_price', allow_null=True, read_only=True + ) + project_code_label = common.filters.enable_project_label_filter() project_code_detail = common.filters.enable_project_code_filter() @@ -359,6 +366,7 @@ class AbstractExtraLineMeta: fields = [ 'pk', 'description', + 'discount', 'quantity', 'reference', 'notes', @@ -367,6 +375,7 @@ class AbstractExtraLineMeta: 'order_detail', 'price', 'price_currency', + 'total_price', 'link', ] @@ -413,6 +422,13 @@ class PurchaseOrderSerializer( return [*fields, 'duplicate'] + duplicate = DuplicateOptionsSerializer( + order.models.PurchaseOrder.objects.all(), + copy_lines=True, + copy_extra_lines=True, + copy_parameters=True, + ) + @staticmethod def annotate_queryset(queryset): """Add extra information to the queryset. @@ -555,6 +571,7 @@ class PurchaseOrderLineItemSerializer( fields = AbstractLineItemSerializer.line_fields([ 'part', 'build_order', + 'discount', 'overdue', 'received', 'purchase_price', @@ -583,7 +600,6 @@ class PurchaseOrderLineItemSerializer( def annotate_queryset(queryset): """Add some extra annotations to this queryset. - - "total_price" = purchase_price * quantity - "overdue" status (boolean field) """ queryset = queryset.prefetch_related( @@ -599,12 +615,6 @@ class PurchaseOrderLineItemSerializer( 'part__manufacturer_part__manufacturer', ) - queryset = queryset.annotate( - total_price=ExpressionWrapper( - F('purchase_price') * F('quantity'), output_field=models.DecimalField() - ) - ) - queryset = queryset.annotate( overdue=Case( When( @@ -645,7 +655,9 @@ class PurchaseOrderLineItemSerializer( overdue = serializers.BooleanField(read_only=True, allow_null=True) - total_price = serializers.FloatField(read_only=True) + total_price = InvenTreeMoneySerializer( + source='total_line_price', allow_null=True, read_only=True + ) part_detail = OptionalField( serializer_class=PartBriefSerializer, @@ -733,6 +745,14 @@ class PurchaseOrderLineItemSerializer( write_only=True, ) + def __init__(self, *args, **kwargs): + """Set dynamic defaults for create-only fields.""" + super().__init__(*args, **kwargs) + + self.fields['merge_items'].default = get_global_setting( + 'PURCHASEORDER_MERGE_LINE_ITEMS', backup_value=True + ) + sku = serializers.CharField( source='part.SKU', read_only=True, allow_null=True, label=_('SKU') ) @@ -1007,6 +1027,13 @@ class PurchaseOrderReceiveSerializer(serializers.Serializer): # Ensure barcodes are unique unique_barcodes = set() + # Ensure serial numbers are unique across all line items in this request + # (each line is only validated against the *database* individually) + unique_serials = set() + serials_globally_unique = get_global_setting( + 'SERIAL_NUMBER_GLOBALLY_UNIQUE', False + ) + # Check if the location is not specified for any particular item for item in items: line = item['line_item'] @@ -1032,6 +1059,25 @@ class PurchaseOrderReceiveSerializer(serializers.Serializer): else: unique_barcodes.add(barcode) + if serials := item.get('serials'): + if line.part: + # Scope uniqueness the same way as the database check: + # per part tree, or globally (if so configured) + for serial in serials: + key = ( + str(serial) + if serials_globally_unique + else (line.part.part.tree_id, str(serial)) + ) + + if key in unique_serials: + raise ValidationError( + _('Supplied serial numbers must be unique') + + f': {serial}' + ) + + unique_serials.add(key) + return data def save(self) -> list[stock.models.StockItem]: @@ -1047,9 +1093,15 @@ class PurchaseOrderReceiveSerializer(serializers.Serializer): location = data.get('location', order.destination) try: - items = order.receive_line_items( - location, items, request.user if request else None - ) + with ( + transaction.atomic(), + batch_events(), + batch_tracking_entries(), + batch_offload_tasks(), + ): + items = order.receive_line_items( + location, items, request.user if request else None + ) except (ValidationError, DjangoValidationError) as exc: # Catch model errors and re-throw as DRF errors raise ValidationError(detail=serializers.as_serializer_error(exc)) @@ -1064,6 +1116,7 @@ class SalesOrderSerializer( TotalPriceMixin, InvenTreeCustomStatusSerializerMixin, AbstractOrderSerializer, + InvenTreeTaggitSerializer, InvenTreeModelSerializer, ): """Serializer for the SalesOrder model class.""" @@ -1083,6 +1136,7 @@ class SalesOrderSerializer( 'completed_shipments_count', 'allocated_lines', 'updated_at', + 'tags', ]) read_only_fields = ['status', 'creation_date', 'shipment_date', 'updated_at'] extra_kwargs = {'order_currency': {'required': False}} @@ -1093,6 +1147,13 @@ class SalesOrderSerializer( return [*fields, 'duplicate'] + duplicate = DuplicateOptionsSerializer( + order.models.SalesOrder.objects.all(), + copy_lines=True, + copy_extra_lines=True, + copy_parameters=True, + ) + @staticmethod def annotate_queryset(queryset): """Add extra information to the queryset. @@ -1164,6 +1225,8 @@ class SalesOrderSerializer( read_only=True, allow_null=True, label=_('Allocated Lines') ) + tags = common.filters.enable_tags_filter() + class SalesOrderIssueSerializer(OrderAdjustSerializer): """Serializer for issuing a SalesOrder.""" @@ -1188,6 +1251,7 @@ class SalesOrderLineItemSerializer( fields = AbstractLineItemSerializer.line_fields([ 'allocated', 'customer_detail', + 'discount', 'overdue', 'part', 'part_detail', @@ -1362,11 +1426,14 @@ class SalesOrderLineItemSerializer( class SalesOrderShipmentSerializer( DataImportExportSerializerMixin, FilterableSerializerMixin, + InvenTreeTaggitSerializer, NotesFieldMixin, InvenTreeModelSerializer, ): """Serializer for the SalesOrderShipment class.""" + SKIP_CREATE_FIELDS = ['duplicate'] + class Meta: """Metaclass options.""" @@ -1379,6 +1446,7 @@ class SalesOrderShipmentSerializer( 'shipment_address', 'delivery_date', 'checked_by', + 'duplicate', 'reference', 'tracking_number', 'invoice_number', @@ -1391,6 +1459,7 @@ class SalesOrderShipmentSerializer( 'customer_detail', 'order_detail', 'shipment_address_detail', + 'tags', ] @staticmethod @@ -1460,9 +1529,30 @@ class SalesOrderShipmentSerializer( parameters = common.filters.enable_parameters_filter() + tags = common.filters.enable_tags_filter() + + duplicate = DuplicateOptionsSerializer( + order.models.SalesOrderShipment.objects.all(), copy_parameters=True + ) + + @transaction.atomic + def create(self, validated_data): + """Create a new SalesOrderShipment instance, optionally copying data from an existing shipment.""" + duplicate = validated_data.pop('duplicate', None) + + instance = super().create(validated_data) + + if duplicate: + original = duplicate['original'] + + if duplicate.get('copy_parameters', True): + instance.copy_parameters_from(original) + + return instance + class SalesOrderAllocationSerializer( - FilterableSerializerMixin, InvenTreeModelSerializer + DataExportSerializerMixin, FilterableSerializerMixin, InvenTreeModelSerializer ): """Serializer for the SalesOrderAllocation model. @@ -1825,104 +1915,23 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer): return shipment - def validate(self, data): - """Validation for the serializer. - - - Ensure the serial_numbers and quantity fields match - - Check that all serial numbers exist - - Check that the serial numbers are not yet allocated - """ - data = super().validate(data) + def save(self): + """Allocate stock items against the sales order, by serial number.""" + data = self.validated_data + sales_order = self.context['order'] line_item = data['line_item'] quantity = data['quantity'] serial_numbers = data['serial_numbers'] - - part = line_item.part - - try: - data['serials'] = extract_serial_numbers( - serial_numbers, quantity, part.get_latest_serial_number(), part=part - ) - except DjangoValidationError as e: - raise ValidationError({'serial_numbers': e.messages}) - - serials_not_exist = set() - serials_unavailable = set() - stock_items_to_allocate = [] - - for serial in data['serials']: - serial = str(serial).strip() - - items = stock.models.StockItem.objects.filter( - part=part, serial=serial, quantity=1 - ) - - if not items.exists(): - serials_not_exist.add(str(serial)) - continue - - stock_item = items[0] - - if get_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS'): - if ( - stock_item.hasRequiredTests() - and not stock_item.passedAllRequiredTests() - ): - serials_unavailable.add(str(serial)) - continue - - if not stock_item.in_stock: - serials_unavailable.add(str(serial)) - continue - - if stock_item.unallocated_quantity() < 1: - serials_unavailable.add(str(serial)) - continue - - # At this point, the serial number is valid, and can be added to the list - stock_items_to_allocate.append(stock_item) - - if len(serials_not_exist) > 0: - error_msg = _('No match found for the following serial numbers') - error_msg += ': ' - error_msg += ','.join(sorted(serials_not_exist)) - - raise ValidationError({'serial_numbers': error_msg}) - - if len(serials_unavailable) > 0: - error_msg = _('The following serial numbers are unavailable') - error_msg += ': ' - error_msg += ','.join(sorted(serials_unavailable)) - - raise ValidationError({'serial_numbers': error_msg}) - - data['stock_items'] = stock_items_to_allocate - - return data - - def save(self): - """Allocate stock items against the sales order.""" - data = self.validated_data - - line_item = data['line_item'] - stock_items = data['stock_items'] shipment = data.get('shipment', None) - allocations = [] - - for stock_item in stock_items: - # Create a new SalesOrderAllocation - allocations.append( - order.models.SalesOrderAllocation( - line=line_item, item=stock_item, quantity=1, shipment=shipment - ) - ) - - with transaction.atomic(): - order.models.SalesOrderAllocation.objects.bulk_create( - allocations, batch_size=250 + try: + return sales_order.allocate_serial_numbers( + line_item, quantity, serial_numbers, shipment=shipment ) + except (ValidationError, DjangoValidationError) as exc: + # Catch model errors and re-throw as DRF errors + raise ValidationError(detail=serializers.as_serializer_error(exc)) class SalesOrderShipmentAllocationSerializer(serializers.Serializer): @@ -1978,10 +1987,20 @@ class SalesOrderShipmentAllocationSerializer(serializers.Serializer): with transaction.atomic(): for entry in items: + stock_item = entry.get('stock_item') + + # Lock the StockItem row, so that concurrent allocation requests are + # serialized against each other, and full_clean() below re-validates + # against the now-current (and now-locked) allocation counts + if not stock_item.lock_quantity(): + raise ValidationError({ + 'stock_item': _('Stock item no longer exists') + }) + # Create a new SalesOrderAllocation allocation = order.models.SalesOrderAllocation( line=entry.get('line_item'), - item=entry.get('stock_item'), + item=stock_item, quantity=entry.get('quantity'), shipment=shipment, ) @@ -1990,6 +2009,113 @@ class SalesOrderShipmentAllocationSerializer(serializers.Serializer): allocation.save() +class SalesOrderAutoAllocationSerializer(serializers.Serializer): + """DRF serializer for auto-allocating stock items against a SalesOrder.""" + + class Meta: + """Serializer metaclass.""" + + fields = [ + 'location', + 'exclude_location', + 'shipment', + 'interchangeable', + 'stock_sort_by', + 'serialized_stock', + 'line_items', + ] + + location = serializers.PrimaryKeyRelatedField( + queryset=stock.models.StockLocation.objects.all(), + many=False, + allow_null=True, + required=False, + label=_('Source Location'), + help_text=_( + 'Stock location where items are sourced (leave blank to use any location)' + ), + ) + + exclude_location = serializers.PrimaryKeyRelatedField( + queryset=stock.models.StockLocation.objects.all(), + many=False, + allow_null=True, + required=False, + label=_('Exclude Location'), + help_text=_('Exclude stock items from this location'), + ) + + shipment = serializers.PrimaryKeyRelatedField( + queryset=order.models.SalesOrderShipment.objects.all(), + many=False, + allow_null=True, + required=False, + label=_('Shipment'), + help_text=_('Assign allocations to this shipment'), + ) + + interchangeable = serializers.BooleanField( + default=True, + label=_('Interchangeable Stock'), + help_text=_( + 'Allow stock to be taken from multiple locations to fulfil a single line item' + ), + ) + + stock_sort_by = serializers.ChoiceField( + default=stock.models.STOCK_SORT_DEFAULT, + choices=stock.models.STOCK_SORT_CHOICES, + label=_('Stock Priority'), + help_text=_('Preferred order in which matching stock items are consumed'), + ) + + serialized_stock = serializers.ChoiceField( + default=order.models.SERIALIZED_STOCK_DEFAULT, + choices=order.models.SERIALIZED_STOCK_CHOICES, + label=_('Serialized Stock'), + help_text=_( + 'Control whether serialized stock items are included in auto-allocation' + ), + ) + + line_items = serializers.PrimaryKeyRelatedField( + queryset=order.models.SalesOrderLineItem.objects.all(), + many=True, + required=False, + default=list, + label=_('Line Items'), + help_text=_( + 'Limit allocation to these line items (leave blank to allocate all lines)' + ), + ) + + def validate_shipment(self, shipment): + """Validate that the shipment belongs to this order and is not yet shipped.""" + order_obj = self.context.get('order') + + if shipment is None: + return shipment + + if shipment.shipment_date is not None: + raise ValidationError(_('Shipment has already been shipped')) + + if order_obj and shipment.order != order_obj: + raise ValidationError(_('Shipment is not associated with this order')) + + return shipment + + def validate_line_items(self, line_items): + """Validate that all provided line items belong to this order.""" + order_obj = self.context.get('order') + + if order_obj and line_items: + for line in line_items: + if line.order != order_obj: + raise ValidationError(_('Line item does not belong to this order')) + + return line_items + + @register_importer() class SalesOrderExtraLineSerializer( AbstractExtraLineSerializer, InvenTreeModelSerializer @@ -2044,6 +2170,14 @@ class ReturnOrderSerializer( return [*fields, 'duplicate'] + # Note: line items cannot be duplicated from a ReturnOrder, + # as they are linked to specific stock items + duplicate = DuplicateOptionsSerializer( + order.models.ReturnOrder.objects.all(), + copy_extra_lines=True, + copy_parameters=True, + ) + @staticmethod def annotate_queryset(queryset): """Custom annotation for the serializer queryset.""" @@ -2225,6 +2359,7 @@ class ReturnOrderLineItemSerializer( 'item', 'received_date', 'outcome', + 'discount', 'price', 'price_currency', # Filterable detail fields @@ -2331,6 +2466,11 @@ class TransferOrderSerializer( return [*fields, 'duplicate'] + # Note: TransferOrder does not have "extra" line items + duplicate = DuplicateOptionsSerializer( + order.models.TransferOrder.objects.all(), copy_lines=True, copy_parameters=True + ) + @staticmethod def annotate_queryset(queryset): """Add extra information to the queryset. @@ -2698,10 +2838,20 @@ class TransferOrderLineItemAllocationSerializer(serializers.Serializer): with transaction.atomic(): for entry in items: + stock_item = entry.get('stock_item') + + # Lock the StockItem row, so that concurrent allocation requests are + # serialized against each other, and full_clean() below re-validates + # against the now-current (and now-locked) allocation counts + if not stock_item.lock_quantity(): + raise ValidationError({ + 'stock_item': _('Stock item no longer exists') + }) + # Create a new TransferOrderAllocation allocation = order.models.TransferOrderAllocation( line=entry.get('line_item'), - item=entry.get('stock_item'), + item=stock_item, quantity=entry.get('quantity'), ) @@ -2835,8 +2985,10 @@ class TransferOrderSerialAllocationSerializer(serializers.Serializer): """Validation for the serializer. - Ensure the serial_numbers and quantity fields match - - Check that all serial numbers exist - - Check that the serial numbers are not yet allocated + + Note: Resolving serial numbers to StockItem objects (and checking their + availability) is deferred to save(), where it can be done under a + database lock - see save() for details. """ data = super().validate(data) @@ -2853,11 +3005,29 @@ class TransferOrderSerialAllocationSerializer(serializers.Serializer): except DjangoValidationError as e: raise ValidationError({'serial_numbers': e.messages}) + return data + + @transaction.atomic + def save(self): + """Allocate stock items against the transfer order. + + Stock items are resolved from the requested serial numbers, and locked + (select_for_update, via StockItem.lock_quantity()) before their + availability is checked - this serializes concurrent allocation requests + against each other, so two requests cannot both allocate the same + serialized StockItem. + """ + data = self.validated_data + + line_item = data['line_item'] + serials = data['serials'] + part = line_item.part + serials_not_exist = set() serials_unavailable = set() - stock_items_to_allocate = [] + allocations = [] - for serial in data['serials']: + for serial in serials: serial = str(serial).strip() items = stock.models.StockItem.objects.filter( @@ -2874,12 +3044,20 @@ class TransferOrderSerialAllocationSerializer(serializers.Serializer): serials_unavailable.add(str(serial)) continue + if not stock_item.lock_quantity(): + serials_unavailable.add(str(serial)) + continue + if stock_item.unallocated_quantity() < 1: serials_unavailable.add(str(serial)) continue # At this point, the serial number is valid, and can be added to the list - stock_items_to_allocate.append(stock_item) + allocations.append( + order.models.TransferOrderAllocation( + line=line_item, item=stock_item, quantity=1 + ) + ) if len(serials_not_exist) > 0: error_msg = _('No match found for the following serial numbers') @@ -2895,26 +3073,4 @@ class TransferOrderSerialAllocationSerializer(serializers.Serializer): raise ValidationError({'serial_numbers': error_msg}) - data['stock_items'] = stock_items_to_allocate - - return data - - def save(self): - """Allocate stock items against the transfer order.""" - data = self.validated_data - - line_item = data['line_item'] - stock_items = data['stock_items'] - - allocations = [] - - for stock_item in stock_items: - # Create a new TransferOrderAllocation - allocations.append( - order.models.TransferOrderAllocation( - line=line_item, item=stock_item, quantity=1 - ) - ) - - with transaction.atomic(): - order.models.TransferOrderAllocation.objects.bulk_create(allocations) + order.models.TransferOrderAllocation.objects.bulk_create(allocations) diff --git a/src/backend/InvenTree/order/status_codes.py b/src/backend/InvenTree/order/status_codes.py index d8893a1fa3..170a4a2a44 100644 --- a/src/backend/InvenTree/order/status_codes.py +++ b/src/backend/InvenTree/order/status_codes.py @@ -63,10 +63,11 @@ class SalesOrderStatusGroups: SalesOrderStatus.PENDING.value, SalesOrderStatus.ON_HOLD.value, SalesOrderStatus.IN_PROGRESS.value, + SalesOrderStatus.SHIPPED.value, ] # Completed orders - COMPLETE = [SalesOrderStatus.SHIPPED.value, SalesOrderStatus.COMPLETE.value] + COMPLETE = [SalesOrderStatus.COMPLETE.value] class ReturnOrderStatus(StatusCode): diff --git a/src/backend/InvenTree/order/tasks.py b/src/backend/InvenTree/order/tasks.py index d9065c2d20..2edb052f40 100644 --- a/src/backend/InvenTree/order/tasks.py +++ b/src/backend/InvenTree/order/tasks.py @@ -14,8 +14,9 @@ from opentelemetry import trace import common.notifications import InvenTree.helpers_model import order.models +import stock.models as stock_models from InvenTree.tasks import ScheduledTask, scheduled_task -from order.events import PurchaseOrderEvents, SalesOrderEvents +from order.events import PurchaseOrderEvents, ReturnOrderEvents, SalesOrderEvents from order.status_codes import ( PurchaseOrderStatusGroups, ReturnOrderStatusGroups, @@ -192,7 +193,7 @@ def notify_overdue_return_order(ro: order.models.ReturnOrder) -> None: 'template': {'html': 'email/overdue_return_order.html', 'subject': name}, } - event_name = SalesOrderEvents.OVERDUE + event_name = ReturnOrderEvents.OVERDUE # Send a notification to the appropriate users common.notifications.trigger_notification( @@ -254,16 +255,29 @@ def complete_sales_order_shipment( At this stage, the shipment is assumed to be complete, and we need to perform the required "processing" tasks. """ - # Do not handle any lookup errors here - # If the shipment cannot be found, then we want the task to fail (and retry later) - shipment = order.models.SalesOrderShipment.objects.get(pk=shipment_id) user = User.objects.filter(pk=user_id).first() if user_id else None - logger.info('Completing SalesOrderShipment <%s>', shipment) + logger.info('Completing SalesOrderShipment <%s>', shipment_id) with transaction.atomic(): - for allocation in shipment.allocations.all(): - allocation.complete_allocation(user=user) + # Lock the shipment row for the duration of the update, + # and re-check that it has not already been completed. + # This guards against duplicate task execution - e.g. if the completion + # request was submitted multiple times before the first task ran. + # Do not handle any lookup errors here: + # If the shipment cannot be found, then we want the task to fail (and retry later) + shipment = order.models.SalesOrderShipment.objects.select_for_update().get( + pk=shipment_id + ) + + if shipment.is_complete(): + logger.warning( + 'SalesOrderShipment <%s> has already been completed - skipping', + shipment_id, + ) + return + + shipment.complete_allocations(shipment.allocations.all(), user=user) # Once all allocations have been completed, we can mark the shipment as complete shipment.shipment_date = shipment_date or datetime.now().date() @@ -273,3 +287,38 @@ def complete_sales_order_shipment( # Trigger event signalling that the shipment has been completed trigger_event(SalesOrderEvents.SHIPMENT_COMPLETE, id=shipment.pk) + + +@tracer.start_as_current_span('auto_allocate_sales_order') +def auto_allocate_sales_order( + order_id: int, + location_id: Optional[int] = None, + exclude_location_id: Optional[int] = None, + shipment_id: Optional[int] = None, + line_ids: Optional[list] = None, + **kwargs, +): + """Run auto-allocation for a specified SalesOrder.""" + sales_order = order.models.SalesOrder.objects.get(pk=order_id) + + location = ( + stock_models.StockLocation.objects.get(pk=location_id) if location_id else None + ) + exclude_location = ( + stock_models.StockLocation.objects.get(pk=exclude_location_id) + if exclude_location_id + else None + ) + shipment = ( + order.models.SalesOrderShipment.objects.get(pk=shipment_id) + if shipment_id + else None + ) + + sales_order.auto_allocate_stock( + location=location, + exclude_location=exclude_location, + shipment=shipment, + line_ids=line_ids or None, + **kwargs, + ) diff --git a/src/backend/InvenTree/order/test_api.py b/src/backend/InvenTree/order/test_api.py index 2da8cd6115..893976cdb2 100644 --- a/src/backend/InvenTree/order/test_api.py +++ b/src/backend/InvenTree/order/test_api.py @@ -3,24 +3,31 @@ import base64 import io import json +import threading from datetime import date, datetime, timedelta from typing import Optional +from unittest import mock +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.db import connection +from django.test import TransactionTestCase, skipUnlessDBFeature from django.test.utils import CaptureQueriesContext from django.urls import reverse from djmoney.money import Money from icalendar import Calendar from rest_framework import status +from rest_framework.exceptions import ValidationError as DRFValidationError from common.currency import currency_codes -from common.models import InvenTreeSetting +from common.models import InvenTreeCustomUserStateModel, InvenTreeSetting from common.settings import set_global_setting from company.models import Company, SupplierPart, SupplierPriceBreak from InvenTree.unit_test import InvenTreeAPITestCase from order import models +from order.models import SalesOrderAllocation, SalesOrderLineItem, SalesOrderShipment +from order.serializers import TransferOrderSerialAllocationSerializer from order.status_codes import ( PurchaseOrderStatus, ReturnOrderLineStatus, @@ -31,8 +38,8 @@ from order.status_codes import ( TransferOrderStatusGroups, ) from part.models import Part -from stock.models import StockItem, StockLocation -from stock.status_codes import StockStatus +from stock.models import StockItem, StockLocation, StockSortOrder +from stock.status_codes import StockHistoryCode, StockStatus from users.models import Owner @@ -51,7 +58,14 @@ class OrderTest(InvenTreeAPITestCase): 'transfer_order', ] - roles = ['purchase_order.change', 'sales_order.change', 'transfer_order.change'] + roles = [ + 'purchase_order.change', + 'sales_order.change', + 'transfer_order.change', + 'part.view', + 'stock.view', + 'stock_location.view', + ] def filter(self, filters, count): """Test API filters.""" @@ -239,6 +253,77 @@ class PurchaseOrderTest(OrderTest): self.assertEqual(data['pk'], 1) self.assertEqual(data['description'], 'Ordering some screws') + def test_po_status_custom_key_options(self): + """Test that status_custom_key is exposed as writable in options.""" + self.assignRole('purchase_order.add') + + response = self.options(self.LIST_URL, expected_code=200) + post = response.data['actions']['POST'] + + self.assertIn('status_custom_key', post) + self.assertEqual(post['status_custom_key']['required'], False) + self.assertEqual(post['status_custom_key']['read_only'], False) + + def test_po_status_custom_key_patch_valid(self): + """Test patching a valid custom status key for the current PO status.""" + self.assignRole('purchase_order.change') + + po = models.PurchaseOrder.objects.get(pk=1) + self.assertEqual(po.status, PurchaseOrderStatus.PENDING.value) + + custom_status = InvenTreeCustomUserStateModel.objects.create( + key=901, + name='PO Pending Custom', + label='PO Pending Custom', + color='secondary', + logical_key=PurchaseOrderStatus.PENDING.value, + model=ContentType.objects.get_for_model(models.PurchaseOrder), + reference_status='PurchaseOrderStatus', + ) + + url = reverse('api-po-detail', kwargs={'pk': po.pk}) + response = self.patch( + url, {'status_custom_key': custom_status.key}, expected_code=200 + ) + + self.assertEqual(response.data['status'], PurchaseOrderStatus.PENDING.value) + self.assertEqual(response.data['status_custom_key'], custom_status.key) + + def test_po_status_custom_key_patch_invalid(self): + """Test patching an invalid custom status key for a PO.""" + self.assignRole('purchase_order.change') + + po = models.PurchaseOrder.objects.get(pk=1) + url = reverse('api-po-detail', kwargs={'pk': po.pk}) + + response = self.patch(url, {'status_custom_key': 999999}, expected_code=400) + + self.assertIn('status_custom_key', response.data) + + def test_po_status_custom_key_patch_wrong_logical_status(self): + """Test patching a custom key mapped to a different logical status.""" + self.assignRole('purchase_order.change') + + po = models.PurchaseOrder.objects.get(pk=1) + self.assertEqual(po.status, PurchaseOrderStatus.PENDING.value) + + custom_status = InvenTreeCustomUserStateModel.objects.create( + key=902, + name='PO Placed Custom', + label='PO Placed Custom', + color='secondary', + logical_key=PurchaseOrderStatus.PLACED.value, + model=ContentType.objects.get_for_model(models.PurchaseOrder), + reference_status='PurchaseOrderStatus', + ) + + url = reverse('api-po-detail', kwargs={'pk': po.pk}) + response = self.patch( + url, {'status_custom_key': custom_status.key}, expected_code=400 + ) + + self.assertIn('status_custom_key', response.data) + def test_po_reference(self): """Test that a reference with a too big / small reference is handled correctly.""" # get permissions @@ -500,7 +585,7 @@ class PurchaseOrderTest(OrderTest): # Duplicate with non-existent PK to provoke error data['duplicate'] = { - 'order_id': 10000001, + 'original': 10000001, 'copy_lines': True, 'copy_extra_lines': False, } @@ -511,7 +596,7 @@ class PurchaseOrderTest(OrderTest): response = self.post(reverse('api-po-list'), data, expected_code=400) data['duplicate'] = { - 'order_id': 1, + 'original': 1, 'copy_lines': True, 'copy_extra_lines': False, } @@ -532,7 +617,7 @@ class PurchaseOrderTest(OrderTest): data['reference'] = 'PO-9998' data['duplicate'] = { - 'order_id': 1, + 'original': 1, 'copy_lines': False, 'copy_extra_lines': True, } @@ -601,6 +686,39 @@ class PurchaseOrderTest(OrderTest): self.assertEqual(po.status, PurchaseOrderStatus.COMPLETE) + def test_po_complete_stale_instance_is_noop(self): + """A second completion attempt with a stale order instance must be a no-op. + + Regression test: _action_complete() checked 'status' on the caller's + (potentially stale) instance, so two concurrent completion requests could + both run the completion side effects (duplicate COMPLETED events and + duplicate pricing-update scheduling). The status is now re-read (under + lock) from the database before the check. + """ + po = models.PurchaseOrder.objects.get(pk=3) + self.assertEqual(po.status, PurchaseOrderStatus.PLACED) + + # Two "concurrent" requests each hold their own instance of the order + po_a = models.PurchaseOrder.objects.get(pk=po.pk) + po_b = models.PurchaseOrder.objects.get(pk=po.pk) + + po_a.complete_order() + + po.refresh_from_db() + self.assertEqual(po.status, PurchaseOrderStatus.COMPLETE) + + # The second (stale) instance still believes the order is PLACED - + # completion must be skipped based on the database state + self.assertEqual(po_b.status, PurchaseOrderStatus.PLACED) + + with self.assertRaises(ValidationError) as err: + po_b.complete_order() + + self.assertIn('Purchase Order is already Complete', str(err.exception)) + + po.refresh_from_db() + self.assertEqual(po.status, PurchaseOrderStatus.COMPLETE) + def test_po_issue(self): """Test the PurchaseOrderIssue API endpoint.""" po = models.PurchaseOrder.objects.get(pk=2) @@ -736,6 +854,69 @@ class PurchaseOrderTest(OrderTest): ) self.assertEqual(response.status_code, 200) + def test_po_custom_status_query_count(self): + """Test that listing PurchaseOrders with custom statuses does not cause N+1 queries. + + Ensures that resolving the 'status_text' field for custom status values + is O(1) in database queries, not O(N) relative to the number of results. + """ + from django.contrib.contenttypes.models import ContentType + + po_content_type = ContentType.objects.get_for_model(models.PurchaseOrder) + + # 10 custom status values - different keys, labels, and logical_keys + logical_keys = [ + PurchaseOrderStatus.PENDING.value, + PurchaseOrderStatus.PLACED.value, + PurchaseOrderStatus.ON_HOLD.value, + PurchaseOrderStatus.COMPLETE.value, + PurchaseOrderStatus.CANCELLED.value, + PurchaseOrderStatus.LOST.value, + PurchaseOrderStatus.RETURNED.value, + PurchaseOrderStatus.PENDING.value, + PurchaseOrderStatus.PLACED.value, + PurchaseOrderStatus.ON_HOLD.value, + ] + + custom_statuses = [ + InvenTreeCustomUserStateModel.objects.create( + key=1000 + i, + name=f'PoCustomStatus{i}', + label=f'PO Custom Status Label {i}', + color='secondary', + logical_key=logical_keys[i], + model=po_content_type, + reference_status='PurchaseOrderStatus', + ) + for i in range(10) + ] + + # Create 100 purchase orders, cycling through the custom statuses + supplier = Company.objects.filter(is_supplier=True).first() + models.PurchaseOrder.objects.bulk_create([ + models.PurchaseOrder( + supplier=supplier, + reference=f'PO-QTEST-{i}', + status=custom_statuses[i % 10].logical_key, + status_custom_key=custom_statuses[i % 10].key, + ) + for i in range(100) + ]) + + # Query count must stay below the fixed threshold for all limit values. + # An N+1 bug would push limit=50 or limit=100 well over the threshold. + for limit in [1, 5, 10, 25, 50, 100]: + response = self.get( + self.LIST_URL, + data={'limit': limit}, + expected_code=200, + max_query_count=50, + ) + + for result in response.data['results']: + self.assertIn('status_text', result) + self.assertIsNotNone(result['status_text']) + class PurchaseOrderLineItemTest(OrderTest): """Unit tests for PurchaseOrderLineItems.""" @@ -763,16 +944,46 @@ class PurchaseOrderLineItemTest(OrderTest): """Test that we can bulk delete multiple PurchaseOrderLineItems via the API.""" n = models.PurchaseOrderLineItem.objects.count() - self.assignRole('purchase_order.delete') - url = reverse('api-po-line-list') + # Deletion should fail without the correct role + self.delete(url, {'items': [1, 2]}, expected_code=403) + + self.assignRole('purchase_order.delete') + # Try to delete a set of line items via their IDs self.delete(url, {'items': [1, 2]}, expected_code=200) - # We should have 2 less PurchaseOrderLineItems after deletign them + # We should have 2 less PurchaseOrderLineItems after deleting them self.assertEqual(models.PurchaseOrderLineItem.objects.count(), n - 2) + def test_po_extra_line_bulk_delete(self): + """Test that we can bulk delete multiple PurchaseOrderExtraLine items via the API.""" + po = models.PurchaseOrder.objects.get(pk=1) + + models.PurchaseOrderExtraLine.objects.bulk_create([ + models.PurchaseOrderExtraLine( + order=po, quantity=idx + 1, reference=f'Extra line {idx}' + ) + for idx in range(3) + ]) + + n = models.PurchaseOrderExtraLine.objects.count() + items = list( + models.PurchaseOrderExtraLine.objects.values_list('pk', flat=True)[:2] + ) + + url = reverse('api-po-extra-line-list') + + # Deletion should fail without the correct role + self.delete(url, {'items': items}, expected_code=403) + + self.assignRole('purchase_order.delete') + + self.delete(url, {'items': items}, expected_code=200) + + self.assertEqual(models.PurchaseOrderExtraLine.objects.count(), n - 2) + def test_po_line_merge_pricing(self): """Test that we can create a new PurchaseOrderLineItem via the API.""" self.assignRole('purchase_order.add') @@ -861,6 +1072,42 @@ class PurchaseOrderLineItemTest(OrderTest): ).json() self.assertEqual(float(li5['purchase_price']), 1) + def test_po_line_merge_default_setting(self): + """Test that merge_items defaults to the global setting value.""" + self.assignRole('purchase_order.add') + + su = Company.objects.get(pk=1) + sp = SupplierPart.objects.get(pk=1) + po = models.PurchaseOrder.objects.create( + supplier=su, reference='PO-MERGE-DEFAULT' + ) + + set_global_setting('PURCHASEORDER_MERGE_LINE_ITEMS', False) + + li1 = self.post( + reverse('api-po-line-list'), + {'order': po.pk, 'part': sp.pk, 'quantity': 1}, + expected_code=201, + ).json() + + li2 = self.post( + reverse('api-po-line-list'), + {'order': po.pk, 'part': sp.pk, 'quantity': 2}, + expected_code=201, + ).json() + + self.assertNotEqual(li1['pk'], li2['pk']) + + set_global_setting('PURCHASEORDER_MERGE_LINE_ITEMS', True) + + li3 = self.post( + reverse('api-po-line-list'), + {'order': po.pk, 'part': sp.pk, 'quantity': 3}, + expected_code=201, + ).json() + + self.assertEqual(li1['pk'], li3['pk']) + def test_output_options(self): """Test PurchaseOrderLineItem output option endpoint.""" self.run_output_test( @@ -1141,6 +1388,10 @@ class PurchaseOrderReceiveTest(OrderTest): self.assertEqual(stock_1.last().expiry_date, one_week_from_today) self.assertEqual(stock_2.last().expiry_date, one_week_from_today) + # creation_date must be populated on both received items + self.assertIsNotNone(stock_1.last().creation_date) + self.assertIsNotNone(stock_2.last().creation_date) + # Barcodes should have been assigned to the stock items self.assertTrue( StockItem.objects.filter(barcode_data='MY-UNIQUE-BARCODE-123').exists() @@ -1217,6 +1468,7 @@ class PurchaseOrderReceiveTest(OrderTest): self.assertEqual(item.serial, str(i)) self.assertEqual(item.quantity, 1) self.assertEqual(item.batch, 'B-abc-123') + self.assertIsNotNone(item.creation_date) # A single stock item (quantity 10) created for the second line item items = StockItem.objects.filter(supplier_part=line_2.part) @@ -1227,6 +1479,43 @@ class PurchaseOrderReceiveTest(OrderTest): self.assertEqual(item.quantity, 10) self.assertEqual(item.batch, 'B-xyz-789') + def test_duplicate_serial_numbers_across_items(self): + """Duplicate serial numbers across line items in a single request are rejected. + + Regression test: each line's serials used to be validated against the + database only, so two lines could claim the same serial number and create + duplicate serialized stock items. + """ + data = { + 'items': [ + {'line_item': 1, 'quantity': 3, 'serial_numbers': '100-102'}, + {'line_item': 1, 'quantity': 3, 'serial_numbers': '102-104'}, + ], + 'location': 1, + } + + # Serial 102 is claimed by both entries - request must be rejected + response = self.post(self.url, data, expected_code=400) + + self.assertIn('Supplied serial numbers must be unique', str(response.data)) + + # No new stock items have been created + self.assertEqual(self.n, StockItem.objects.count()) + + # Non-overlapping serial numbers are accepted + data['items'][1]['serial_numbers'] = '103-105' + + self.post(self.url, data, expected_code=201, max_query_count=250) + + self.assertEqual(self.n + 6, StockItem.objects.count()) + + for serial in range(100, 106): + self.assertEqual( + StockItem.objects.filter(serial=str(serial)).count(), + 1, + f'Expected exactly one stock item with serial {serial}', + ) + def test_receive_large_quantity(self): """Test receipt of a large number of items.""" from stock.status_codes import StockStatus @@ -1275,12 +1564,24 @@ class PurchaseOrderReceiveTest(OrderTest): # Check for expected response self.assertEqual(len(response), N_LINES) + + # Check that the expected number of stock items has been created self.assertEqual(N_ITEMS + N_LINES, StockItem.objects.count()) for item in response: self.assertEqual(item['purchase_order'], po.pk) self.assertEqual(item['status'], StockStatus.QUARANTINED) + stock_item = StockItem.objects.get(pk=item['pk']) + # Check that the item has tracking entries + self.assertEqual(stock_item.tracking_info.count(), 1) + entry = stock_item.tracking_info.first() + self.assertEqual(entry.deltas['quantity'], stock_item.quantity) + self.assertEqual(entry.user, self.user) + self.assertEqual( + entry.tracking_type, StockHistoryCode.RECEIVED_AGAINST_PURCHASE_ORDER + ) + # Check that the order has been completed po.refresh_from_db() self.assertEqual(po.status, PurchaseOrderStatus.COMPLETE) @@ -1289,6 +1590,47 @@ class PurchaseOrderReceiveTest(OrderTest): line.refresh_from_db() self.assertEqual(line.received, line.quantity) + def test_bulk_receive_query_benchmark(self): + """Benchmark: measure the number of DB queries required to receive 100 line items at once.""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + sp = SupplierPart.objects.first() + + po = models.PurchaseOrder.objects.create( + reference='PO-BENCHMARK-100', supplier=sp.supplier + ) + + N_LINES = 100 + + models.PurchaseOrderLineItem.objects.bulk_create([ + models.PurchaseOrderLineItem(order=po, part=sp, quantity=10) + for _ in range(N_LINES) + ]) + + po.place_order() + + url = reverse('api-po-receive', kwargs={'pk': po.pk}) + + lines = po.lines.all() + location = StockLocation.objects.filter(structural=False).first() + + data = { + 'items': [ + {'line_item': line.pk, 'quantity': line.quantity} for line in lines + ], + 'location': location.pk, + } + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + response = self.post( + url, data, max_query_count=400, benchmark=True, format='json' + ) + + self.assertEqual(response.status_code, 201) + self.assertEqual(len(response.data), N_LINES) + def test_packaging(self): """Test that we can supply a 'packaging' value when receiving items.""" line_1 = models.PurchaseOrderLineItem.objects.get(pk=1) @@ -1389,19 +1731,21 @@ class SalesOrderTest(OrderTest): def test_so_list(self): """Test the SalesOrder list API endpoint.""" # All orders - self.filter({}, 5) + self.filter({}, 6) # Filter by customer self.filter({'customer': 4}, 3) - self.filter({'customer': 5}, 2) + self.filter({'customer': 5}, 3) # Filter by outstanding - self.filter({'outstanding': True}, 3) + self.filter({'outstanding': True}, 4) self.filter({'outstanding': False}, 2) # Filter by status - self.filter({'status': SalesOrderStatus.PENDING.value}, 3) # PENDING - self.filter({'status': SalesOrderStatus.SHIPPED.value}, 1) # SHIPPED + self.filter({'status': SalesOrderStatus.PENDING.value}, 3) + self.filter({'status': SalesOrderStatus.SHIPPED.value}, 1) + self.filter({'status': SalesOrderStatus.COMPLETE.value}, 1) + self.filter({'status': SalesOrderStatus.CANCELLED.value}, 0) self.filter({'status': 99}, 0) # Invalid # Filter by "reference" @@ -1410,7 +1754,7 @@ class SalesOrderTest(OrderTest): # Filter by "assigned_to_me" self.filter({'assigned_to_me': 1}, 0) - self.filter({'assigned_to_me': 0}, 5) + self.filter({'assigned_to_me': 0}, 6) def test_total_price(self): """Unit tests for the 'total_price' field.""" @@ -1484,7 +1828,7 @@ class SalesOrderTest(OrderTest): def test_overdue(self): """Test "overdue" status.""" self.filter({'overdue': True}, 0) - self.filter({'overdue': False}, 5) + self.filter({'overdue': False}, 6) for pk in [1, 2]: order = models.SalesOrder.objects.get(pk=pk) @@ -1492,7 +1836,7 @@ class SalesOrderTest(OrderTest): order.save() self.filter({'overdue': True}, 2) - self.filter({'overdue': False}, 3) + self.filter({'overdue': False}, 4) def test_so_detail(self): """Test the SalesOrder detail endpoint.""" @@ -1649,7 +1993,7 @@ class SalesOrderTest(OrderTest): { 'reference': 'SO-12345', 'customer': so.customer.pk, - 'duplicate': {'order_id': so.pk, 'copy_parameters': False}, + 'duplicate': {'original': so.pk, 'copy_parameters': False}, }, ) @@ -1666,7 +2010,7 @@ class SalesOrderTest(OrderTest): { 'reference': 'SO-12346', 'customer': so.customer.pk, - 'duplicate': {'order_id': so.pk}, + 'duplicate': {'original': so.pk}, }, ) @@ -1879,6 +2223,63 @@ class SalesOrderTest(OrderTest): reverse('api-so-detail', kwargs={'pk': 1}), ['customer_detail'] ) + def test_so_custom_status_query_count(self): + """Test that listing SalesOrders with custom statuses does not cause N+1 queries. + + Ensures that resolving the 'status_text' field for custom status values + is O(1) in database queries, not O(N) relative to the number of results. + """ + so_content_type = ContentType.objects.get_for_model(models.SalesOrder) + + logical_keys = [ + SalesOrderStatus.PENDING.value, + SalesOrderStatus.IN_PROGRESS.value, + SalesOrderStatus.SHIPPED.value, + SalesOrderStatus.ON_HOLD.value, + SalesOrderStatus.COMPLETE.value, + SalesOrderStatus.CANCELLED.value, + SalesOrderStatus.PENDING.value, + SalesOrderStatus.IN_PROGRESS.value, + SalesOrderStatus.SHIPPED.value, + SalesOrderStatus.ON_HOLD.value, + ] + + custom_statuses = [ + InvenTreeCustomUserStateModel.objects.create( + key=2000 + i, + name=f'SoCustomStatus{i}', + label=f'SO Custom Status Label {i}', + color='secondary', + logical_key=logical_keys[i], + model=so_content_type, + reference_status='SalesOrderStatus', + ) + for i in range(10) + ] + + customer = Company.objects.filter(is_customer=True).first() + models.SalesOrder.objects.bulk_create([ + models.SalesOrder( + customer=customer, + reference=f'SO-QTEST-{i}', + status=custom_statuses[i % 10].logical_key, + status_custom_key=custom_statuses[i % 10].key, + ) + for i in range(100) + ]) + + for limit in [1, 5, 10, 25, 50, 100]: + response = self.get( + self.LIST_URL, + data={'limit': limit}, + expected_code=200, + max_query_count=50, + ) + + for result in response.data['results']: + self.assertIn('status_text', result) + self.assertIsNotNone(result['status_text']) + class SalesOrderLineItemTest(OrderTest): """Tests for the SalesOrderLineItem API.""" @@ -1954,6 +2355,103 @@ class SalesOrderLineItemTest(OrderTest): self.filter({'allocated': 'true'}, 1) self.filter({'allocated': 'false'}, n - 1) + def test_so_line_ordering(self): + """Test that the SalesOrderLineItem list can be ordered by order-related fields. + + Regression test for aliased ordering fields ('status', 'shipment_date') + which are not present directly on the SalesOrderLineItem model, + but rather on the linked SalesOrder. + """ + # Orders 1-3 are 'pending' (status=10), order 4 is 'shipped' (status=20), + # order 5 is 'returned' (status=60), order 6 is 'complete' (status=30) + # (refer to the 'sales_order' fixture data) + + # Order by 'status' (aliased to 'order__status') + response = self.get( + self.url, {'ordering': 'status', 'order_detail': True}, expected_code=200 + ) + + statuses = [item['order_detail']['status'] for item in response.data] + self.assertEqual(statuses, sorted(statuses)) + self.assertEqual(statuses[0], SalesOrderStatus.PENDING.value) + self.assertEqual(statuses[-1], SalesOrderStatus.RETURNED.value) + + # Reverse the ordering + response = self.get( + self.url, {'ordering': '-status', 'order_detail': True}, expected_code=200 + ) + + statuses = [item['order_detail']['status'] for item in response.data] + self.assertEqual(statuses, sorted(statuses, reverse=True)) + self.assertEqual(statuses[0], SalesOrderStatus.RETURNED.value) + + # Order by 'shipment_date' (aliased to 'order__shipment_date') + order_a = models.SalesOrder.objects.get(pk=4) + order_b = models.SalesOrder.objects.get(pk=5) + + order_a.shipment_date = date(2020, 1, 1) + order_a.save() + + order_b.shipment_date = date(2024, 1, 1) + order_b.save() + + response = self.get(self.url, {'ordering': 'shipment_date'}, expected_code=200) + + order_ids = [item['order'] for item in response.data] + + # Lines for 'order_a' (earlier shipment date) should sort before 'order_b' + self.assertLess(order_ids.index(order_a.pk), order_ids.index(order_b.pk)) + + # Reverse the ordering - 'order_b' should now come first + response = self.get(self.url, {'ordering': '-shipment_date'}, expected_code=200) + + order_ids = [item['order'] for item in response.data] + + self.assertLess(order_ids.index(order_b.pk), order_ids.index(order_a.pk)) + + def test_so_line_bulk_delete(self): + """Test that we can bulk delete multiple SalesOrderLineItems via the API.""" + n = models.SalesOrderLineItem.objects.count() + + items = list(models.SalesOrderLineItem.objects.values_list('pk', flat=True)[:2]) + + # Deletion should fail without the correct role + self.delete(self.url, {'items': items}, expected_code=403) + + self.assignRole('sales_order.delete') + + self.delete(self.url, {'items': items}, expected_code=200) + + # We should have 2 less SalesOrderLineItems after deleting them + self.assertEqual(models.SalesOrderLineItem.objects.count(), n - 2) + + def test_so_extra_line_bulk_delete(self): + """Test that we can bulk delete multiple SalesOrderExtraLine items via the API.""" + so = models.SalesOrder.objects.first() + + models.SalesOrderExtraLine.objects.bulk_create([ + models.SalesOrderExtraLine( + order=so, quantity=idx + 1, reference=f'Extra line {idx}' + ) + for idx in range(3) + ]) + + n = models.SalesOrderExtraLine.objects.count() + items = list( + models.SalesOrderExtraLine.objects.values_list('pk', flat=True)[:2] + ) + + url = reverse('api-so-extra-line-list') + + # Deletion should fail without the correct role + self.delete(url, {'items': items}, expected_code=403) + + self.assignRole('sales_order.delete') + + self.delete(url, {'items': items}, expected_code=200) + + self.assertEqual(models.SalesOrderExtraLine.objects.count(), n - 2) + def test_so_line_allocated_filters(self): """Test filtering by allocation status for a SalesOrderLineItem.""" self.assignRole('sales_order.add') @@ -2445,6 +2943,214 @@ class SalesOrderAllocateTest(OrderTest): response = self.post(self.url, data, expected_code=201) +class SalesOrderAllocationDownloadTest(OrderTest): + """Unit tests for downloading SalesOrderAllocation data via the API endpoint.""" + + def test_download_csv(self): + """Test that SalesOrderAllocation data can be downloaded as a .csv file. + + Regression test for a bug where the SalesOrderAllocation list endpoint + did not support data export. + """ + url = reverse('api-so-allocation-list') + + required_cols = ['ID', 'Item', 'Quantity', 'Shipment', 'Line', 'Part', 'Order'] + + with self.export_data(url, export_format='csv', expected_code=200) as file: + data = self.process_csv( + file, + required_cols=required_cols, + required_rows=SalesOrderAllocation.objects.count(), + ) + + for row in data: + allocation = SalesOrderAllocation.objects.get(pk=row['ID']) + + self.assertEqual(row['Item'], str(allocation.item.pk)) + self.assertEqual(float(row['Quantity']), float(allocation.quantity)) + self.assertEqual(row['Line'], str(allocation.line.pk)) + self.assertEqual(row['Part'], str(allocation.item.part.pk)) + self.assertEqual(row['Order'], str(allocation.line.order.pk)) + + +class SalesOrderAllocateSerialsTest(OrderTest): + """Unit tests for allocating stock items against a SalesOrder, by serial number.""" + + @classmethod + def setUpTestData(cls): + """Init routine for this unit test class.""" + super().setUpTestData() + + def setUp(self): + """Init routines for this unit testing class.""" + super().setUp() + + self.assignRole('sales_order.add') + + self.url = reverse('api-so-allocate-serials', kwargs={'pk': 1}) + + self.order = models.SalesOrder.objects.get(pk=1) + + self.part = Part.objects.create( + name='Serial Allocation Part', + salable=True, + trackable=True, + description='A trackable part for serial allocation tests', + ) + + self.line = models.SalesOrderLineItem.objects.create( + order=self.order, part=self.part, quantity=5 + ) + + # Create some serialized stock items for this part + self.stock_items = [ + StockItem.objects.create(part=self.part, quantity=1, serial=str(n)) + for n in range(1, 6) + ] + + self.shipment = models.SalesOrderShipment.objects.create(order=self.order) + + def test_allocate(self): + """Test that we can allocate stock items to a SalesOrder line, by serial number.""" + self.assertEqual(self.order.stock_allocations.count(), 0) + + data = {'line_item': self.line.pk, 'quantity': 3, 'serial_numbers': '1,2,3'} + + self.post(self.url, data, expected_code=201) + + self.assertEqual(self.order.stock_allocations.count(), 3) + + allocated_serials = { + allocation.item.serial for allocation in self.order.stock_allocations.all() + } + self.assertEqual(allocated_serials, {'1', '2', '3'}) + + for allocation in self.order.stock_allocations.all(): + self.assertEqual(allocation.quantity, 1) + self.assertIsNone(allocation.shipment) + + def test_allocate_with_shipment(self): + """Test that allocations are correctly assigned to a provided shipment.""" + data = { + 'line_item': self.line.pk, + 'quantity': 2, + 'serial_numbers': '4,5', + 'shipment': self.shipment.pk, + } + + self.post(self.url, data, expected_code=201) + + for allocation in self.order.stock_allocations.all(): + self.assertEqual(allocation.shipment, self.shipment) + + def test_invalid_line_item(self): + """Test that a line item belonging to a different order is rejected.""" + other_order = models.SalesOrder.objects.exclude(pk=self.order.pk).first() + other_line = models.SalesOrderLineItem.objects.create( + order=other_order, part=self.part, quantity=5 + ) + + data = {'line_item': other_line.pk, 'quantity': 1, 'serial_numbers': '1'} + + response = self.post(self.url, data, expected_code=400) + + self.assertIn('Line item is not associated with this order', str(response.data)) + + self.assertEqual(self.order.stock_allocations.count(), 0) + + def test_shipment_already_shipped(self): + """Test that a shipment which has already been shipped is rejected.""" + self.shipment.shipment_date = date.today() + self.shipment.save() + + data = { + 'line_item': self.line.pk, + 'quantity': 1, + 'serial_numbers': '1', + 'shipment': self.shipment.pk, + } + + response = self.post(self.url, data, expected_code=400) + + self.assertIn('Shipment has already been shipped', str(response.data)) + + self.assertEqual(self.order.stock_allocations.count(), 0) + + def test_shipment_wrong_order(self): + """Test that a shipment belonging to a different order is rejected.""" + other_order = models.SalesOrder.objects.exclude(pk=self.order.pk).first() + other_shipment = models.SalesOrderShipment.objects.create(order=other_order) + + data = { + 'line_item': self.line.pk, + 'quantity': 1, + 'serial_numbers': '1', + 'shipment': other_shipment.pk, + } + + response = self.post(self.url, data, expected_code=400) + + self.assertIn('Shipment is not associated with this order', str(response.data)) + + self.assertEqual(self.order.stock_allocations.count(), 0) + + def test_serial_not_exist(self): + """Test that non-existent serial numbers are rejected.""" + data = {'line_item': self.line.pk, 'quantity': 1, 'serial_numbers': '999'} + + response = self.post(self.url, data, expected_code=400) + + self.assertIn( + 'No match found for the following serial numbers', str(response.data) + ) + self.assertIn('999', str(response.data)) + + self.assertEqual(self.order.stock_allocations.count(), 0) + + def test_serial_unavailable(self): + """Test that an already-allocated serial number is rejected as unavailable.""" + # Fully allocate stock item with serial '1' against some other line + models.SalesOrderAllocation.objects.create( + line=self.line, item=self.stock_items[0], quantity=1 + ) + + data = {'line_item': self.line.pk, 'quantity': 1, 'serial_numbers': '1'} + + response = self.post(self.url, data, expected_code=400) + + self.assertIn( + 'The following serial numbers are unavailable', str(response.data) + ) + self.assertIn('1', str(response.data)) + + # No *additional* allocation should have been created + self.assertEqual(self.order.stock_allocations.count(), 1) + + def test_block_on_required_tests(self): + """Test the SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS setting.""" + from part.models import PartTestTemplate + + self.part.testable = True + self.part.save() + + PartTestTemplate.objects.create( + part=self.part, test_name='A required test', required=True + ) + + data = {'line_item': self.line.pk, 'quantity': 1, 'serial_numbers': '1'} + + set_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS', True) + + response = self.post(self.url, data, expected_code=400) + self.assertIn( + 'The following serial numbers are unavailable', str(response.data) + ) + + set_global_setting('SALESORDER_BLOCK_INCOMPLETE_ITEM_TESTS', False) + + self.post(self.url, data, expected_code=201) + + class ReturnOrderTests(InvenTreeAPITestCase): """Unit tests for ReturnOrder API endpoints.""" @@ -2755,6 +3461,100 @@ class ReturnOrderTests(InvenTreeAPITestCase): self.assertIsNone(line.item.sales_order) self.assertEqual(line.item.location.pk, LOCATION_ID) + def test_receive_stale_line_instance(self): + """A second receipt attempt with a stale line instance must be a no-op. + + Regression test: receive_line_item() checked received_date on the + caller's (potentially stale) instance, so two concurrent receipt + requests could both process the same line - splitting the source stock + item twice and orphaning one of the splits. The line is now re-read + (under lock) from the database before the check. + """ + company = Company.objects.get(pk=4) + + rma = models.ReturnOrder.objects.create( + customer=company, description='A return order' + ) + rma.issue_order() + + part = Part.objects.get(pk=25) + + # An untracked item, where only part of the quantity is returned + # (forces the stock item to be split on receipt) + stock_item = StockItem.objects.create(part=part, customer=company, quantity=10) + line = models.ReturnOrderLineItem.objects.create( + order=rma, item=stock_item, quantity=4 + ) + + location = StockLocation.objects.get(pk=1) + + # Two "concurrent" requests each hold their own instance of the line + line_a = models.ReturnOrderLineItem.objects.get(pk=line.pk) + line_b = models.ReturnOrderLineItem.objects.get(pk=line.pk) + + n_items = StockItem.objects.count() + + rma.receive_line_item(line_a, location, None) + + # The stock item has been split: 4 returned, 6 remain with the customer + self.assertEqual(StockItem.objects.count(), n_items + 1) + + stock_item.refresh_from_db() + self.assertEqual(stock_item.quantity, 6) + + line.refresh_from_db() + self.assertIsNotNone(line.received_date) + self.assertEqual(line.item.quantity, 4) + self.assertEqual(line.item.location, location) + + # The second (stale) instance still believes the line is unreceived - + # the receipt must be skipped based on the database state + self.assertIsNone(line_b.received_date) + + rma.receive_line_item(line_b, location, None) + + # No further stock item has been created, and the source is unchanged + self.assertEqual(StockItem.objects.count(), n_items + 1) + + stock_item.refresh_from_db() + self.assertEqual(stock_item.quantity, 6) + + def test_complete_stale_instance_is_noop(self): + """A second completion attempt with a stale instance must be a no-op. + + Regression test: _action_complete() checked 'status' on the caller's + (potentially stale) instance, so two concurrent completion requests + could both run the completion side effects (duplicate COMPLETED events). + The status is now re-read (under lock) from the database before the check. + """ + company = Company.objects.get(pk=4) + + rma = models.ReturnOrder.objects.create( + customer=company, description='A return order' + ) + rma.issue_order() + + # Two "concurrent" requests each hold their own instance of the order + order_a = models.ReturnOrder.objects.get(pk=rma.pk) + order_b = models.ReturnOrder.objects.get(pk=rma.pk) + + order_a.complete_order() + + rma.refresh_from_db() + self.assertEqual(rma.status, ReturnOrderStatus.COMPLETE.value) + + # The second (stale) instance still believes the order is IN_PROGRESS - + # completion must be skipped based on the database state + self.assertEqual(order_b.status, ReturnOrderStatus.IN_PROGRESS.value) + + with self.assertRaises(ValidationError) as err: + order_b.complete_order() + + self.assertIn('Return Order is already Complete', str(err.exception)) + + rma.refresh_from_db() + self.assertEqual(rma.status, ReturnOrderStatus.COMPLETE.value) + def test_ro_calendar(self): """Test the calendar export endpoint.""" # Full test is in test_po_calendar. Since these use the same backend, test only @@ -2829,7 +3629,7 @@ class ReturnOrderLineItemTests(InvenTreeAPITestCase): 'supplier_part', 'stock', ] - roles = ['return_order.view'] + roles = ['return_order.view', 'part.view', 'stock.view'] def test_options(self): """Test the OPTIONS endpoint.""" @@ -2896,6 +3696,162 @@ class ReturnOrderLineItemTests(InvenTreeAPITestCase): line = models.ReturnOrderLineItem.objects.get(pk=1) self.assertEqual(float(line.price.amount), 15.75) + def test_bulk_delete(self): + """Test that we can bulk delete multiple ReturnOrderLineItems via the API.""" + n = models.ReturnOrderLineItem.objects.count() + self.assertGreater(n, 0) + + items = list( + models.ReturnOrderLineItem.objects.values_list('pk', flat=True)[:1] + ) + + url = reverse('api-return-order-line-list') + + # Deletion should fail without the correct role + self.delete(url, {'items': items}, expected_code=403) + + self.assignRole('return_order.delete') + + self.delete(url, {'items': items}, expected_code=200) + + self.assertEqual(models.ReturnOrderLineItem.objects.count(), n - 1) + + def test_bulk_update(self): + """Test that we can bulk update the 'outcome' field for multiple ReturnOrderLineItems via the API.""" + ro = models.ReturnOrder.objects.get(pk=6) + + # Create some extra line items against the same order, so we have multiple to update + models.ReturnOrderLineItem.objects.bulk_create([ + models.ReturnOrderLineItem(order=ro, item_id=1006, quantity=1), + models.ReturnOrderLineItem(order=ro, item_id=1007, quantity=1), + ]) + + items = list( + models.ReturnOrderLineItem.objects.filter(order=ro).values_list( + 'pk', flat=True + ) + ) + + self.assertEqual(len(items), 3) + + for line in models.ReturnOrderLineItem.objects.filter(pk__in=items): + self.assertEqual(line.outcome, ReturnOrderLineStatus.PENDING) + + url = reverse('api-return-order-line-list') + + data = {'items': items, 'outcome': ReturnOrderLineStatus.REPAIR.value} + + # Update should fail without the correct role + self.patch(url, data, expected_code=403) + + self.assignRole('return_order.change') + + response = self.patch(url, data, expected_code=200).data + self.assertEqual(len(response['items']), 3) + + for line in models.ReturnOrderLineItem.objects.filter(pk__in=items): + self.assertEqual(line.outcome, ReturnOrderLineStatus.REPAIR.value) + + def test_extra_line_bulk_delete(self): + """Test that we can bulk delete multiple ReturnOrderExtraLine items via the API.""" + ro = models.ReturnOrder.objects.first() + + models.ReturnOrderExtraLine.objects.bulk_create([ + models.ReturnOrderExtraLine( + order=ro, quantity=idx + 1, reference=f'Extra line {idx}' + ) + for idx in range(3) + ]) + + n = models.ReturnOrderExtraLine.objects.count() + items = list( + models.ReturnOrderExtraLine.objects.values_list('pk', flat=True)[:2] + ) + + url = reverse('api-return-order-extra-line-list') + + # Deletion should fail without the correct role + self.delete(url, {'items': items}, expected_code=403) + + self.assignRole('return_order.delete') + + self.delete(url, {'items': items}, expected_code=200) + + self.assertEqual(models.ReturnOrderExtraLine.objects.count(), n - 2) + + +class ExtraLineTotalPriceTest(InvenTreeAPITestCase): + """Unit tests for the 'total_price' field on ExtraLine API endpoints. + + Covers PurchaseOrderExtraLine, SalesOrderExtraLine and ReturnOrderExtraLine, + which all share the same 'total_price' field via AbstractExtraLineSerializer. + """ + + fixtures = [ + 'category', + 'part', + 'company', + 'location', + 'supplier_part', + 'stock', + 'order', + 'sales_order', + 'return_order', + ] + + roles = ['purchase_order.change', 'sales_order.change', 'return_order.change'] + + def check_total_price( + self, order, extra_line_model, list_url_name, detail_url_name + ): + """Create an ExtraLine with a known price/quantity/discount, and check total_price.""" + line = extra_line_model.objects.create( + order=order, quantity=5, price=Money(10, 'USD'), discount=20 + ) + + # 5 * 10 = 50, less 20% discount = 40 + expected = 40 + + # List endpoint + response = self.get( + reverse(list_url_name), {'order': order.pk}, expected_code=200 + ) + result = next(r for r in response.data if r['pk'] == line.pk) + self.assertEqual(float(result['total_price']), expected) + + # Detail endpoint + response = self.get( + reverse(detail_url_name, kwargs={'pk': line.pk}), expected_code=200 + ) + self.assertEqual(float(response.data['total_price']), expected) + + def test_po_extra_line_total_price(self): + """Check 'total_price' for a PurchaseOrderExtraLine.""" + self.check_total_price( + models.PurchaseOrder.objects.get(pk=1), + models.PurchaseOrderExtraLine, + 'api-po-extra-line-list', + 'api-po-extra-line-detail', + ) + + def test_so_extra_line_total_price(self): + """Check 'total_price' for a SalesOrderExtraLine.""" + self.check_total_price( + models.SalesOrder.objects.get(pk=1), + models.SalesOrderExtraLine, + 'api-so-extra-line-list', + 'api-so-extra-line-detail', + ) + + def test_return_order_extra_line_total_price(self): + """Check 'total_price' for a ReturnOrderExtraLine.""" + self.check_total_price( + models.ReturnOrder.objects.get(pk=1), + models.ReturnOrderExtraLine, + 'api-return-order-extra-line-list', + 'api-return-order-extra-line-detail', + ) + class TransferOrderTest(OrderTest): """Tests for the TransferOrder API.""" @@ -3073,6 +4029,39 @@ class TransferOrderTest(OrderTest): self.assertEqual(to.status, TransferOrderStatus.CANCELLED) + def test_transfer_order_cancel_stale_instance_is_noop(self): + """A second cancellation attempt with a stale order instance must be a no-op. + + Regression test: _action_cancel() checked 'can_cancel' (derived from + 'status') on the caller's (potentially stale) instance, so two concurrent + cancellation requests could both run the cancellation side effects + (duplicate CANCELLED events). The status is now re-read (under lock) + from the database before the check. + """ + to = models.TransferOrder.objects.get(pk=1) + self.assertEqual(to.status, TransferOrderStatus.PENDING) + + # Two "concurrent" requests each hold their own instance of the order + instance_a = models.TransferOrder.objects.get(pk=to.pk) + instance_b = models.TransferOrder.objects.get(pk=to.pk) + + instance_a.cancel_order() + + to.refresh_from_db() + self.assertEqual(to.status, TransferOrderStatus.CANCELLED) + + # The second (stale) instance still believes the order is PENDING - + # cancellation must be skipped based on the database state + self.assertEqual(instance_b.status, TransferOrderStatus.PENDING) + + with mock.patch('order.models.trigger_event') as trigger: + with self.assertRaises(ValidationError): + instance_b.cancel_order() + trigger.assert_not_called() + + to.refresh_from_db() + self.assertEqual(to.status, TransferOrderStatus.CANCELLED) + def test_transfer_order_hold(self): """Test API endpoint for holdling a TransferOrder.""" to = models.TransferOrder.objects.get(pk=1) @@ -3300,6 +4289,222 @@ class TransferOrderTest(OrderTest): location=destination, ) + def test_transfer_order_depleted_allocation(self): + """Completion handles allocations whose stock was reduced after allocation. + + Regression test: the 'transferred' quantity used to be incremented by the + *allocated* quantity even when less (or no) stock was actually moved. + """ + self.assignRole('transfer_order.add') + destination = StockLocation.objects.first() + + to = models.TransferOrder.objects.create( + reference='TO-54321', description='Test TO', destination=destination + ) + + part = Part.objects.exclude(virtual=True).first() + + line_a = models.TransferOrderLineItem.objects.create( + order=to, part=part, quantity=10 + ) + line_b = models.TransferOrderLineItem.objects.create( + order=to, part=part, quantity=10 + ) + + url = reverse('api-transfer-order-issue', kwargs={'pk': to.pk}) + self.post(url, {}, expected_code=201) + + item_a = StockItem.objects.create(part=part, quantity=10, batch='to-reduced') + item_b = StockItem.objects.create(part=part, quantity=10, batch='to-depleted') + + models.TransferOrderAllocation.objects.create( + quantity=10, line=line_a, item=item_a + ) + models.TransferOrderAllocation.objects.create( + quantity=10, line=line_b, item=item_b + ) + + # Reduce the available stock *after* the allocations have been made + item_a.quantity = 6 + item_a.save() + + item_b.quantity = 0 + item_b.save() + + url = reverse('api-transfer-order-complete', kwargs={'pk': to.pk}) + self.post(url, {}, expected_code=201) + + to.refresh_from_db() + self.assertEqual(to.status, TransferOrderStatus.COMPLETE.value) + + # Only the quantity which was actually available has been transferred + line_a.refresh_from_db() + item_a.refresh_from_db() + self.assertEqual(line_a.transferred, 6) + self.assertEqual(item_a.location, destination) + self.assertEqual(item_a.quantity, 6) + + # The depleted allocation was skipped, without error + line_b.refresh_from_db() + item_b.refresh_from_db() + self.assertEqual(line_b.transferred, 0) + self.assertIsNone(item_b.location) + + def test_transfer_order_consume_depleted_allocation(self): + """Consume-type completion only records the quantity actually consumed.""" + self.assignRole('transfer_order.add') + + to = models.TransferOrder.objects.create( + reference='TO-54322', description='Test TO', consume=True + ) + + part = Part.objects.exclude(virtual=True).first() + + line = models.TransferOrderLineItem.objects.create( + order=to, part=part, quantity=10 + ) + + url = reverse('api-transfer-order-issue', kwargs={'pk': to.pk}) + self.post(url, {}, expected_code=201) + + item = StockItem.objects.create( + part=part, quantity=100, batch='to-consume', delete_on_deplete=False + ) + + models.TransferOrderAllocation.objects.create(quantity=10, line=line, item=item) + + # Reduce the available stock *after* the allocation has been made + item.quantity = 4 + item.save() + + url = reverse('api-transfer-order-complete', kwargs={'pk': to.pk}) + self.post(url, {}, expected_code=201) + + to.refresh_from_db() + self.assertEqual(to.status, TransferOrderStatus.COMPLETE.value) + + # Only the quantity which was actually available has been consumed + line.refresh_from_db() + item.refresh_from_db() + self.assertEqual(line.transferred, 4) + self.assertEqual(item.quantity, 0) + + def test_transfer_order_partial_allocation_stale_item_instance(self): + """A partial allocation must not fail completion if stock is reduced concurrently. + + Regression test: transfer_quantity (and the choice between the "move" and + "split" branches) was computed from self.item.quantity as cached in memory + on the allocation instance. If the stock item's quantity was reduced by a + concurrent operation after the allocation was loaded, the stale value could + select the "split" branch when only a "move" of the entire (now-reduced) + item is actually possible - causing splitStock() to reject the now-oversized + split, and the whole order completion to fail. The stock item's row is now + locked and its quantity refreshed before the branch is chosen. + """ + self.assignRole('transfer_order.add') + destination = StockLocation.objects.first() + + to = models.TransferOrder.objects.create( + reference='TO-STALE-ITEM', description='Test TO', destination=destination + ) + + part = Part.objects.exclude(virtual=True).first() + + line = models.TransferOrderLineItem.objects.create( + order=to, part=part, quantity=6 + ) + + to.issue_order() + + item = StockItem.objects.create(part=part, quantity=10, batch='to-stale-item') + + # A partial allocation - less than the full stock item quantity + allocation = models.TransferOrderAllocation.objects.create( + quantity=6, line=line, item=item + ) + + # Load a second copy of the allocation, caching the item's original quantity + stale_allocation = models.TransferOrderAllocation.objects.get(pk=allocation.pk) + self.assertEqual(stale_allocation.item.quantity, 10) + + # Reduce the available stock *after* the stale copy was loaded + # (simulating a concurrent stock adjustment) + item.quantity = 4 + item.save() + + # Completing the (stale) allocation must not raise, and must transfer + # only the quantity which is actually available + stale_allocation.complete_allocation(None) + + item.refresh_from_db() + line.refresh_from_db() + + self.assertEqual(item.location, destination) + self.assertEqual(item.quantity, 4) + self.assertEqual(line.transferred, 4) + + def test_transfer_order_complete_stale_instance(self): + """A second completion attempt with a stale instance must be rejected. + + Regression test: _action_complete() only checked the *in-memory* status, + so two concurrent completion requests (each holding its own instance of + the order) could both observe status=ISSUED and each process every + allocation - duplicating all stock movements and double-counting the + 'transferred' quantity. The status is now re-read (under lock) from the + database before the allocations are processed. + """ + self.assignRole('transfer_order.add') + destination = StockLocation.objects.first() + + to = models.TransferOrder.objects.create( + reference='TO-54323', description='Test TO', destination=destination + ) + + part = Part.objects.exclude(virtual=True).first() + + line = models.TransferOrderLineItem.objects.create( + order=to, part=part, quantity=10 + ) + + to.issue_order() + to.refresh_from_db() + self.assertEqual(to.status, TransferOrderStatus.ISSUED.value) + + item = StockItem.objects.create(part=part, quantity=10, batch='to-stale') + models.TransferOrderAllocation.objects.create(quantity=10, line=line, item=item) + + # Two "concurrent" requests each hold their own instance of the order + instance_a = models.TransferOrder.objects.get(pk=to.pk) + instance_b = models.TransferOrder.objects.get(pk=to.pk) + + self.assertTrue(instance_a.complete_order(None)) + + line.refresh_from_db() + self.assertEqual(line.transferred, 10) + + # The second (stale) instance still believes the order is ISSUED, + # but completion must be rejected based on the database state + self.assertEqual(instance_b.status, TransferOrderStatus.ISSUED.value) + + with self.assertRaises(ValidationError) as err: + instance_b.complete_order(None) + + self.assertIn('Transfer Order is already Complete', str(err.exception)) + + # The transferred quantity has not been double-counted + line.refresh_from_db() + self.assertEqual(line.transferred, 10) + + # check that the wrong starting point also triggers an error + instance_b.status = TransferOrderStatus.CANCELLED.value + instance_b.save() + with self.assertRaises(ValidationError) as err: + instance_b.complete_order(None) + self.assertIn( + 'Invalid transition on Transfer Order.status (source value should be 20, is 40)', + str(err.exception), + ) + def test_output_options(self): """Test the output options for the TransferOrder detail endpoint.""" self.run_output_test( @@ -3384,6 +4589,63 @@ class TransferOrderLineItemTest(OrderTest): self.filter({'allocated': 'true'}, 2) self.filter({'allocated': 'false'}, n - 2) + def test_transfer_order_line_bulk_delete(self): + """Test that we can bulk delete multiple TransferOrderLineItems via the API.""" + n = models.TransferOrderLineItem.objects.count() + + # Select lines from orders which are not completed (and thus not locked) + items = list( + models.TransferOrderLineItem.objects.exclude( + order__status__in=TransferOrderStatusGroups.COMPLETE + ).values_list('pk', flat=True)[:2] + ) + + # Deletion should fail without the correct role + self.delete(self.url, {'items': items}, expected_code=403) + + self.assignRole('transfer_order.delete') + + self.delete(self.url, {'items': items}, expected_code=200) + + # We should have 2 less TransferOrderLineItems after deleting them + self.assertEqual(models.TransferOrderLineItem.objects.count(), n - 2) + + def test_completed_order_locked(self): + """Test that line items cannot be deleted from a completed TransferOrder.""" + self.assignRole('transfer_order.delete') + + set_global_setting(models.TransferOrder.UNLOCK_SETTING, False) + + order = models.TransferOrder.objects.filter( + status=TransferOrderStatus.PENDING.value, lines__isnull=False + ).first() + assert order + + # Mark the order as complete + order.status = TransferOrderStatus.COMPLETE.value + order.save() + + n = order.lines.count() + self.assertGreater(n, 1) + + line = order.lines.first() + detail_url = reverse('api-transfer-order-line-detail', kwargs={'pk': line.pk}) + + # Single deletion of a line item should fail + self.delete(detail_url, expected_code=400) + + # Bulk deletion should also fail (and roll back atomically) + items = list(order.lines.values_list('pk', flat=True)) + self.delete(self.url, {'items': items}, expected_code=400) + + self.assertEqual(order.lines.count(), n) + + # Unlocking completed orders should allow deletion again + set_global_setting(models.TransferOrder.UNLOCK_SETTING, True) + + self.delete(detail_url, expected_code=204) + self.assertEqual(order.lines.count(), n - 1) + def test_transfer_order_line_allocated_filters(self): """Test filtering by allocation status for a TransferOrderLineItem.""" self.assignRole('transfer_order.add') @@ -3740,3 +5002,480 @@ class TransferOrderAllocateTest(OrderTest): ['part_detail', 'item_detail', 'order_detail', 'location_detail'], assert_subset=True, ) + + +@skipUnlessDBFeature('has_select_for_update') +class TransferOrderSerialAllocateConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for serial-based transfer order allocation. + + Uses two real threads (each with its own database connection) to reproduce + the reported race: two concurrent requests to allocate the *same* serial + number (against two different TransferOrder line items) could both resolve + and validate the serialized StockItem as available before either had + committed its bulk_create - allocating the same physical unit twice. + + TransferOrderSerialAllocationSerializer.save() now locks each resolved + StockItem (select_for_update, via StockItem.lock_quantity()) and + re-validates its unallocated quantity under that lock before it is added + to the batch that gets created, so only one of two concurrent requests for + the same serial number may succeed. + """ + + fixtures = ['users'] + + def setUp(self): + """Create two TransferOrder lines which both request the same serial number.""" + super().setUp() + + self.part = Part.objects.create( + name='Concurrency trackable part', + description='Part for serial allocation concurrency test', + trackable=True, + ) + + self.order_a = models.TransferOrder.objects.create(reference='TO-CONC-A') + self.order_b = models.TransferOrder.objects.create(reference='TO-CONC-B') + + self.line_a = models.TransferOrderLineItem.objects.create( + order=self.order_a, part=self.part, quantity=1 + ) + self.line_b = models.TransferOrderLineItem.objects.create( + order=self.order_b, part=self.part, quantity=1 + ) + + # Only a single physical unit exists for this serial number + self.stock_item = StockItem.objects.create( + part=self.part, quantity=1, serial='1' + ) + + def test_concurrent_allocation_does_not_duplicate_serial(self): + """Two concurrent requests for the same serial number must not both succeed.""" + start_barrier = threading.Barrier(2, timeout=5) + errors = [] + results = [] + + # Wrap StockItem.lock_quantity() so both threads reach the (real, + # database-level) row lock at the same time - one wins the lock and + # proceeds, the other blocks until the winner's transaction completes. + original_lock_quantity = StockItem.lock_quantity + + def synced_lock_quantity(self_item): + start_barrier.wait(timeout=5) + return original_lock_quantity(self_item) + + def allocate(line_item): + try: + serializer = TransferOrderSerialAllocationSerializer( + data={ + 'line_item': line_item.pk, + 'quantity': 1, + 'serial_numbers': '1', + }, + context={'order': line_item.order}, + ) + serializer.is_valid(raise_exception=True) + serializer.save() + results.append('ok') + except (ValidationError, DRFValidationError): + results.append('rejected') + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + thread_a = threading.Thread(target=allocate, args=(self.line_a,)) + thread_b = threading.Thread(target=allocate, args=(self.line_b,)) + + with mock.patch.object(StockItem, 'lock_quantity', synced_lock_quantity): + thread_a.start() + thread_b.start() + + thread_a.join(timeout=5) + thread_b.join(timeout=5) + + self.assertFalse(thread_a.is_alive()) + self.assertFalse(thread_b.is_alive()) + self.assertEqual(errors, []) + + # Exactly one request must have been rejected as unavailable + self.assertEqual(sorted(results), ['ok', 'rejected']) + + # The serial number must only have been allocated once + self.assertEqual( + models.TransferOrderAllocation.objects.filter(item=self.stock_item).count(), + 1, + ) + + +class SalesOrderAutoAllocateAPITest(InvenTreeAPITestCase): + """API integration tests for the SalesOrder auto-allocate endpoint.""" + + fixtures = ['company', 'users'] + + roles = ['sales_order.add', 'sales_order.change', 'sales_order.delete'] + + @classmethod + def setUpTestData(cls): + """Create shared order, parts, locations and stock for all tests.""" + super().setUpTestData() + + cls.customer = Company.objects.create( + name='Test Customer', is_customer=True, description='' + ) + cls.part = Part.objects.create( + name='AutoAlloc Part', salable=True, description='' + ) + + cls.loc_a = StockLocation.objects.create(name='Shelf A') + cls.loc_b = StockLocation.objects.create(name='Shelf B') + + def _make_order(self, qty=50): + """Create a fresh SalesOrder with one line item and one shipment.""" + order = models.SalesOrder.objects.create( + customer=self.customer, + reference=f'SO-TEST-{models.SalesOrder.objects.count()}', + ) + line = SalesOrderLineItem.objects.create( + order=order, part=self.part, quantity=qty + ) + shipment = SalesOrderShipment.objects.create(order=order) + return order, line, shipment + + def _url(self, pk): + return reverse('api-so-auto-allocate', kwargs={'pk': pk}) + + # ------------------------------------------------------------------ + # Permission and basic response tests + # ------------------------------------------------------------------ + + def test_requires_authentication(self): + """POST without authentication returns 401.""" + self.client.logout() + order, _, _ = self._make_order() + self.post(self._url(order.pk), {}, expected_code=401) + + def test_basic_post_returns_200(self): + """POST with defaults runs synchronously in tests and returns 200.""" + order, line, _ = self._make_order() + StockItem.objects.create(part=self.part, quantity=100) + + response = self.post(self._url(order.pk), {}, expected_code=200) + + self.assertIn('task_id', response.data) + self.assertTrue(response.data['complete']) + self.assertTrue(response.data['success']) + + # Task ran synchronously — allocations are already committed + self.assertTrue(line.is_fully_allocated()) + + def test_invalid_order_pk_returns_404(self): + """POST to a non-existent order pk returns 404.""" + self.post(self._url(999999), {}, expected_code=404) + + # ------------------------------------------------------------------ + # Field validation + # ------------------------------------------------------------------ + + def test_invalid_stock_sort_by_rejected(self): + """An unrecognised stock_sort_by value is rejected with 400.""" + order, _, _ = self._make_order() + self.post( + self._url(order.pk), + {'stock_sort_by': 'not_a_valid_sort'}, + expected_code=400, + ) + + def test_invalid_serialized_stock_rejected(self): + """An unrecognised serialized_stock value is rejected with 400.""" + order, _, _ = self._make_order() + self.post(self._url(order.pk), {'serialized_stock': 'maybe'}, expected_code=400) + + def test_shipment_from_another_order_rejected(self): + """A shipment that belongs to a different order is rejected with 400.""" + order, _, _ = self._make_order() + _other_order, _, other_shipment = self._make_order() + + self.post( + self._url(order.pk), {'shipment': other_shipment.pk}, expected_code=400 + ) + + def test_shipped_shipment_rejected(self): + """A shipment that has already been marked as shipped is rejected with 400.""" + from datetime import date + + order, _, shipment = self._make_order() + shipment.shipment_date = date.today() + shipment.save() + + self.post(self._url(order.pk), {'shipment': shipment.pk}, expected_code=400) + + def test_line_items_from_another_order_rejected(self): + """line_items belonging to a different order are rejected with 400.""" + order, _, _ = self._make_order() + _, other_line, _ = self._make_order() + + self.post( + self._url(order.pk), {'line_items': [other_line.pk]}, expected_code=400 + ) + + # ------------------------------------------------------------------ + # Allocation behaviour + # ------------------------------------------------------------------ + + def test_allocates_available_stock(self): + """Stock is allocated to the line item after a successful POST.""" + order, line, _ = self._make_order(qty=30) + item = StockItem.objects.create(part=self.part, quantity=100) + + self.post(self._url(order.pk), {}, expected_code=200) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().item, item) + self.assertEqual(allocs.first().quantity, 30) + + def test_line_items_subset_only_allocates_selected_lines(self): + """When line_items is specified only those lines are allocated.""" + order = models.SalesOrder.objects.create( + customer=self.customer, + reference=f'SO-SUBSET-{models.SalesOrder.objects.count()}', + ) + line_a = SalesOrderLineItem.objects.create( + order=order, part=self.part, quantity=10 + ) + part_b = Part.objects.create(name='Part B', salable=True, description='') + line_b = SalesOrderLineItem.objects.create( + order=order, part=part_b, quantity=10 + ) + + StockItem.objects.create(part=self.part, quantity=50) + StockItem.objects.create(part=part_b, quantity=50) + + self.post(self._url(order.pk), {'line_items': [line_a.pk]}, expected_code=200) + + self.assertTrue(line_a.is_fully_allocated()) + self.assertFalse(line_b.is_fully_allocated()) + + def test_serialized_stock_only(self): + """serialized_stock='serialized' allocates only serialized items.""" + order, line, _ = self._make_order(qty=1) + # Unserialized item + StockItem.objects.create(part=self.part, quantity=50) + # Serialized item + serial_item = StockItem.objects.create( + part=self.part, quantity=1, serial='SN-001' + ) + + self.post( + self._url(order.pk), {'serialized_stock': 'serialized'}, expected_code=200 + ) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().item, serial_item) + + def test_unserialized_stock_only(self): + """serialized_stock='unserialized' skips serialized items.""" + order, line, _ = self._make_order(qty=10) + # Serialized items only + for sn in range(10): + StockItem.objects.create(part=self.part, quantity=1, serial=f'SN-{sn}') + + self.post( + self._url(order.pk), {'serialized_stock': 'unserialized'}, expected_code=200 + ) + + self.assertFalse(line.is_fully_allocated()) + self.assertEqual(SalesOrderAllocation.objects.filter(line=line).count(), 0) + + def test_stock_sort_by_quantity_asc(self): + """stock_sort_by=QUANTITY_ASC consumes the smallest lot first.""" + order, line, _ = self._make_order(qty=15) + small = StockItem.objects.create(part=self.part, quantity=5) + StockItem.objects.create(part=self.part, quantity=100) + + self.post( + self._url(order.pk), + { + 'stock_sort_by': str(StockSortOrder.QUANTITY_ASC), + 'interchangeable': True, + }, + expected_code=200, + ) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(any(a.item == small and a.quantity == 5 for a in allocs)) + + def test_stock_sort_by_quantity_desc(self): + """stock_sort_by=QUANTITY_DESC consumes the largest lot first, covering the requirement in one allocation.""" + order, line, _ = self._make_order(qty=15) + StockItem.objects.create(part=self.part, quantity=5) + StockItem.objects.create(part=self.part, quantity=100) + + self.post( + self._url(order.pk), + { + 'stock_sort_by': str(StockSortOrder.QUANTITY_DESC), + 'interchangeable': True, + }, + expected_code=200, + ) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().quantity, 15) + + def test_location_filter(self): + """Only stock within the specified location is used.""" + order, line, _ = self._make_order(qty=10) + StockItem.objects.create(part=self.part, quantity=50, location=self.loc_a) + StockItem.objects.create(part=self.part, quantity=50, location=self.loc_b) + + self.post(self._url(order.pk), {'location': self.loc_a.pk}, expected_code=200) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().item.location, self.loc_a) + + def test_exclude_location_filter(self): + """Stock in the excluded location is not used.""" + order, line, _ = self._make_order(qty=10) + StockItem.objects.create(part=self.part, quantity=50, location=self.loc_a) + StockItem.objects.create(part=self.part, quantity=50, location=self.loc_b) + + self.post( + self._url(order.pk), {'exclude_location': self.loc_a.pk}, expected_code=200 + ) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().item.location, self.loc_b) + + def test_shipment_assigned_to_allocations(self): + """When a shipment is specified, all allocations are assigned to it.""" + order, line, shipment = self._make_order(qty=20) + StockItem.objects.create(part=self.part, quantity=100) + + self.post(self._url(order.pk), {'shipment': shipment.pk}, expected_code=200) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(allocs.exists()) + for alloc in allocs: + self.assertEqual(alloc.shipment, shipment) + + def test_interchangeable_false_skips_split_stock(self): + """With interchangeable=False, allocation is skipped when no single item covers the full quantity.""" + order, line, _ = self._make_order(qty=50) + StockItem.objects.create(part=self.part, quantity=20) + StockItem.objects.create(part=self.part, quantity=20) + + self.post(self._url(order.pk), {'interchangeable': False}, expected_code=200) + + self.assertFalse(line.is_fully_allocated()) + self.assertEqual(SalesOrderAllocation.objects.filter(line=line).count(), 0) + + +class SalesOrderAllocationBulkDeleteAPITest(InvenTreeAPITestCase): + """API integration tests for bulk-delete of SalesOrderAllocation, verifying shipped allocations are protected.""" + + fixtures = ['company', 'users'] + + roles = ['sales_order.add', 'sales_order.change', 'sales_order.delete'] + + @classmethod + def setUpTestData(cls): + """Create shared order, part and stock for all tests.""" + super().setUpTestData() + + cls.customer = models.Company.objects.create( + name='BulkDelete Customer', is_customer=True, description='' + ) + cls.part = Part.objects.create( + name='BulkDelete Part', salable=True, description='' + ) + + def _make_order_with_allocations(self, n_unshipped=2, n_shipped=1): + """Return (order, unshipped_allocations, shipped_allocations).""" + order = models.SalesOrder.objects.create( + customer=self.customer, + reference=f'SO-BD-{models.SalesOrder.objects.count()}', + ) + line = SalesOrderLineItem.objects.create( + order=order, part=self.part, quantity=100 + ) + unshipped_shipment = models.SalesOrderShipment.objects.create( + order=order, reference='1' + ) + + shipped_shipment = models.SalesOrderShipment.objects.create( + order=order, reference='2' + ) + shipped_shipment.shipment_date = date.today() + shipped_shipment.save() + + unshipped = [] + for _ in range(n_unshipped): + item = StockItem.objects.create(part=self.part, quantity=10) + alloc = SalesOrderAllocation.objects.create( + line=line, item=item, quantity=10, shipment=unshipped_shipment + ) + unshipped.append(alloc) + + shipped = [] + for _ in range(n_shipped): + item = StockItem.objects.create(part=self.part, quantity=10) + alloc = SalesOrderAllocation.objects.create( + line=line, item=item, quantity=10, shipment=shipped_shipment + ) + shipped.append(alloc) + + return order, unshipped, shipped + + def _url(self): + return reverse('api-so-allocation-list') + + # ------------------------------------------------------------------ + # Basic bulk-delete + # ------------------------------------------------------------------ + + def test_bulk_delete_unshipped_allocations(self): + """Unshipped allocations can be bulk-deleted.""" + _, unshipped, _ = self._make_order_with_allocations(n_unshipped=2, n_shipped=0) + ids = [a.pk for a in unshipped] + + self.delete(self._url(), {'items': ids}, expected_code=200) + + self.assertFalse(SalesOrderAllocation.objects.filter(pk__in=ids).exists()) + + # ------------------------------------------------------------------ + # Shipped allocation protection + # ------------------------------------------------------------------ + + def test_shipped_allocations_are_not_deleted(self): + """Shipped allocations are silently skipped when included in a bulk-delete request.""" + _, _, shipped = self._make_order_with_allocations(n_unshipped=0, n_shipped=2) + ids = [a.pk for a in shipped] + + self.delete(self._url(), {'items': ids}, expected_code=200) + + # All shipped allocations should still exist + self.assertEqual(SalesOrderAllocation.objects.filter(pk__in=ids).count(), 2) + + def test_mixed_delete_removes_only_unshipped(self): + """A bulk-delete of mixed shipped/unshipped allocations removes only the unshipped ones.""" + _, unshipped, shipped = self._make_order_with_allocations( + n_unshipped=2, n_shipped=2 + ) + all_ids = [a.pk for a in unshipped] + [a.pk for a in shipped] + + self.delete(self._url(), {'items': all_ids}, expected_code=200) + + # Unshipped should be gone + for alloc in unshipped: + self.assertFalse(SalesOrderAllocation.objects.filter(pk=alloc.pk).exists()) + + # Shipped should remain + shipped_ids = [a.pk for a in shipped] + self.assertEqual( + SalesOrderAllocation.objects.filter(pk__in=shipped_ids).count(), 2 + ) diff --git a/src/backend/InvenTree/order/test_sales_order.py b/src/backend/InvenTree/order/test_sales_order.py index 0186cfd90c..2c53b3a92b 100644 --- a/src/backend/InvenTree/order/test_sales_order.py +++ b/src/backend/InvenTree/order/test_sales_order.py @@ -1,17 +1,30 @@ """Unit tests for the SalesOrder models.""" +import threading from datetime import datetime, timedelta +from unittest import mock from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.core.exceptions import ValidationError +from django.db import connection +from django.db.models import Sum +from django.test import TransactionTestCase, skipUnlessDBFeature +from django.urls import reverse + +from django_q.models import OrmQ +from rest_framework.exceptions import ValidationError as DRFValidationError import order.tasks from common.models import InvenTreeSetting, NotificationMessage from common.settings import set_global_setting from company.models import Address, Company from InvenTree import status_codes as status -from InvenTree.unit_test import InvenTreeTestCase, addUserPermission +from InvenTree.unit_test import ( + InvenTreeAPITestCase, + InvenTreeTestCase, + addUserPermission, +) from order.models import ( SalesOrder, SalesOrderAllocation, @@ -19,19 +32,25 @@ from order.models import ( SalesOrderLineItem, SalesOrderShipment, ) +from order.serializers import SalesOrderShipmentAllocationSerializer from part.models import Part -from stock.models import StockItem +from stock.events import StockEvents +from stock.models import StockItem, StockItemTracking, StockLocation +from stock.status_codes import StockHistoryCode from users.models import Owner -class SalesOrderTest(InvenTreeTestCase): +class SalesOrderTest(InvenTreeAPITestCase): """Run tests to ensure that the SalesOrder model is working correctly.""" fixtures = ['company', 'users'] + roles = ['sales_order.add'] @classmethod def setUpTestData(cls): """Initial setup for this set of unit tests.""" + super().setUpTestData() + # Create a Company to ship the goods to cls.customer = Company.objects.create( name='ABC Co', description='My customer', is_customer=True @@ -178,6 +197,24 @@ class SalesOrderTest(InvenTreeTestCase): quantity=25 if full else 20, ) + def test_scratch_complete_allocation_single(self): + """Scratch check: SalesOrderAllocation.complete_allocation() backwards-compat shim.""" + self.allocate_stock(True) + + allocations = list(self.shipment.allocations.all()) + self.assertEqual(len(allocations), 2) + + for allocation in allocations: + allocation.complete_allocation(self.user) + + self.line.refresh_from_db() + self.assertEqual(self.line.shipped, 50) + + for allocation in allocations: + allocation.item.refresh_from_db() + self.assertEqual(allocation.item.sales_order, self.order) + self.assertEqual(allocation.item.customer, self.order.customer) + def test_over_allocate(self): """Test that over allocation logic works.""" SA = StockItem.objects.create(part=self.part, quantity=9) @@ -219,6 +256,30 @@ class SalesOrderTest(InvenTreeTestCase): self.assertTrue(self.line.is_fully_allocated()) self.assertEqual(self.line.allocated_quantity(), 50) + def test_complete_allocation_stale_line_instance(self): + """The 'shipped' count is incremented atomically at the database level. + + Simulates two concurrent workers completing different allocations + against the same order line, each holding its own (stale) copy of the line. + """ + self.allocate_stock(True) + + alloc_a, alloc_b = SalesOrderAllocation.objects.filter(line=self.line).order_by( + 'pk' + ) + + # Cache a separate copy of the line on each allocation + self.assertEqual(alloc_a.line.shipped, 0) + self.assertEqual(alloc_b.line.shipped, 0) + + allocations = SalesOrderAllocation.objects.filter(line=self.line).order_by('pk') + + self.shipment.complete_allocations(allocations) + + # Both shipped quantities must be counted + self.line.refresh_from_db() + self.assertEqual(self.line.shipped, 50) + def test_allocate_variant(self): """Allocate a variant of the designated item.""" SalesOrderAllocation.objects.create( @@ -244,8 +305,40 @@ class SalesOrderTest(InvenTreeTestCase): self.order.can_complete(raise_error=True) # Now try to ship it - should fail - result = self.order.ship_order(None) - self.assertFalse(result) + with self.assertRaises(ValidationError): + self.order.ship_order(None) + + def test_order_cancel_stale_instance_is_noop(self): + """A second cancellation attempt with a stale order instance must be a no-op. + + Regression test: _action_cancel() checked 'status' on the caller's + (potentially stale) instance, so two concurrent cancellation requests + could both run the cancellation side effects (duplicate CANCELLED + events). The status is now re-read (under lock) from the database + before the check. + """ + self.allocate_stock(True) + self.assertEqual(SalesOrderAllocation.objects.count(), 2) + + # Two "concurrent" requests each hold their own instance of the order + order_a = SalesOrder.objects.get(pk=self.order.pk) + order_b = SalesOrder.objects.get(pk=self.order.pk) + + order_a.cancel_order() + + self.order.refresh_from_db() + self.assertEqual(self.order.status, status.SalesOrderStatus.CANCELLED) + self.assertEqual(SalesOrderAllocation.objects.count(), 0) + + # The second (stale) instance still believes the order is PENDING - + # cancellation must be skipped based on the database state + self.assertEqual(order_b.status, status.SalesOrderStatus.PENDING) + + with self.assertRaises(ValidationError): + order_b.cancel_order() + + self.order.refresh_from_db() + self.assertEqual(self.order.status, status.SalesOrderStatus.CANCELLED) def test_complete_order(self): """Allocate line items, then ship the order.""" @@ -259,9 +352,8 @@ class SalesOrderTest(InvenTreeTestCase): self.assertEqual(SalesOrderAllocation.objects.count(), 2) # Attempt to ship the order (but shipments are not completed!) - result = self.order.ship_order(None) - - self.assertFalse(result) + with self.assertRaises(ValidationError): + self.order.ship_order(None) self.assertIsNone(self.shipment.shipment_date) self.assertFalse(self.shipment.is_complete()) @@ -336,6 +428,80 @@ class SalesOrderTest(InvenTreeTestCase): self.assertEqual(self.line.fulfilled_quantity(), 50) self.assertEqual(self.line.allocated_quantity(), 50) + def test_complete_order_stale_instance_is_noop(self): + """A second completion attempt with a stale order instance must be a no-op. + + Regression test: _action_complete() checked 'status' on the caller's + (potentially stale) instance, so two concurrent completion requests could + both run the completion side effects (duplicate COMPLETED events and + duplicate pricing-update scheduling). The status is now re-read (under + lock) from the database before the check. + """ + self.allocate_stock(True) + self.shipment.complete_shipment(None) + + # Ship the order (PENDING -> SHIPPED) + self.assertTrue(self.order.ship_order(None)) + self.order.refresh_from_db() + self.assertEqual(self.order.status, status.SalesOrderStatus.SHIPPED) + + # Two "concurrent" requests each hold their own instance of the order, + # both about to transition SHIPPED -> COMPLETE + order_a = SalesOrder.objects.get(pk=self.order.pk) + order_b = SalesOrder.objects.get(pk=self.order.pk) + + self.assertTrue(order_a.complete_order(None)) + + self.order.refresh_from_db() + self.assertEqual(self.order.status, status.SalesOrderStatus.COMPLETE) + + # The second (stale) instance still believes the order is SHIPPED - + # completion must be skipped based on the database state + self.assertEqual(order_b.status, status.SalesOrderStatus.SHIPPED) + + with self.assertRaises(ValidationError): + self.assertFalse(order_b.complete_order(None)) + + self.order.refresh_from_db() + self.assertEqual(self.order.status, status.SalesOrderStatus.COMPLETE) + + def test_complete_shipment_task_is_idempotent(self): + """Duplicate execution of the shipment completion task must not double-ship. + + Regression test: two rapid completion requests could enqueue the background + completion task twice - each execution then completed every allocation again, + double-counting the 'shipped' quantity and re-assigning stock to the customer. + """ + self.allocate_stock(True) + + # Complete the shipment (the task runs inline during testing) + self.shipment.complete_shipment(None) + + self.shipment.refresh_from_db() + self.line.refresh_from_db() + + self.assertTrue(self.shipment.is_complete()) + self.assertEqual(self.line.shipped, 50) + + # A second completion request is rejected outright + self.assertFalse(self.shipment.check_can_complete(raise_error=False)) + + n_items = StockItem.objects.count() + n_tracking = StockItemTracking.objects.count() + + # Simulate a duplicated task execution + # (e.g. a second completion request submitted before the first task ran) + order.tasks.complete_sales_order_shipment(self.shipment.pk, None, None) + + self.line.refresh_from_db() + + # The 'shipped' quantity must not be double-counted + self.assertEqual(self.line.shipped, 50) + + # No additional stock items or tracking entries have been created + self.assertEqual(StockItem.objects.count(), n_items) + self.assertEqual(StockItemTracking.objects.count(), n_tracking) + def test_shipment_many_items(self): """Test completion of a shipment with many items. @@ -345,6 +511,13 @@ class SalesOrderTest(InvenTreeTestCase): This test is designed to test that the database does not error out, even when a large number of items are assigned to a shipment. + It also checks that: + - Stock items are split (or fully consumed) correctly + - The correct stock tracking entries are created for each item + - The associated ITEM_SPLIT / ITEM_ASSIGNED_TO_CUSTOMER events are queued + - A low-stock check is queued for the (single) affected part + - Line 'shipped' quantities and allocation->item references are updated correctly + Ref: https://github.com/inventree/InvenTree/pull/11500 """ customer = Company.objects.create(name='Customer 2', is_customer=True) @@ -367,27 +540,27 @@ class SalesOrderTest(InvenTreeTestCase): line = SalesOrderLineItem.objects.create(part=part, order=so, quantity=N_ITEMS) # Create stock items, and assign to shipment + # Every 5th item has exactly the allocated quantity (no split required); + # the rest have excess quantity (requiring a split) allocations = [] stock_items = [] - tree_id = StockItem.objects.all().order_by('-tree_id').first().tree_id - for idx in range(N_ITEMS): - tree_id += 1 - - stock_items.append( - StockItem( - part=part, - quantity=1 + idx % 5, - level=0, - lft=0, - rght=0, - tree_id=tree_id, - ) - ) + stock_items.append(StockItem(part=part, quantity=1 + idx % 5)) StockItem.objects.bulk_create(stock_items) + # Re-fetch the created items, as bulk_create() does not guarantee that the + # pk values of the passed-in objects are populated (e.g. on MySQL) + stock_items = list(StockItem.objects.filter(part=part)) + + # Original quantity of each stock item, keyed by pk (used for verification below) + original_quantities = {item.pk: item.quantity for item in stock_items} + split_pks = {pk for pk, qty in original_quantities.items() if qty > 1} + exact_pks = {pk for pk, qty in original_quantities.items() if qty == 1} + self.assertEqual(len(split_pks), N_ITEMS * 4 // 5) + self.assertEqual(len(exact_pks), N_ITEMS // 5) + # Check expected available quantity self.assertEqual(part.total_stock, 2250) @@ -407,8 +580,30 @@ class SalesOrderTest(InvenTreeTestCase): self.assertFalse(shipment.is_complete()) self.assertTrue(shipment.check_can_complete(raise_error=False)) - # Complete the shipment - shipment.complete_shipment(None) + # Complete the shipment via the API + self.assignRole('sales_order.add') + + # Enable plugin events, and queue them (rather than firing synchronously), + # so we can inspect exactly what was queued once the shipment is completed + set_global_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + # Start with a fresh slate for the OrmQ queue + OrmQ.objects.all().delete() + + url = reverse('api-so-shipment-ship', kwargs={'pk': shipment.pk}) + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + response = self.post( + url, + expected_code=200, + benchmark=True, + max_query_time=5.0, + max_query_count=100, + ) + + self.assertEqual(response.status_code, 200) shipment.refresh_from_db() self.assertIsNotNone(shipment.shipment_date) @@ -418,6 +613,143 @@ class SalesOrderTest(InvenTreeTestCase): part.refresh_from_db() self.assertEqual(part.total_stock, 2250 - N_ITEMS) + # The line item should now show the full quantity as 'shipped' + line.refresh_from_db() + self.assertEqual(line.shipped, N_ITEMS) + + # Every allocation should now point to a StockItem which has been assigned to the customer + self.assertEqual( + shipment.allocations.filter( + item__sales_order=so, item__customer=customer + ).count(), + N_ITEMS, + ) + + queued_tasks = list(OrmQ.objects.all()) + + # register_event tasks queued for StockEvents.ITEM_SPLIT, one per split item + split_event_tasks = [ + task + for task in queued_tasks + if task.func() == 'plugin.base.event.events.register_event' + and task.args() == (StockEvents.ITEM_SPLIT,) + ] + self.assertEqual(len(split_event_tasks), len(split_pks)) + + # register_event tasks queued for StockEvents.ITEM_ASSIGNED_TO_CUSTOMER, one per item + customer_event_tasks = [ + task + for task in queued_tasks + if task.func() == 'plugin.base.event.events.register_event' + and task.args() == (StockEvents.ITEM_ASSIGNED_TO_CUSTOMER,) + ] + self.assertEqual(len(customer_event_tasks), N_ITEMS) + + # 'notify_low_stock_if_required' should be queued exactly once - there is only + # a single distinct part involved, despite the large number of stock items + low_stock_tasks = [ + task + for task in queued_tasks + if task.func() == 'part.tasks.notify_low_stock_if_required' + ] + self.assertEqual(len(low_stock_tasks), 1) + self.assertEqual(low_stock_tasks[0].args(), (part.pk,)) + + # Exactly one StockItemTracking entry should exist per split, per side + self.assertEqual( + StockItemTracking.objects.filter( + tracking_type=StockHistoryCode.SPLIT_FROM_PARENT.value + ).count(), + len(split_pks), + ) + self.assertEqual( + StockItemTracking.objects.filter( + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value + ).count(), + len(split_pks), + ) + + # Exactly one 'shipped' tracking entry should exist per allocated item + self.assertEqual( + StockItemTracking.objects.filter( + tracking_type=StockHistoryCode.SHIPPED_AGAINST_SALES_ORDER.value + ).count(), + N_ITEMS, + ) + + # Check the original (exact-quantity) stock items were consumed directly, with no split + for pk in exact_pks: + item = StockItem.objects.get(pk=pk) + self.assertEqual(item.quantity, 1) + self.assertEqual(item.sales_order, so) + self.assertEqual(item.customer, customer) + + self.assertFalse( + StockItemTracking.objects.filter( + item=item, tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value + ).exists() + ) + self.assertTrue( + StockItemTracking.objects.filter( + item=item, + tracking_type=StockHistoryCode.SHIPPED_AGAINST_SALES_ORDER.value, + deltas__salesorder=so.pk, + ).exists() + ) + + # Check that the split (excess-quantity) stock items were correctly split + for pk in split_pks: + original_item = StockItem.objects.get(pk=pk) + original_quantity = original_quantities[pk] + + # The original item should retain the remainder, and *not* be shipped + self.assertEqual(original_item.quantity, original_quantity - 1) + self.assertIsNone(original_item.sales_order) + self.assertIsNone(original_item.customer) + + # Spot-check a single split item for the exact linkage between tracking entries + # (aggregate counts above already confirm this holds for every split item) + sample_pk = next(iter(split_pks)) + sample_original = StockItem.objects.get(pk=sample_pk) + sample_new_item = StockItem.objects.get( + part=part, quantity=1, sales_order=so, parent=sample_original + ) + + self.assertEqual(sample_new_item.quantity, 1) + self.assertTrue( + StockItemTracking.objects.filter( + item=sample_new_item, + tracking_type=StockHistoryCode.SPLIT_FROM_PARENT.value, + deltas__stockitem=sample_original.pk, + ).exists() + ) + self.assertTrue( + StockItemTracking.objects.filter( + item=sample_original, + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value, + ).exists() + ) + self.assertTrue( + StockItemTracking.objects.filter( + item=sample_new_item, + tracking_type=StockHistoryCode.SHIPPED_AGAINST_SALES_ORDER.value, + deltas__salesorder=so.pk, + ).exists() + ) + self.assertTrue( + any( + task.kwargs() + == {'id': sample_new_item.pk, 'parent': sample_original.pk} + for task in split_event_tasks + ) + ) + + # The allocation for the split item should now point at the new (split-off) item + allocation = SalesOrderAllocation.objects.get( + line=line, shipment=shipment, item=sample_new_item + ) + self.assertNotEqual(allocation.item_id, sample_pk) + def test_default_shipment(self): """Test sales order default shipment creation.""" # Default setting value should be False @@ -619,3 +951,353 @@ class SalesOrderTest(InvenTreeTestCase): # Ensure that virtual line item quantity values have been updated for line in so.lines.all(): self.assertEqual(line.shipped, line.quantity) + + +class SalesOrderAutoAllocateTest(InvenTreeTestCase): + """Tests for SalesOrder.auto_allocate_stock().""" + + fixtures = ['company', 'users'] + + @classmethod + def setUpTestData(cls): + """Create a basic order, line items, and stock items for each test.""" + cls.customer = Company.objects.create( + name='Auto Alloc Co', description='', is_customer=True + ) + cls.part = Part.objects.create( + name='Widget', salable=True, description='A salable widget' + ) + cls.virtual_part = Part.objects.create( + name='Virtual Widget', + salable=True, + virtual=True, + description='A virtual part', + ) + + cls.loc_a = StockLocation.objects.create(name='Shelf A') + cls.loc_b = StockLocation.objects.create(name='Shelf B', parent=cls.loc_a) + + def _make_order(self, qty=50): + order = SalesOrder.objects.create(customer=self.customer) + line = SalesOrderLineItem.objects.create( + order=order, part=self.part, quantity=qty + ) + shipment = SalesOrderShipment.objects.create(order=order) + return order, line, shipment + + def test_allocates_single_item(self): + """A single stock item that covers the full quantity is fully allocated.""" + order, line, _ = self._make_order(qty=30) + stock = StockItem.objects.create(part=self.part, quantity=100) + + order.auto_allocate_stock() + + self.assertEqual(SalesOrderAllocation.objects.filter(line=line).count(), 1) + alloc = SalesOrderAllocation.objects.get(line=line) + self.assertEqual(alloc.item, stock) + self.assertEqual(alloc.quantity, 30) + self.assertTrue(line.is_fully_allocated()) + + def test_interchangeable_consumes_multiple_items(self): + """With interchangeable=True (default), multiple stock items are consumed.""" + order, line, _ = self._make_order(qty=50) + StockItem.objects.create(part=self.part, quantity=20) + StockItem.objects.create(part=self.part, quantity=40) + + order.auto_allocate_stock(interchangeable=True) + + total = SalesOrderAllocation.objects.filter(line=line).aggregate( + t=Sum('quantity') + )['t'] + self.assertEqual(total, 50) + self.assertTrue(line.is_fully_allocated()) + + def test_not_interchangeable_skips_split_stock(self): + """With interchangeable=False, allocation is skipped when stock is split.""" + order, line, _ = self._make_order(qty=50) + StockItem.objects.create(part=self.part, quantity=20) + StockItem.objects.create(part=self.part, quantity=20) + + order.auto_allocate_stock(interchangeable=False) + + self.assertEqual(SalesOrderAllocation.objects.filter(line=line).count(), 0) + self.assertFalse(line.is_fully_allocated()) + + def test_not_interchangeable_uses_single_sufficient_item(self): + """With interchangeable=False, a single item that covers the full qty is used.""" + order, line, _ = self._make_order(qty=30) + StockItem.objects.create(part=self.part, quantity=10) + StockItem.objects.create(part=self.part, quantity=50) + + order.auto_allocate_stock(interchangeable=False) + + self.assertEqual(SalesOrderAllocation.objects.filter(line=line).count(), 1) + alloc = SalesOrderAllocation.objects.get(line=line) + self.assertEqual(alloc.quantity, 30) + + def test_location_filter(self): + """Only stock within the specified location tree is considered.""" + order, line, _ = self._make_order(qty=10) + StockItem.objects.create(part=self.part, quantity=100, location=self.loc_a) + StockItem.objects.create(part=self.part, quantity=100) # no location + + order.auto_allocate_stock(location=self.loc_a) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(allocs.exists()) + for alloc in allocs: + self.assertEqual(alloc.item.location, self.loc_a) + + def test_exclude_location_filter(self): + """Stock within the excluded location tree is not used.""" + order, line, _ = self._make_order(qty=10) + excluded = StockItem.objects.create( + part=self.part, quantity=100, location=self.loc_a + ) + included = StockItem.objects.create(part=self.part, quantity=100) + + order.auto_allocate_stock(exclude_location=self.loc_a) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(allocs.exists()) + allocated_items = [a.item for a in allocs] + self.assertNotIn(excluded, allocated_items) + self.assertIn(included, allocated_items) + + def test_skips_fully_allocated_lines(self): + """Lines that are already fully allocated are not touched.""" + order, line, shipment = self._make_order(qty=10) + existing = StockItem.objects.create(part=self.part, quantity=100) + SalesOrderAllocation.objects.create( + line=line, item=existing, quantity=10, shipment=shipment + ) + self.assertTrue(line.is_fully_allocated()) + + order.auto_allocate_stock() + + self.assertEqual(SalesOrderAllocation.objects.filter(line=line).count(), 1) + + def test_skips_virtual_parts(self): + """Line items for virtual parts are skipped (virtual parts cannot hold stock).""" + order = SalesOrder.objects.create(customer=self.customer) + virtual_line = SalesOrderLineItem.objects.create( + order=order, part=self.virtual_part, quantity=5 + ) + + order.auto_allocate_stock() + + self.assertEqual( + SalesOrderAllocation.objects.filter(line=virtual_line).count(), 0 + ) + # Virtual parts are considered fully allocated without any stock + self.assertTrue(virtual_line.is_fully_allocated()) + + def test_allocates_serialized_stock(self): + """Serialized stock items are included in auto-allocation.""" + order, line, _ = self._make_order(qty=1) + serialized = StockItem.objects.create( + part=self.part, quantity=1, serial='SN001' + ) + + order.auto_allocate_stock() + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().item, serialized) + self.assertTrue(line.is_fully_allocated()) + + def test_shipment_assigned(self): + """Allocations are assigned to the provided shipment.""" + order, line, shipment = self._make_order(qty=10) + StockItem.objects.create(part=self.part, quantity=50) + + order.auto_allocate_stock(shipment=shipment) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(allocs.exists()) + for alloc in allocs: + self.assertEqual(alloc.shipment, shipment) + + def test_sort_quantity_asc(self): + """quantity_asc sort consumes smallest lots first.""" + order, line, _ = self._make_order(qty=15) + small = StockItem.objects.create(part=self.part, quantity=5) + StockItem.objects.create(part=self.part, quantity=100) + + order.auto_allocate_stock(stock_sort_by='quantity', interchangeable=True) + + allocs = SalesOrderAllocation.objects.filter(line=line).order_by('quantity') + self.assertTrue(allocs.exists()) + # Small lot should be fully consumed + self.assertTrue(any(a.item == small and a.quantity == 5 for a in allocs)) + + def test_sort_quantity_desc(self): + """quantity_desc sort consumes largest lots first.""" + order, line, _ = self._make_order(qty=15) + StockItem.objects.create(part=self.part, quantity=5) + large = StockItem.objects.create(part=self.part, quantity=100) + + order.auto_allocate_stock(stock_sort_by='-quantity', interchangeable=True) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(allocs.exists()) + # Large lot should be the first consumed (fully covers 15) + self.assertEqual(allocs.count(), 1) + self.assertEqual(allocs.first().item, large) + + def test_task_resolves_pk_params(self): + """auto_allocate_sales_order task resolves location/shipment pks to instances.""" + from order.tasks import auto_allocate_sales_order + + order, line, shipment = self._make_order(qty=10) + StockItem.objects.create(part=self.part, quantity=50, location=self.loc_a) + + auto_allocate_sales_order( + order.pk, location_id=self.loc_a.pk, shipment_id=shipment.pk + ) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(allocs.exists()) + for alloc in allocs: + self.assertEqual(alloc.shipment, shipment) + self.assertEqual(alloc.item.location, self.loc_a) + + def test_task_exclude_location_pk(self): + """auto_allocate_sales_order respects exclude_location_id parameter.""" + from order.tasks import auto_allocate_sales_order + + order, line, _ = self._make_order(qty=10) + excluded = StockItem.objects.create( + part=self.part, quantity=50, location=self.loc_a + ) + included = StockItem.objects.create(part=self.part, quantity=50) + + auto_allocate_sales_order(order.pk, exclude_location_id=self.loc_a.pk) + + allocs = SalesOrderAllocation.objects.filter(line=line) + self.assertTrue(allocs.exists()) + allocated_items = [a.item for a in allocs] + self.assertNotIn(excluded, allocated_items) + self.assertIn(included, allocated_items) + + +@skipUnlessDBFeature('has_select_for_update') +class SalesOrderAllocateStockConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for sales order stock allocation. + + Uses two real threads (each with its own database connection) to reproduce + the reported race: two concurrent allocation requests, against two + different SalesOrder line items but the *same* StockItem, could each read + the item's unallocated quantity before either had committed, and both + create a SalesOrderAllocation for the full quantity - over-allocating the + StockItem. There was no order-level lock serializing these requests + against each other, since they target different orders. + + SalesOrderShipmentAllocationSerializer.save() now locks the referenced + StockItem (select_for_update, via StockItem.lock_quantity()) before + validating and creating each allocation, so only one of two concurrent + full-quantity allocation requests against a shared StockItem may succeed. + """ + + fixtures = ['users'] + + def setUp(self): + """Create two SalesOrders which both request the same shared StockItem.""" + super().setUp() + + self.user = get_user_model().objects.get(pk=1) + + self.customer = Company.objects.create( + name='Concurrency customer', + description='Customer for allocation concurrency test', + is_customer=True, + ) + + self.part = Part.objects.create( + name='Concurrency salable part', + description='Part for allocation concurrency test', + salable=True, + ) + + self.order_a = SalesOrder.objects.create( + customer=self.customer, reference='SO-CONC-A' + ) + self.order_b = SalesOrder.objects.create( + customer=self.customer, reference='SO-CONC-B' + ) + + self.line_a = SalesOrderLineItem.objects.create( + quantity=5, order=self.order_a, part=self.part + ) + self.line_b = SalesOrderLineItem.objects.create( + quantity=5, order=self.order_b, part=self.part + ) + + # Only enough stock for *one* of the two full-quantity allocations below + self.stock_item = StockItem.objects.create(part=self.part, quantity=5) + + def test_concurrent_allocation_does_not_over_allocate(self): + """Two concurrent full-quantity allocation requests must not both succeed.""" + start_barrier = threading.Barrier(2, timeout=5) + errors = [] + results = [] + + # Wrap StockItem.lock_quantity() so both threads reach the (real, + # database-level) row lock at the same time - one wins the lock and + # proceeds, the other blocks until the winner's transaction completes. + original_lock_quantity = StockItem.lock_quantity + + def synced_lock_quantity(self_item): + start_barrier.wait(timeout=5) + return original_lock_quantity(self_item) + + def allocate(line_item): + try: + serializer = SalesOrderShipmentAllocationSerializer( + data={ + 'items': [ + { + 'line_item': line_item.pk, + 'stock_item': self.stock_item.pk, + 'quantity': 5, + } + ] + }, + context={'order': line_item.order}, + ) + serializer.is_valid(raise_exception=True) + serializer.save() + results.append('ok') + except (ValidationError, DRFValidationError): + results.append('rejected') + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + thread_a = threading.Thread(target=allocate, args=(self.line_a,)) + thread_b = threading.Thread(target=allocate, args=(self.line_b,)) + + with mock.patch.object(StockItem, 'lock_quantity', synced_lock_quantity): + thread_a.start() + thread_b.start() + + thread_a.join(timeout=5) + thread_b.join(timeout=5) + + self.assertFalse(thread_a.is_alive()) + self.assertFalse(thread_b.is_alive()) + self.assertEqual(errors, []) + + # Exactly one request must have been rejected as over-allocating + self.assertEqual(sorted(results), ['ok', 'rejected']) + + total_allocated = ( + SalesOrderAllocation.objects.filter(item=self.stock_item).aggregate( + q=Sum('quantity') + )['q'] + or 0 + ) + + self.assertEqual(total_allocated, 5) + self.assertLessEqual(total_allocated, self.stock_item.quantity) diff --git a/src/backend/InvenTree/order/tests.py b/src/backend/InvenTree/order/tests.py index e4e04c82ee..74f35a5c85 100644 --- a/src/backend/InvenTree/order/tests.py +++ b/src/backend/InvenTree/order/tests.py @@ -523,7 +523,7 @@ class OrderTest(ExchangeRateMixin, PluginRegistryMixin, TestCase): msg = messages.first() - self.assertEqual(msg.target_object_id, 1) + self.assertEqual(msg.target_object_id, str(1)) self.assertEqual(msg.name, 'Overdue Purchase Order') def test_new_po_notification(self): @@ -728,3 +728,13 @@ class OrderUpdatedAtTest(TestCase): before = self._refresh(instance).updated_at line.delete() self.assertGreaterEqual(self._refresh(instance).updated_at, before) + + def test_po_lineitem_admin_search(self): + """Test search fields for PurchaseOrderLineItemAdmin.""" + from order.admin import PurchaseOrderLineItemAdmin + + admin_class = PurchaseOrderLineItemAdmin + self.assertIn('part__part__name', admin_class.search_fields) + self.assertIn('part__SKU', admin_class.search_fields) + self.assertIn('order__reference', admin_class.search_fields) + self.assertIn('order__supplier__name', admin_class.search_fields) diff --git a/src/backend/InvenTree/part/api.py b/src/backend/InvenTree/part/api.py index 2b4e79421f..a773440c26 100644 --- a/src/backend/InvenTree/part/api.py +++ b/src/backend/InvenTree/part/api.py @@ -12,6 +12,7 @@ from drf_spectacular.utils import extend_schema, extend_schema_field from rest_framework import serializers from rest_framework.response import Response +import common.filters import common.serializers import part.tasks as part_tasks from data_exporter.mixins import DataExportViewMixin @@ -20,6 +21,8 @@ from InvenTree.api import ( BulkUpdateMixin, ListCreateDestroyAPIView, ParameterListMixin, + TreeMixin, + meta_path, ) from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.filters import ( @@ -282,25 +285,38 @@ class CategoryDetail(CategoryMixin, OutputOptionsMixin, CustomRetrieveUpdateDest ) -class CategoryTree(ListAPI): +class CategoryTreeFilter(FilterSet): + """Custom filterset class for the CategoryTree endpoint.""" + + class Meta: + """Metaclass options for this filterset.""" + + model = PartCategory + fields = ['parent', 'tree_id', 'level'] + + max_level = rest_filters.NumberFilter( + label=_('Max Level'), + method='filter_max_level', + help_text=_('Limit the depth of the category tree'), + ) + + def filter_max_level(self, queryset, name, value): + """Filter by the maximum depth of the category tree.""" + return queryset.filter(level__lte=value) + + +class CategoryTree(TreeMixin, ListAPI): """API endpoint for accessing a list of PartCategory objects ready for rendering a tree.""" + model_class = PartCategory queryset = PartCategory.objects.all() - serializer_class = part_serializers.CategoryTree - - filter_backends = ORDER_FILTER - - ordering_fields = ['level', 'name', 'subcategories'] - - ordering_field_aliases = {'level': ['level', 'name'], 'name': ['name', 'level']} - - # Order by tree level (top levels first) and then name - ordering = ['level', 'name'] + serializer_class = part_serializers.CategoryTreeSerializer + filterset_class = CategoryTreeFilter def get_queryset(self, *args, **kwargs): """Return an annotated queryset for the CategoryTree endpoint.""" queryset = super().get_queryset(*args, **kwargs) - queryset = part_serializers.CategoryTree.annotate_queryset(queryset) + queryset = part_serializers.CategoryTreeSerializer.annotate_queryset(queryset) return queryset @@ -768,6 +784,15 @@ class PartFilter(FilterSet): return queryset.filter(Q(unallocated_stock__gt=0)) return queryset.filter(Q(unallocated_stock__lte=0)) + # on_order filter + on_order = rest_filters.BooleanFilter(label='On order', method='filter_on_order') + + def filter_on_order(self, queryset, name, value): + """Filter by whether the Part has any stock on order.""" + if str2bool(value): + return queryset.filter(Q(ordering__gt=0)) + return queryset.filter(Q(ordering__lte=0)) + convert_from = rest_filters.ModelChoiceFilter( label='Can convert from', queryset=Part.objects.all(), @@ -909,9 +934,9 @@ class PartFilter(FilterSet): virtual = rest_filters.BooleanFilter() - tags_name = rest_filters.CharFilter(field_name='tags__name', lookup_expr='iexact') + consumable = rest_filters.BooleanFilter() - tags_slug = rest_filters.CharFilter(field_name='tags__slug', lookup_expr='iexact') + tags = common.filters.TagsFilter() # Created date filters created_before = InvenTreeDateFilter( @@ -1080,6 +1105,7 @@ class PartList( 'name', 'creation_date', 'IPN', + 'ordering', 'in_stock', 'total_in_stock', 'unallocated_stock', @@ -1564,8 +1590,14 @@ part_api_urls = [ include([ path( '/', - CategoryParameterDetail.as_view(), - name='api-part-category-parameter-detail', + include([ + meta_path(PartCategoryParameterTemplate), + path( + '', + CategoryParameterDetail.as_view(), + name='api-part-category-parameter-detail', + ), + ]), ), path( '', @@ -1576,7 +1608,12 @@ part_api_urls = [ ), # Category detail endpoints path( - '/', CategoryDetail.as_view(), name='api-part-category-detail' + '/', + include([ + meta_path(PartCategory), + # PartCategory detail endpoint + path('', CategoryDetail.as_view(), name='api-part-category-detail'), + ]), ), path('', CategoryList.as_view(), name='api-part-category-list'), ]), @@ -1587,8 +1624,14 @@ part_api_urls = [ include([ path( '/', - PartTestTemplateDetail.as_view(), - name='api-part-test-template-detail', + include([ + meta_path(PartTestTemplate), + path( + '', + PartTestTemplateDetail.as_view(), + name='api-part-test-template-detail', + ), + ]), ), path( '', PartTestTemplateList.as_view(), name='api-part-test-template-list' @@ -1626,7 +1669,13 @@ part_api_urls = [ 'related/', include([ path( - '/', PartRelatedDetail.as_view(), name='api-part-related-detail' + '/', + include([ + meta_path(PartRelated), + path( + '', PartRelatedDetail.as_view(), name='api-part-related-detail' + ), + ]), ), path('', PartRelatedList.as_view(), name='api-part-related-list'), ]), @@ -1677,6 +1726,8 @@ part_api_urls = [ path( 'bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate' ), + # Part metadata + meta_path(Part), # Part pricing path('pricing/', PartPricingDetail.as_view(), name='api-part-pricing'), # Part detail endpoint @@ -1693,8 +1744,14 @@ bom_api_urls = [ # Detail view path( '/', - BomItemSubstituteDetail.as_view(), - name='api-bom-substitute-detail', + include([ + meta_path(BomItemSubstitute), + path( + '', + BomItemSubstituteDetail.as_view(), + name='api-bom-substitute-detail', + ), + ]), ), # Catch all path('', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'), @@ -1705,6 +1762,7 @@ bom_api_urls = [ '/', include([ path('validate/', BomItemValidate.as_view(), name='api-bom-item-validate'), + meta_path(BomItem), path('', BomDetail.as_view(), name='api-bom-item-detail'), ]), ), diff --git a/src/backend/InvenTree/part/migrations/0067_partinternalpricebreak.py b/src/backend/InvenTree/part/migrations/0067_partinternalpricebreak.py index c290bd6ec9..b4e6be8f8c 100644 --- a/src/backend/InvenTree/part/migrations/0067_partinternalpricebreak.py +++ b/src/backend/InvenTree/part/migrations/0067_partinternalpricebreak.py @@ -26,6 +26,7 @@ class Migration(migrations.Migration): ], options={ 'unique_together': {('part', 'quantity')}, + 'verbose_name': 'Part Internal Price Break', }, ), ] diff --git a/src/backend/InvenTree/part/migrations/0151_part_consumable.py b/src/backend/InvenTree/part/migrations/0151_part_consumable.py new file mode 100644 index 0000000000..673313e25e --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0151_part_consumable.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.15 on 2026-07-02 07:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("part", "0150_part_maximum_stock"), + ] + + operations = [ + migrations.AddField( + model_name="part", + name="consumable", + field=models.BooleanField( + default=False, + help_text="Is this part consumable, such as glue or a fastener?", + verbose_name="Consumable", + ), + ), + ] diff --git a/src/backend/InvenTree/part/migrations/0152_alter_partpricing_currency.py b/src/backend/InvenTree/part/migrations/0152_alter_partpricing_currency.py new file mode 100644 index 0000000000..de0f646ae9 --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0152_alter_partpricing_currency.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.15 on 2026-07-08 00:00 + +import InvenTree.validators +import common.currency +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("part", "0151_part_consumable"), + ] + + operations = [ + migrations.AlterField( + model_name="partpricing", + name="currency", + field=models.CharField( + default=common.currency.currency_code_default, + help_text="Currency used to cache pricing calculations", + max_length=10, + validators=[InvenTree.validators.validate_currency_code], + verbose_name="Currency", + ), + ), + ] diff --git a/src/backend/InvenTree/part/migrations/0153_bomitem_piece_count_bomitem_piece_size.py b/src/backend/InvenTree/part/migrations/0153_bomitem_piece_count_bomitem_piece_size.py new file mode 100644 index 0000000000..646b8b73bb --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0153_bomitem_piece_count_bomitem_piece_size.py @@ -0,0 +1,30 @@ +"""Add piece_count field to BomItem model. + +This field supports cut-to-length parts (cables, tubing, profiles) where +a BOM line requires multiple pieces of a specific size. The existing +quantity field represents the per-piece size/length, and piece_count +indicates how many pieces are needed. Total material = quantity x piece_count. +""" + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('part', '0152_alter_partpricing_currency'), + ] + + operations = [ + migrations.AddField( + model_name='bomitem', + name='piece_count', + field=models.PositiveIntegerField( + default=1, + help_text='Number of pieces required (for cut-to-length items). Total material = quantity x piece_count.', + validators=[django.core.validators.MinValueValidator(1)], + verbose_name='Piece Count', + ), + ), + ] diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index 48b0bb0399..ec28a8827e 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -9,7 +9,7 @@ import os import re from datetime import timedelta from decimal import ROUND_HALF_UP, Decimal, InvalidOperation -from typing import TypedDict, cast +from typing import Optional, TypedDict, cast from django.conf import settings from django.contrib.auth.models import User @@ -32,10 +32,10 @@ from djmoney.contrib.exchange.models import convert_money from djmoney.money import Money from mptt.managers import TreeManager from mptt.models import TreeForeignKey -from taggit.managers import TaggableManager import common.currency import common.models +import company.models import InvenTree.conversion import InvenTree.fields import InvenTree.helpers @@ -52,9 +52,10 @@ from common.currency import currency_code_default from common.icons import validate_icon from common.settings import get_global_setting from InvenTree import helpers, validators +from InvenTree.cache import get_session_cache, set_session_cache from InvenTree.exceptions import log_error from InvenTree.fields import InvenTreeURLField -from InvenTree.helpers import decimal2money, decimal2string, normalize +from InvenTree.helpers import decimal2string, normalize from order import models as OrderModels from order.status_codes import ( PurchaseOrderStatus, @@ -69,6 +70,7 @@ logger = structlog.get_logger('inventree') class PartCategory( InvenTree.models.PluginValidationMixin, + InvenTree.models.InvenTreeParameterMixin, InvenTree.models.MetadataMixin, InvenTree.models.PathStringMixin, InvenTree.models.InvenTreeTree, @@ -465,6 +467,7 @@ class Part( InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeBarcodeMixin, + InvenTree.models.InvenTreeTagsMixin, InvenTree.models.InvenTreeNotesMixin, report.mixins.InvenTreeReportMixin, InvenTree.models.InvenTreeImageMixin, @@ -502,6 +505,7 @@ class Part( active: Is this part active? Parts are deactivated instead of being deleted locked: This part is locked and cannot be edited virtual: Is this part "virtual"? e.g. a software product or similar + consumable: Is this part consumable, such as glue or a fastener? notes: Additional notes field for this part creation_date: Date that this part was added to the database creation_user: User who added this part to the database @@ -520,8 +524,6 @@ class Part( objects = TreeManager() - tags = TaggableManager(blank=True) - class Meta: """Metaclass defines extra model properties.""" @@ -724,19 +726,21 @@ class Part( """ from plugin import PluginMixinEnum, registry - for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): - # Run the name through each custom validator - # If the plugin returns 'True' we will skip any subsequent validation + # Skip plugin validation checks during read-only management commands + if not InvenTree.ready.isReadOnlyCommand(): + for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): + # Run the name through each custom validator + # If the plugin returns 'True' we will skip any subsequent validation - try: - result = plugin.validate_part_name(self.name, self) - if result: - return - except ValidationError as exc: - if raise_error: - raise ValidationError({'name': exc.message}) - except Exception: - log_error('validate_part_name', plugin=plugin.slug) + try: + result = plugin.validate_part_name(self.name, self) + if result: + return + except ValidationError as exc: + if raise_error: + raise ValidationError({'name': exc.message}) + except Exception: + log_error('validate_part_name', plugin=plugin.slug) def validate_ipn(self, raise_error=True): """Ensure that the IPN (internal part number) is valid for this Part". @@ -746,18 +750,20 @@ class Part( """ from plugin import PluginMixinEnum, registry - for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): - try: - result = plugin.validate_part_ipn(self.IPN, self) + # Skip plugin validation checks during read-only management commands + if not InvenTree.ready.isReadOnlyCommand(): + for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): + try: + result = plugin.validate_part_ipn(self.IPN, self) - if result: - # A "true" result force skips any subsequent checks - break - except ValidationError as exc: - if raise_error: - raise ValidationError({'IPN': exc.message}) - except Exception: - log_error('validate_part_ipn', plugin=plugin.slug) + if result: + # A "true" result force skips any subsequent checks + break + except ValidationError as exc: + if raise_error: + raise ValidationError({'IPN': exc.message}) + except Exception: + log_error('validate_part_ipn', plugin=plugin.slug) # If we get to here, none of the plugins have raised an error pattern = get_global_setting('PART_IPN_REGEX', '', create=False).strip() @@ -835,40 +841,41 @@ class Part( Raises: ValidationError if serial number is invalid and raise_error = True """ - serial = str(serial).strip() - - # First, throw the serial number against each of the loaded validation plugins from plugin import PluginMixinEnum, registry - for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): - # Run the serial number through each custom validator - # If the plugin returns 'True' we will skip any subsequent validation + serial = str(serial).strip() - try: - result = False + if not InvenTree.ready.isReadOnlyCommand(): + # First, throw the serial number against each of the loaded validation plugins + for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): + # Run the serial number through each custom validator + # If the plugin returns 'True' we will skip any subsequent validation - if hasattr(plugin, 'validate_serial_number'): - signature = inspect.signature(plugin.validate_serial_number) + try: + result = False - if 'stock_item' in signature.parameters: - # 2024-08-21: New method signature accepts a 'stock_item' parameter - result = plugin.validate_serial_number( - serial, self, stock_item=stock_item - ) + if hasattr(plugin, 'validate_serial_number'): + signature = inspect.signature(plugin.validate_serial_number) + + if 'stock_item' in signature.parameters: + # 2024-08-21: New method signature accepts a 'stock_item' parameter + result = plugin.validate_serial_number( + serial, self, stock_item=stock_item + ) + else: + # Old method signature - does not accept a 'stock_item' parameter + result = plugin.validate_serial_number(serial, self) + + if result is True: + return True + except ValidationError as exc: + if raise_error: + # Re-throw the error + raise exc else: - # Old method signature - does not accept a 'stock_item' parameter - result = plugin.validate_serial_number(serial, self) - - if result is True: - return True - except ValidationError as exc: - if raise_error: - # Re-throw the error - raise exc - else: - return False - except Exception: - log_error('validate_serial_number', plugin=plugin.slug) + return False + except Exception: + log_error('validate_serial_number', plugin=plugin.slug) """ If we are here, none of the loaded plugins (if any) threw an error or exited early @@ -960,7 +967,7 @@ class Part( """ from plugin import PluginMixinEnum, registry - if allow_plugins: + if allow_plugins and not InvenTree.ready.isReadOnlyCommand(): # Check with plugin system # If any plugin returns a non-null result, that takes priority for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): @@ -998,6 +1005,7 @@ class Part( return InvenTree.helpers.increment_serial_number(sn, self) @property + @report.mixins.report_attribute() def full_name(self) -> str: """Format a 'full name' for this Part based on the format PART_NAME_FORMAT defined in InvenTree settings.""" return part_helpers.render_part_full_name(self) @@ -1045,11 +1053,20 @@ class Part( raise ValidationError(_('Duplicate part revision already exists.')) # Ensure unique across (Name, revision, IPN) (as specified) - if (self.revision or self.IPN) and ( - Part.objects - .exclude(pk=self.pk) - .filter(name=self.name, revision=self.revision, IPN=self.IPN) - .exists() + # Note: the 'unique_part' database constraint only rejects a row when + # *all three* fields are non-null (Postgres treats NULL as distinct from + # NULL), so mirror that here rather than skipping whenever either field + # is merely blank - an empty string ('') still collides with another + # empty string at the database level, unlike None/NULL. + if ( + self.IPN is not None + and self.revision is not None + and ( + Part.objects + .exclude(pk=self.pk) + .filter(name=self.name, revision=self.revision, IPN=self.IPN) + .exists() + ) ): raise ValidationError( _('Part with this Name, IPN and Revision already exists.') @@ -1209,7 +1226,8 @@ class Part( return None @property - def default_supplier(self): + @report.mixins.report_attribute() + def default_supplier(self) -> Optional[company.models.SupplierPart]: """Return the default (primary) SupplierPart for this Part. This function is included for backwards compatibility, @@ -1304,6 +1322,12 @@ class Part( help_text=_('Is this a virtual part, such as a software product or license?'), ) + consumable = models.BooleanField( + default=False, + verbose_name=_('Consumable'), + help_text=_('Is this part consumable, such as glue or a fastener?'), + ) + bom_validated = models.BooleanField( default=False, verbose_name=_('BOM Validated'), @@ -1358,14 +1382,15 @@ class Part( ) @property - def category_path(self): + def category_path(self) -> str: """Return the category path of this Part instance.""" if self.category: return self.category.pathstring return '' @property - def available_stock(self): + @report.mixins.report_attribute() + def available_stock(self) -> Decimal: """Return the total available stock. - This subtracts stock which is already allocated to builds @@ -1603,7 +1628,8 @@ class Part( PartStar.objects.filter(part=self, user=user).delete() @property - def can_build(self): + @report.mixins.report_attribute() + def can_build(self) -> Decimal: """Return the number of units that can be build with available stock.""" import part.filters @@ -1615,7 +1641,7 @@ class Part( queryset = self.get_bom_items(include_virtual=False) # Ignore 'consumable' BOM items for this calculation - queryset = queryset.filter(consumable=False) + queryset = queryset.filter(BomItem.consumable_filter(consumable=False)) # Annotate the queryset with the 'can_build' quantity queryset = part.filters.annotate_bom_item_can_build(queryset) @@ -1635,7 +1661,7 @@ class Part( return int(max(can_build_quantity, 0)) @property - def active_builds(self): + def active_builds(self) -> int: """Return a list of outstanding builds. Builds marked as 'complete' or 'cancelled' are ignored @@ -1643,12 +1669,10 @@ class Part( return self.builds.filter(status__in=BuildStatusGroups.ACTIVE_CODES) @property - def quantity_being_built(self, include_variants: bool = True): + @report.mixins.report_attribute() + def quantity_being_built(self) -> Decimal: """Return the current number of parts currently being built. - Arguments: - include_variants: If True, include variants of this part in the calculation - Note: This is the total quantity of Build orders, *not* the number of build outputs. In this fashion, it is the "projected" quantity of builds """ @@ -1656,12 +1680,8 @@ class Part( status__in=BuildStatusGroups.ACTIVE_CODES ) - if include_variants: - # If we are including variants, get all parts in the variant tree - builds = builds.filter(part__in=self.get_descendants(include_self=True)) - else: - # Only look at this part - builds = builds.filter(part=self) + # We are including variants, get all parts in the variant tree + builds = builds.filter(part__in=self.get_descendants(include_self=True)) quantity = 0 @@ -1672,7 +1692,7 @@ class Part( return quantity @property - def quantity_in_production(self, include_variants: bool = True): + def quantity_in_production(self, include_variants: bool = True) -> Decimal: """Quantity of this part currently actively in production. Arguments: @@ -1866,7 +1886,8 @@ class Part( return query['t'] @property - def total_stock(self): + @report.mixins.report_attribute() + def total_stock(self) -> Decimal: """Return the total stock quantity for this part. - Part may be stored in multiple locations @@ -2019,7 +2040,7 @@ class Part( return list(parts) @property - def has_bom(self): + def has_bom(self) -> bool: """Return True if this Part instance has any BOM items.""" return self.get_bom_items().exists() @@ -2031,7 +2052,7 @@ class Part( return queryset @property - def has_trackable_parts(self): + def has_trackable_parts(self) -> bool: """Return True if any parts linked in the Bill of Materials are trackable. This is important when building the part. @@ -2039,16 +2060,16 @@ class Part( return self.get_trackable_parts().exists() @property - def bom_count(self): + def bom_count(self) -> int: """Return the number of items contained in the BOM for this part.""" return self.get_bom_items().count() @property - def used_in_count(self): + def used_in_count(self) -> int: """Return the number of part BOMs that this part appears in.""" return len(self.get_used_in()) - def get_bom_hash(self): + def get_bom_hash(self) -> str: """Return a checksum hash for the BOM for this part. Used to determine if the BOM has changed (and needs to be signed off!) @@ -2057,7 +2078,14 @@ class Part( result_hash = hashlib.md5(str(self.id).encode()) # List *all* BOM items (including inherited ones!) - bom_items = self.get_bom_items().all().prefetch_related('part', 'sub_part') + # Note: We must order the BOM items in a consistent way, otherwise the hash will change if the order of the items changes + bom_items = ( + self + .get_bom_items() + .all() + .prefetch_related('part', 'sub_part') + .order_by('pk') + ) for item in bom_items: result_hash.update(str(item.get_item_hash()).encode()) @@ -2130,7 +2158,7 @@ class Part( if parts is None: parts = set() - bom_items = self.get_bom_items() + bom_items = self.get_bom_items().prefetch_related('sub_part') for bom_item in bom_items: sub_part = bom_item.sub_part @@ -2203,150 +2231,6 @@ class Part( # which can cause issues down the track pass - def get_price_info(self, quantity=1, buy=True, bom=True, internal=False): - """Return a simplified pricing string for this part. - - Args: - quantity: Number of units to calculate price for - buy: Include supplier pricing (default = True) - bom: Include BOM pricing (default = True) - internal: Include internal pricing (default = False) - """ - price_range = self.get_price_range(quantity, buy, bom, internal) - - if price_range is None: - return None - - min_price, max_price = price_range - - if min_price == max_price: - return min_price - - min_price = normalize(min_price) - max_price = normalize(max_price) - - return f'{min_price} - {max_price}' - - def get_supplier_price_range(self, quantity=1): - """Return the supplier price range of this part. - - Actions: - - Checks if there is any supplier pricing information associated with this Part - - Iterate through available supplier pricing and select (min, max) - - Returns tuple of (min, max) - - Arguments: - quantity: Quantity at which to calculate price (default=1) - - Returns: (min, max) tuple or (None, None) if no supplier pricing available - """ - min_price = None - max_price = None - - for supplier in self.supplier_parts.all(): - price = supplier.get_price(quantity) - - if price is None: - continue - - if min_price is None or price < min_price: - min_price = price - - if max_price is None or price > max_price: - max_price = price - - if min_price is None or max_price is None: - return None - - min_price = normalize(min_price) - max_price = normalize(max_price) - - return (min_price, max_price) - - def get_bom_price_range(self, quantity=1, internal=False, purchase=False): - """Return the price range of the BOM for this part. - - Adds the minimum price for all components in the BOM. - Note: If the BOM contains items without pricing information, - these items cannot be included in the BOM! - """ - min_price = None - max_price = None - - for item in self.get_bom_items().select_related('sub_part'): - if item.sub_part.pk == self.pk: - logger.warning('WARNING: BomItem ID %s contains itself in BOM', item.pk) - continue - - q = Decimal(quantity) - i = Decimal(item.quantity) - - prices = item.sub_part.get_price_range( - q * i, internal=internal, purchase=purchase - ) - - if prices is None: - continue - - low, high = prices - - if min_price is None: - min_price = 0 - - if max_price is None: - max_price = 0 - - min_price += low - max_price += high - - if min_price is None or max_price is None: - return None - - min_price = normalize(min_price) - max_price = normalize(max_price) - - return (min_price, max_price) - - def get_price_range( - self, quantity=1, buy=True, bom=True, internal=False, purchase=False - ): - """Return the price range for this part. - - This price can be either: - - Supplier price (if purchased from suppliers) - - BOM price (if built from other parts) - - Internal price (if set for the part) - - Purchase price (if set for the part) - - Returns: - Minimum of the supplier, BOM, internal or purchase price. If no pricing available, returns None - """ - # only get internal price if set and should be used - if internal and self.has_internal_price_breaks: - internal_price = self.get_internal_price(quantity) - return internal_price, internal_price - - # only get purchase price if set and should be used - if purchase: - purchase_price = self.get_purchase_price(quantity) - if purchase_price: - return purchase_price - - buy_price_range = self.get_supplier_price_range(quantity) if buy else None - bom_price_range = ( - self.get_bom_price_range(quantity, internal=internal) if bom else None - ) - - if buy_price_range is None: - return bom_price_range - - elif bom_price_range is None: - return buy_price_range - return ( - min(buy_price_range[0], bom_price_range[0]), - max(buy_price_range[1], bom_price_range[1]), - ) - base_cost = models.DecimalField( max_digits=19, decimal_places=6, @@ -2363,73 +2247,6 @@ class Part( help_text=_('Sell multiple'), ) - get_price = common.currency.get_price - - @property - def has_price_breaks(self): - """Return True if this part has sale price breaks.""" - return self.price_breaks.exists() - - @property - def price_breaks(self): - """Return the associated price breaks in the correct order.""" - return self.salepricebreaks.order_by('quantity').all() - - @property - def unit_pricing(self): - """Returns the price of this Part at quantity=1.""" - return self.get_price(1) - - def add_price_break(self, quantity, price): - """Create a new price break for this part. - - Args: - quantity: Numerical quantity - price: Must be a Money object - """ - # Check if a price break at that quantity already exists... - if self.price_breaks.filter(quantity=quantity, part=self.pk).exists(): - return - - PartSellPriceBreak.objects.create(part=self, quantity=quantity, price=price) - - def get_internal_price(self, quantity, moq=True, multiples=True, currency=None): - """Return the internal price of this Part at the specified quantity.""" - return common.currency.get_price( - self, quantity, moq, multiples, currency, break_name='internal_price_breaks' - ) - - @property - def has_internal_price_breaks(self): - """Return True if this Part has internal pricing information.""" - return self.internal_price_breaks.exists() - - @property - def internal_price_breaks(self): - """Return the associated price breaks in the correct order.""" - return self.internalpricebreaks.order_by('quantity').all() - - def get_purchase_price(self, quantity): - """Calculate the purchase price for this part at the specified quantity. - - - Looks at available supplier pricing data - - Calculates the price base on the closest price point - """ - currency = currency_code_default() - try: - prices = [ - convert_money(item.purchase_price, currency).amount - for item in self.stock_items.all() - if item.purchase_price - ] - except MissingRate: - prices = None - - if prices: - return min(prices) * quantity, max(prices) * quantity - - return None - @transaction.atomic def copy_bom_from(self, other, clear: bool = True, **kwargs): """Copy the BOM from another part. @@ -2548,6 +2365,14 @@ class Part( if category_template.template.pk in template_ids: continue + # Skip templates which enforce a uniqueness requirement - applying the same + # default value to every part in the category would create conflicting values + if ( + category_template.template.unique + != common.models.ParameterTemplate.UniqueOptions.NONE + ): + continue + template_ids.add(category_template.template.pk) parameters.append( @@ -2636,7 +2461,8 @@ class Part( return orders @property - def on_order(self): + @report.mixins.report_attribute() + def on_order(self) -> Decimal: """Return the total number of items on order for this part. Note that some supplier parts may have a different pack_quantity attribute, @@ -2829,7 +2655,26 @@ class PartPricing(common.models.MetaMixin): Arguments: counter: Recursion counter (used to prevent infinite recursion) refresh: If specified, the PartPricing object will be refreshed from the database + + Note: + Within a single request, repeated calls for the same part are cheap: a request-scoped + cache (see InvenTree.cache) short-circuits everything below after the first call, + avoiding redundant refresh_from_db() / existence-check queries for a part whose pricing + has already been resolved (scheduled or not) earlier in the same request. This does not + change behavior outside of a request (e.g. background tasks), where the cache is a + no-op and every call runs in full. """ + cache_key = f'part-pricing-scheduled-{self.part_id}' + if get_session_cache(cache_key): + return + + try: + self._schedule_for_update(counter=counter, refresh=refresh) + finally: + set_session_cache(cache_key, True) + + def _schedule_for_update(self, counter: int = 0, refresh: bool = True): + """Implementation of schedule_for_update(), without the request-scoped cache guard.""" import InvenTree.ready # If importing data, skip pricing update @@ -2937,7 +2782,9 @@ class PartPricing(common.models.MetaMixin): try: self.refresh_from_db() except PartPricing.DoesNotExist: - pass + # The underlying Part (and this pricing entry) has been deleted + # since this update was scheduled - nothing to do + return self.update_bom_cost(save=False) self.update_purchase_cost(save=False) @@ -2990,15 +2837,12 @@ class PartPricing(common.models.MetaMixin): try: self.update_overall_cost() - except Exception: - # If something has happened to the Part model, might throw an error - pass - - try: super().save(*args, **kwargs) except Exception: - # This error may be thrown if there is already duplicate pricing data - pass + log_error('PartPricing.save') + logger.error( + "Could not save PartPricing for part '%s' to the database", self.part + ) def update_bom_cost(self, save=True): """Recalculate BOM cost for the referenced Part instance. @@ -3370,7 +3214,7 @@ class PartPricing(common.models.MetaMixin): max_length=10, verbose_name=_('Currency'), help_text=_('Currency used to cache pricing calculations'), - choices=common.currency.currency_code_mappings(), + validators=[validators.validate_currency_code], ) scheduled_for_update = models.BooleanField(default=False) @@ -3591,6 +3435,7 @@ class PartInternalPriceBreak(common.models.PriceBreak): """Metaclass providing extra model definition.""" unique_together = ('part', 'quantity') + verbose_name = _('Part Internal Price Break') @staticmethod def get_api_url(): @@ -3845,6 +3690,8 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): setup_quantity: Extra required quantity for a build, to account for setup losses attrition: Estimated losses for a Build, expressed as a percentage (e.g. '2%') rounding_multiple: Rounding quantity when calculating the required quantity for a build + piece_count: Number of pieces required (for cut-to-length items like cables, tubing). + Total material = quantity x piece_count. note: Note field for this BOM item checksum: Validation checksum for the particular BOM line item validated: Boolean field indicating if this BOM item is valid (checksum matches) @@ -3880,6 +3727,7 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): allow_variants: bool = True, allow_substitutes: bool = True, allow_inactive: bool = True, + variant_parts=None, ): """Return a list of valid parts which can be allocated against this BomItem. @@ -3887,6 +3735,8 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): allow_variants: If True, include variants of the sub_part allow_substitutes: If True, include any directly specified substitute parts allow_inactive: If True, include inactive parts in the returned list + variant_parts: Optional pre-fetched iterable of sub_part's descendants, + to avoid re-querying the part tree when the caller already has it Includes: - The referenced sub_part @@ -3900,7 +3750,9 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): # Variant parts (if allowed) if allow_variants and self.allow_variants: - for variant in self.sub_part.get_descendants(include_self=False): + if variant_parts is None: + variant_parts = self.sub_part.get_descendants(include_self=False) + for variant in variant_parts: parts.add(variant) # Substitute parts @@ -4165,6 +4017,16 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): ), ) + piece_count = models.PositiveIntegerField( + default=1, + validators=[MinValueValidator(1)], + verbose_name=_('Piece Count'), + help_text=_( + 'Number of pieces required (for cut-to-length items). ' + 'Total material = quantity x piece_count.' + ), + ) + reference = models.CharField( max_length=5000, blank=True, @@ -4219,6 +4081,7 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): 'setup_quantity', 'attrition', 'rounding_multiple', + 'piece_count', 'reference', 'optional', 'inherited', @@ -4284,6 +4147,35 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): return self.get_item_hash() == self.checksum + @property + def is_consumable(self) -> bool: + """Return True if this BOM line should be treated as consumable. + + This is the case if either: + - The BOM line itself is marked as consumable + - The underlying part is marked as consumable + """ + return self.consumable or self.sub_part.consumable + + @staticmethod + def consumable_filter(consumable: bool = True, prefix: str = '') -> Q: + """Return a Q filter which selects BomItem objects based on "effective" consumable status. + + A BomItem is considered "effectively consumable" if either the BOM line itself, + or the underlying part, is marked as consumable. + + Arguments: + consumable: If True, return a filter which matches consumable BOM items. + If False, return a filter which matches non-consumable BOM items. + prefix: Optional field lookup prefix, for use against querysets of a + related model (e.g. 'bom_item__' when filtering a BuildLine queryset). + """ + f = Q(**{f'{prefix}consumable': True}) | Q(**{ + f'{prefix}sub_part__consumable': True + }) + + return f if consumable else ~f + def clean(self): """Check validity of the BomItem model. @@ -4352,9 +4244,14 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): Returns: Production quantity required for this component + + Note: + For cut-to-length parts, quantity represents the per-piece size/length + and piece_count indicates how many pieces are needed. + Total material = quantity x piece_count x build_quantity. """ - # Base quantity requirement - required = self.quantity * build_quantity + # Base quantity requirement (quantity is per-piece, piece_count is number of pieces) + required = self.quantity * self.piece_count * build_quantity # Account for attrition if self.attrition > 0: @@ -4386,29 +4283,6 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel): return required - @property - def price_range(self, internal=False): - """Return the price-range for this BOM item.""" - # get internal price setting - use_internal = get_global_setting('PART_BOM_USE_INTERNAL_PRICE', False) - p_range = self.sub_part.get_price_range( - self.quantity, internal=use_internal and internal - ) - - if p_range is None: - return p_range - - p_min, p_max = p_range - - if p_min == p_max: - return decimal2money(p_min) - - # Convert to better string representation - p_min = decimal2money(p_min) - p_max = decimal2money(p_max) - - return f'{p_min} to {p_max}' - @receiver(post_save, sender=BomItem, dispatch_uid='update_bom_build_lines') def update_bom_build_lines(sender, instance, created, **kwargs): @@ -4457,8 +4331,13 @@ def update_pricing_after_delete(sender, instance, **kwargs): InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING) and not InvenTree.ready.isImportingData() ): - if instance.part: - instance.part.schedule_pricing_update(create=False) + try: + part = instance.part + part.schedule_pricing_update(create=False) + except Part.DoesNotExist: + # The part instance may have already been deleted, + # in which case we cannot update pricing + pass class BomItemSubstitute(InvenTree.models.InvenTreeMetadataModel): diff --git a/src/backend/InvenTree/part/serializers.py b/src/backend/InvenTree/part/serializers.py index ccbce76492..2a14c73368 100644 --- a/src/backend/InvenTree/part/serializers.py +++ b/src/backend/InvenTree/part/serializers.py @@ -103,6 +103,8 @@ class CategorySerializer( 'structural', 'icon', 'parent_default_location', + # Optional fields + 'parameters', ] read_only_fields = ['level', 'pathstring'] @@ -176,15 +178,28 @@ class CategorySerializer( parent_default_location = serializers.IntegerField(read_only=True, allow_null=True) + parameters = common.filters.enable_parameters_filter() -class CategoryTree(InvenTree.serializers.InvenTreeModelSerializer): + +class CategoryTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer): """Serializer for PartCategory tree.""" class Meta: """Metaclass defining serializer fields.""" model = PartCategory - fields = ['pk', 'name', 'parent', 'icon', 'structural', 'subcategories'] + fields = [ + 'pk', + 'name', + 'description', + 'pathstring', + 'parent', + 'tree_id', + 'level', + 'icon', + 'structural', + 'subcategories', + ] subcategories = serializers.IntegerField(label=_('Subcategories'), read_only=True) @@ -261,7 +276,10 @@ class PartSalePriceSerializer( ) -class PartInternalPriceSerializer(InvenTree.serializers.InvenTreeModelSerializer): +@register_importer() +class PartInternalPriceSerializer( + DataImportExportSerializerMixin, InvenTree.serializers.InvenTreeModelSerializer +): """Serializer for internal prices for Part model.""" class Meta: @@ -342,6 +360,7 @@ class PartBriefSerializer( 'testable', 'trackable', 'virtual', + 'consumable', 'units', 'pricing_min', 'pricing_max', @@ -392,67 +411,6 @@ class PartBriefSerializer( ) -class DuplicatePartSerializer(serializers.Serializer): - """Serializer for specifying options when duplicating a Part. - - The fields in this serializer control how the Part is duplicated. - """ - - class Meta: - """Metaclass options.""" - - fields = [ - 'part', - 'copy_image', - 'copy_bom', - 'copy_parameters', - 'copy_notes', - 'copy_tests', - ] - - part = serializers.PrimaryKeyRelatedField( - queryset=Part.objects.all(), - label=_('Original Part'), - help_text=_('Select original part to duplicate'), - required=True, - ) - - copy_image = serializers.BooleanField( - label=_('Copy Image'), - help_text=_('Copy image from original part'), - required=False, - default=False, - ) - - copy_bom = serializers.BooleanField( - label=_('Copy BOM'), - help_text=_('Copy bill of materials from original part'), - required=False, - default=False, - ) - - copy_parameters = serializers.BooleanField( - label=_('Copy Parameters'), - help_text=_('Copy parameter data from original part'), - required=False, - default=False, - ) - - copy_notes = serializers.BooleanField( - label=_('Copy Notes'), - help_text=_('Copy notes from original part'), - required=False, - default=True, - ) - - copy_tests = serializers.BooleanField( - label=_('Copy Tests'), - help_text=_('Copy test templates from original part'), - required=False, - default=False, - ) - - class InitialStockSerializer(serializers.Serializer): """Serializer for creating initial stock quantity.""" @@ -586,7 +544,7 @@ class PartSerializer( Used when displaying all details of a single component. """ - import_exclude_fields = ['creation_date', 'creation_user', 'duplicate'] + import_exclude_fields = ['creation_date', 'creation_user'] class Meta: """Metaclass defining serializer fields.""" @@ -634,6 +592,7 @@ class PartSerializer( 'units', 'variant_of', 'virtual', + 'consumable', 'pricing_min', 'pricing_max', 'pricing_updated', @@ -992,11 +951,37 @@ class PartSerializer( ) # Extra fields used only for creation of a new Part instance - duplicate = DuplicatePartSerializer( + duplicate = InvenTree.serializers.DuplicateOptionsSerializer( + Part.objects.all(), label=_('Duplicate Part'), help_text=_('Copy initial data from another Part'), - write_only=True, - required=False, + copy_parameters=True, + copy_fields=[ + { + 'name': 'copy_image', + 'label': _('Copy Image'), + 'help_text': _('Copy image from original part'), + 'default': False, + }, + { + 'name': 'copy_bom', + 'label': _('Copy BOM'), + 'help_text': _('Copy bill of materials from original part'), + 'default': False, + }, + { + 'name': 'copy_notes', + 'label': _('Copy Notes'), + 'help_text': _('Copy notes from original part'), + 'default': True, + }, + { + 'name': 'copy_tests', + 'label': _('Copy Tests'), + 'help_text': _('Copy test templates from original part'), + 'default': False, + }, + ], ) initial_stock = InitialStockSerializer( @@ -1053,16 +1038,17 @@ class PartSerializer( initial_supplier = validated_data.pop('initial_supplier', None) copy_category_parameters = validated_data.pop('copy_category_parameters', False) - instance = super().create(validated_data) + # Additional data to apply to the serializer + extra_data = {} - # Save user information if request := self.context.get('request'): - instance.creation_user = request.user - instance.save() + extra_data['creation_user'] = request.user + + instance = super().create({**validated_data, **extra_data}) # Copy data from original Part if duplicate: - original = duplicate['part'] + original = duplicate['original'] if duplicate.get('copy_bom', False): instance.copy_bom_from(original) @@ -1287,7 +1273,7 @@ class PartStocktakeSerializer( if exclude_pk: self.fields.pop('pk', None) - quantity = serializers.FloatField() + quantity = InvenTree.serializers.InvenTreeDecimalField() cost_min = InvenTree.serializers.InvenTreeMoneySerializer(allow_null=True) cost_min_currency = InvenTree.serializers.InvenTreeCurrencySerializer() @@ -1447,7 +1433,9 @@ class PartPricingSerializer(InvenTree.serializers.InvenTreeModelSerializer): 'update', ] - currency = serializers.CharField(allow_null=True, read_only=True) + currency = InvenTree.serializers.InvenTreeCurrencySerializer( + allow_null=True, read_only=True + ) updated = serializers.DateTimeField(allow_null=True, read_only=True) @@ -1678,6 +1666,7 @@ class BomItemSerializer( 'reference', 'raw_amount', 'quantity', + 'piece_count', 'allow_variants', 'inherited', 'optional', @@ -1727,6 +1716,16 @@ class BomItemSerializer( required=False, allow_null=True ) + piece_count = serializers.IntegerField( + required=False, + default=1, + label=_('Piece Count'), + help_text=_( + 'Number of pieces required (for cut-to-length items). ' + 'Total material = quantity x piece_count.' + ), + ) + part = serializers.PrimaryKeyRelatedField( queryset=Part.objects.filter(assembly=True), label=_('Assembly'), diff --git a/src/backend/InvenTree/part/tasks.py b/src/backend/InvenTree/part/tasks.py index 296604422b..cec1279247 100644 --- a/src/backend/InvenTree/part/tasks.py +++ b/src/backend/InvenTree/part/tasks.py @@ -17,6 +17,7 @@ import InvenTree.helpers_model from common.settings import get_global_setting from InvenTree.tasks import ( ScheduledTask, + batch_offload_tasks, check_daily_holdoff, offload_task, record_task_success, @@ -265,45 +266,51 @@ def check_missing_pricing(limit=250): # Task does not run if the interval is zero return - # Find parts for which pricing information has never been updated - results = PartPricing.objects.filter(updated=None)[:limit] + # Scheduling each part's pricing update calls offload_task(), which (outside of a batch) + # checks the entire task queue for duplicates on every call. Batching collapses all of + # this run's scheduling into a single bulk write instead, avoiding that per-call scan. + with batch_offload_tasks(): + # Find parts for which pricing information has never been updated + results = PartPricing.objects.filter(updated=None)[:limit] - if results.count() > 0: - logger.info('Found %s parts with empty pricing', results.count()) + if results.count() > 0: + logger.info('Found %s parts with empty pricing', results.count()) - for pp in results: - pp.schedule_for_update() + for pp in results: + pp.schedule_for_update() - stale_date = datetime.now().date() - timedelta(days=days) + stale_date = datetime.now().date() - timedelta(days=days) - results = PartPricing.objects.filter(updated__lte=stale_date)[:limit] + results = PartPricing.objects.filter(updated__lte=stale_date)[:limit] - if results.count() > 0: - logger.info('Found %s stale pricing entries', results.count()) + if results.count() > 0: + logger.info('Found %s stale pricing entries', results.count()) - for pp in results: - pp.schedule_for_update() + for pp in results: + pp.schedule_for_update() - # Find any pricing data which is in the wrong currency - currency = common.currency.currency_code_default() - results = PartPricing.objects.exclude(currency=currency) + # Find any pricing data which is in the wrong currency + currency = common.currency.currency_code_default() + results = PartPricing.objects.exclude(currency=currency)[:limit] - if results.count() > 0: - logger.info('Found %s pricing entries in the wrong currency', results.count()) + if results.count() > 0: + logger.info( + 'Found %s pricing entries in the wrong currency', results.count() + ) - for pp in results: - pp.schedule_for_update() + for pp in results: + pp.schedule_for_update() - # Find any parts which do not have pricing information - results = Part.objects.filter(pricing_data=None)[:limit] + # Find any parts which do not have pricing information + results = Part.objects.filter(pricing_data=None)[:limit] - if results.count() > 0: - logger.info('Found %s parts without pricing', results.count()) + if results.count() > 0: + logger.info('Found %s parts without pricing', results.count()) - for p in results: - pricing = p.pricing - pricing.save() - pricing.schedule_for_update() + for p in results: + pricing = p.pricing + pricing.save() + pricing.schedule_for_update() @tracer.start_as_current_span('scheduled_stocktake_reports') diff --git a/src/backend/InvenTree/part/test_api.py b/src/backend/InvenTree/part/test_api.py index 011c700884..837bd68086 100644 --- a/src/backend/InvenTree/part/test_api.py +++ b/src/backend/InvenTree/part/test_api.py @@ -7,7 +7,7 @@ from random import randint from django.core.exceptions import ValidationError from django.db import connection -from django.test.utils import CaptureQueriesContext +from django.test.utils import CaptureQueriesContext, override_settings from django.urls import reverse import pytest @@ -19,9 +19,15 @@ import company.models import order.models from build.status_codes import BuildStatus from common.models import InvenTreeSetting, ParameterTemplate +from common.settings import set_global_setting from company.models import Company, SupplierPart from InvenTree.config import get_testfolder_dir -from InvenTree.unit_test import InvenTreeAPIPerformanceTestCase, InvenTreeAPITestCase +from InvenTree.unit_test import ( + InvenTreeAPIPerformanceTestCase, + InvenTreeAPITestCase, + findOffloadedEvent, + findOffloadedTask, +) from order.status_codes import PurchaseOrderStatusGroups from part.models import ( BomItem, @@ -46,6 +52,7 @@ class PartImageTestMixin: 'part.delete', 'part_category.change', 'part_category.add', + 'stock_location.view', ] @classmethod @@ -104,6 +111,72 @@ class PartCategoryAPITest(InvenTreeAPITestCase): 'part_category.delete', ] + def test_bulk_set_parent(self): + """Test that bulk re-parenting of categories correctly rebuilds the tree. + + Re-parenting multiple categories in a single 'bulk update' API call must + leave the tree structure and the 'pathstring' values fully consistent. + + Ref: https://github.com/inventree/InvenTree/issues/12394 + """ + url = reverse('api-part-category-list') + + parent_a = PartCategory.objects.create(name='Parent A') + parent_b = PartCategory.objects.create(name='Parent B') + + # Create a number of subcategories under 'Parent A', + # some of which have their own child categories + categories = [] + + for i in range(50): + category = PartCategory.objects.create(name=f'Cat{i:02d}', parent=parent_a) + categories.append(category) + + if i % 5 == 0: + child = PartCategory.objects.create( + name=f'Cat{i:02d}-child', parent=category + ) + PartCategory.objects.create(name=f'Cat{i:02d}-grandchild', parent=child) + + # Move all subcategories to 'Parent B' in a single bulk update. + # The query count must scale linearly with the number of items. + # Note: when the background worker is not running (e.g. in tests), each + # item save runs the (de-duplicated) tree rebuild task synchronously + self.patch( + url, + {'items': [category.pk for category in categories], 'parent': parent_b.pk}, + expected_code=200, + max_query_count=60 * len(categories), + max_query_time=10, # Note: in production this is offloaded to the background worker + ) + + for category in categories: + category.refresh_from_db() + self.assertEqual(category.parent, parent_b) + + parent_a.refresh_from_db() + parent_b.refresh_from_db() + + # Check *all* categories in the affected trees + # (fixture data outside these trees does not have pathstring values set) + affected_trees = PartCategory.objects.filter( + tree_id__in=[parent_a.tree_id, parent_b.tree_id] + ) + + for category in affected_trees: + # The stored pathstring must match the 'parent' chain for the node + chain = [] + node = category + + while node is not None: + chain.insert(0, node) + node = node.parent + + self.assertEqual(category.pathstring, '/'.join(node.name for node in chain)) + + # The MPTT tree data must match the 'parent' chain, too + self.assertEqual(list(category.get_ancestors()), chain[:-1]) + def test_category_list(self): """Test the PartCategoryList API endpoint.""" url = reverse('api-part-category-list') @@ -748,6 +821,7 @@ class PartAPITestBase(InvenTreeAPITestCase): 'part.delete', 'part_category.change', 'part_category.add', + 'stock_location.view', ] @@ -1440,6 +1514,75 @@ class PartAPITest(PartAPITestBase): for field in ['name', 'description', 'structural']: self.assertIn(field, category) + @override_settings( + TESTING_TABLE_EVENTS=True, + PLUGIN_TESTING_EVENTS=True, + PLUGIN_TESTING_EVENTS_ASYNC=True, + ) + def test_bulk_update(self): + """Test that we can bulk-update a set of parts via the API. + + Test that: + - All parts are updated correctly + - Instance saved events are offloaded to the background worker + """ + from django_q.models import OrmQ + + self.assignRole('part.change') + + set_global_setting('ENABLE_PLUGINS_EVENTS', True) + + # Create a bunch of parts + parts = [ + Part.objects.create( + name=f'Bulk part {i}', + description='A part for bulk update testing', + category=PartCategory.objects.first(), + active=True, + ) + for i in range(10) + ] + + for part in parts: + self.assertTrue(part.active) + + # Clear out event registry + OrmQ.objects.all().delete() + + # Bulk update all parts to be inactive + response = self.patch( + reverse('api-part-list'), + {'active': False, 'items': [part.pk for part in parts]}, + expected_code=200, + benchmark=True, + max_query_count=250, + max_query_time=2.0, + ) + + self.assertEqual(len(response.data['items']), len(parts)) + + # Check that events have been registered + self.assertGreaterEqual(OrmQ.objects.count(), 2 * len(parts)) + + # Check that 'active' parameter has been updated for all parts + for part in parts: + part.refresh_from_db() + self.assertFalse(part.active) + + self.assertIsNotNone( + findOffloadedEvent('part_part.saved', matching_kwargs={'id': part.pk}), + f'part_part.saved event not found for part {part.pk} not found in offloaded events', + ) + + self.assertIsNotNone( + findOffloadedTask( + 'part.tasks.rebuild_supplier_parts', matching_args=[part.pk] + ), + f'rebuild_supplier_parts task not found for part {part.pk} not found in offloaded tasks', + ) + + set_global_setting('ENABLE_PLUGINS_EVENTS', False) + class PartCreationTests(PartAPITestBase): """Tests for creating new Part instances via the API.""" @@ -1495,6 +1638,70 @@ class PartCreationTests(PartAPITestBase): self.assertFalse(response.data['active']) self.assertFalse(response.data['purchaseable']) + def test_create_duplicate_no_ipn_revision(self): + """Test that creating a duplicate part (same name, no IPN/revision) returns a 400. + + Regression test for a bug where the duplicate-name check was skipped + whenever IPN and revision were both blank, letting the request fall + through to an unhandled database IntegrityError (500) instead of a + proper validation error (400). + """ + url = reverse('api-part-list') + + data = { + 'name': 'TEST1', + 'category': 1, + 'assembly': True, + 'component': True, + 'consumable': False, + 'is_template': False, + 'purchaseable': False, + 'salable': False, + 'testable': False, + 'trackable': False, + 'virtual': False, + } + + self.post(url, data, expected_code=201) + + # Attempting to create the exact same part again must be rejected cleanly + response = self.post(url, data, expected_code=400) + self.assertIn('non_field_errors', response.data) + + def test_notes_on_create(self): + """Test that notes can be set when creating a Part.""" + list_url = reverse('api-part-list') + + notes = """ + ### Created from importer + + Notes should persist during part creation. + """ + expected_notes = notes.strip() + + response = self.post( + list_url, + { + 'name': 'part with notes', + 'description': 'Part notes are created in the same request', + 'category': 1, + 'notes': notes, + }, + expected_code=201, + ) + + self.assertEqual(response.data['notes'], expected_notes) + + part = Part.objects.get(pk=response.data['pk']) + self.assertEqual(part.notes, expected_notes) + + detail_url = reverse('api-part-detail', kwargs={'pk': part.pk}) + response = self.get(detail_url, expected_code=200) + self.assertEqual(response.data['notes'], expected_notes) + + response = self.get(list_url, {'limit': 1}, expected_code=200) + self.assertNotIn('notes', response.data['results'][0]) + def test_initial_stock(self): """Tests for initial stock quantity creation.""" @@ -1649,7 +1856,7 @@ class PartCreationTests(PartAPITestBase): 'testable': do_copy, 'assembly': do_copy, 'duplicate': { - 'part': 100, + 'original': 100, 'copy_bom': do_copy, 'copy_notes': do_copy, 'copy_image': do_copy, @@ -1712,6 +1919,51 @@ class PartCreationTests(PartAPITestBase): prt = Part.objects.get(pk=data['pk']) self.assertEqual(prt.parameters.count(), 3) + def test_category_parameters_unique(self): + """Test that category parameters with a uniqueness requirement are not applied. + + Applying the same default value to every part created in a category + would immediately conflict with a 'unique' parameter template. + """ + cat = PartCategory.objects.get(pk=1) + + normal_template = ParameterTemplate.objects.get(pk=1) + + unique_template = ParameterTemplate.objects.create( + name='Serial Number', + description='A globally unique parameter', + unique=ParameterTemplate.UniqueOptions.GLOBAL, + ) + + PartCategoryParameterTemplate.objects.create( + template=normal_template, category=cat, default_value='Normal Value' + ) + + PartCategoryParameterTemplate.objects.create( + template=unique_template, category=cat, default_value='Fixed Value' + ) + + # Create two parts in this category, copying category parameters + for name in ['Part A', 'Part B']: + data = self.post( + reverse('api-part-list'), + { + 'category': cat.pk, + 'name': name, + 'description': 'A part for testing unique category parameters', + 'copy_category_parameters': True, + }, + expected_code=201, + ).data + + prt = Part.objects.get(pk=data['pk']) + + # The 'normal' parameter should have been copied for each part + self.assertIsNotNone(prt.get_parameter(normal_template.name)) + + # The 'unique' parameter template should *not* have been applied + self.assertIsNone(prt.get_parameter(unique_template.name)) + class PartDetailTests(PartImageTestMixin, PartAPITestBase): """Test that we can create / edit / delete Part objects via the API.""" @@ -2170,10 +2422,13 @@ class PartListTests(PartAPITestBase): query_count_with_price_breaks - query_count_without_price_breaks ) - # There are 2 additional queries, 1 for the salepricebreak subselect and 1 for Currency codes because of InvenTreeCurrencySerializer + # There are 4 additional queries: 1 for the salepricebreak subselect, 1 for + # Currency codes because of InvenTreeCurrencySerializer, and 2 for the one-off + # permission check (fetch groups + rule sets) gating the price_breaks field's + # embedded PartSellPriceBreak model - this cost is fixed per-request, not per-row. self.assertLessEqual( query_difference, - 2, + 4, f'Query count difference too high: {query_difference} (with: {query_count_with_price_breaks}, without: {query_count_without_price_breaks})', ) @@ -2562,6 +2817,25 @@ class PartAPIAggregationTest(InvenTreeAPITestCase): # The annotated quantity must also match the part.on_order quantity self.assertEqual(on_order, p.on_order) + # Test the 'on_order' filter + response = self.get( + reverse('api-part-list'), + {'category': paint.pk, 'on_order': True}, + expected_code=200, + ) + + for item in response.data: + self.assertGreater(item['ordering'], 0) + + response = self.get( + reverse('api-part-list'), + {'category': paint.pk, 'on_order': False}, + expected_code=200, + ) + + for item in response.data: + self.assertLessEqual(item['ordering'], 0) + def test_building(self): """Test the 'building' quantity annotations.""" # Create a new "buildable" part @@ -2795,6 +3069,14 @@ class BomItemTest(InvenTreeAPITestCase): """Get the detail view for a single BomItem object.""" from part.models import BomItemSubstitute + # Viewing 'substitutes' requires the 'bom' role (BomItemSubstitute is not + # covered by the part->bomitem RULESET_CHANGE_INHERIT fallback). Grant both + # 'add' and 'delete' so the 'bom' RuleSet ends up fully matching the existing + # part-inherited bomitem permissions - granting only 'view' would otherwise + # cause update_group_roles() to wipe those already-inherited permissions. + self.assignRole('bom.add') + self.assignRole('bom.delete') + bom_item = BomItem.objects.get(pk=3) # Create some substitutes for this BomItem @@ -2872,6 +3154,11 @@ class BomItemTest(InvenTreeAPITestCase): def test_output_options(self): """Test that various output options work as expected.""" + # Viewing 'substitutes' requires the 'bom' role (see test_get_bom_detail for why + # both 'add' and 'delete' are granted together). + self.assignRole('bom.add') + self.assignRole('bom.delete') + self.run_output_test( reverse('api-bom-item-detail', kwargs={'pk': 3}), [ @@ -3222,6 +3509,66 @@ class BomItemTest(InvenTreeAPITestCase): can_build = response.data['can_build'] self.assertAlmostEqual(can_build, 482.9, places=1) + def test_piece_count_get(self): + """Test that piece_count is returned in GET response for BomItem.""" + bom_item = BomItem.objects.first() + assert bom_item + + url = reverse('api-bom-item-detail', kwargs={'pk': bom_item.pk}) + response = self.get(url, expected_code=200) + + # piece_count should be present in the response + self.assertIn('piece_count', response.data) + # Default value is 1 + self.assertEqual(response.data['piece_count'], 1) + + def test_piece_count_post(self): + """Test creating a BomItem with piece_count via POST.""" + url = reverse('api-bom-list') + + # Create a BomItem with piece_count specified + data = {'part': 100, 'sub_part': 4, 'quantity': 200, 'piece_count': 10} + response = self.post(url, data, expected_code=201) + + self.assertEqual(response.data['piece_count'], 10) + self.assertEqual(response.data['quantity'], 200) + + def test_piece_count_post_default(self): + """Test that piece_count defaults to 1 when not specified in POST.""" + url = reverse('api-bom-list') + + data = {'part': 100, 'sub_part': 4, 'quantity': 50} + response = self.post(url, data, expected_code=201) + + self.assertEqual(response.data['piece_count'], 1) + + def test_piece_count_patch(self): + """Test updating piece_count via PATCH.""" + bom_item = BomItem.objects.first() + assert bom_item + + url = reverse('api-bom-item-detail', kwargs={'pk': bom_item.pk}) + + # Update piece_count + response = self.patch(url, {'piece_count': 7}, expected_code=200) + self.assertEqual(response.data['piece_count'], 7) + + # Verify the change persisted + response = self.get(url, expected_code=200) + self.assertEqual(response.data['piece_count'], 7) + + def test_piece_count_invalid_values(self): + """Test that invalid piece_count values are rejected via API.""" + url = reverse('api-bom-list') + + # piece_count = 0 should be rejected + data = {'part': 100, 'sub_part': 4, 'quantity': 10, 'piece_count': 0} + self.post(url, data, expected_code=400) + + # piece_count = -1 should be rejected + data = {'part': 100, 'sub_part': 4, 'quantity': 10, 'piece_count': -1} + self.post(url, data, expected_code=400) + class AttachmentTest(InvenTreeAPITestCase): """Unit tests for the Attachment API endpoint.""" diff --git a/src/backend/InvenTree/part/test_bom_item.py b/src/backend/InvenTree/part/test_bom_item.py index 13bebc5e3c..3e08bea0a9 100644 --- a/src/backend/InvenTree/part/test_bom_item.py +++ b/src/backend/InvenTree/part/test_bom_item.py @@ -1,6 +1,7 @@ """Unit tests for the BomItem model.""" -from decimal import Decimal +import hashlib +from unittest import mock import django.core.exceptions as django_exceptions from django.db import transaction @@ -171,20 +172,6 @@ class BomItemTest(TestCase): self.assertNotEqual(h1, h2) - def test_pricing(self): - """Test BOM pricing.""" - self.bob.get_price(1) - self.assertEqual( - self.bob.get_bom_price_range(1, internal=True), - (Decimal(29.5), Decimal(89.5)), - ) - # remove internal price for R_2K2_0805 - self.r1.internal_price_breaks.delete() - self.assertEqual( - self.bob.get_bom_price_range(1, internal=True), - (Decimal(27.5), Decimal(87.5)), - ) - def test_substitutes(self): """Tests for BOM item substitutes.""" # We will make some substitute parts for the "orphan" part @@ -277,6 +264,52 @@ class BomItemTest(TestCase): self.assertEqual(assembly.can_build, 20) + # Mark 'c4' as consumable at the *part* level (not the BOM line itself) + c4.consumable = True + c4.save() + + bom_item_c4 = BomItem.objects.create(part=assembly, sub_part=c4, quantity=200) + + # The raw BomItem field is unset, but the part is marked as consumable + self.assertFalse(bom_item_c4.consumable) + self.assertTrue(bom_item_c4.is_consumable) + + # A BomItem which is consumable via its part does not alter the can_build calculation + self.assertEqual(assembly.can_build, 20) + + def test_consumable_filter(self): + """Tests for the BomItem.consumable_filter() helper method.""" + assembly = Part.objects.create( + name='Another assembly', description='Made with parts', assembly=True + ) + + c1 = Part.objects.create(name='D1', description='Not consumable') + c2 = Part.objects.create(name='D2', description='Consumable BOM line') + c3 = Part.objects.create( + name='D3', description='Consumable part', consumable=True + ) + + bom_item_1 = BomItem.objects.create(part=assembly, sub_part=c1, quantity=1) + bom_item_2 = BomItem.objects.create( + part=assembly, sub_part=c2, quantity=1, consumable=True + ) + bom_item_3 = BomItem.objects.create(part=assembly, sub_part=c3, quantity=1) + + consumable_items = set( + BomItem.objects.filter(BomItem.consumable_filter(consumable=True)) + ) + non_consumable_items = set( + BomItem.objects.filter(BomItem.consumable_filter(consumable=False)) + ) + + self.assertIn(bom_item_2, consumable_items) + self.assertIn(bom_item_3, consumable_items) + self.assertNotIn(bom_item_1, consumable_items) + + self.assertIn(bom_item_1, non_consumable_items) + self.assertNotIn(bom_item_2, non_consumable_items) + self.assertNotIn(bom_item_3, non_consumable_items) + def test_metadata(self): """Unit tests for the metadata field.""" for model in [BomItem]: @@ -430,6 +463,59 @@ class BomItemTest(TestCase): bom_item2.quantity = 99 bom_item2.save() + def test_bom_hash_order_consistency(self): + """Regression test for BOM checksum instability due to non-deterministic item ordering. + + See: https://github.com/inventree/InvenTree/issues/12445 + + get_bom_hash() must apply an explicit, stable ordering when iterating the BOM + items - otherwise the resulting hash can differ purely because the underlying + query returned rows in a different order (e.g. Postgres provides no ordering + guarantee unless an ORDER BY clause is specified). + """ + assembly = Part.objects.create( + name='HashOrderAssembly', description='An assembly part', assembly=True + ) + + for ii in range(5): + sub_part = Part.objects.create( + name=f'HashOrderPart{ii}', + description='A sub-part for hash ordering test', + component=True, + ) + BomItem.objects.create(part=assembly, sub_part=sub_part, quantity=ii + 1) + + # Calling get_bom_hash() repeatedly must always return the same value + h1 = assembly.get_bom_hash() + h2 = assembly.get_bom_hash() + self.assertEqual(h1, h2) + + def hash_items(items) -> str: + """Replicate the hashing logic of get_bom_hash(), for a given item order.""" + result_hash = hashlib.md5(str(assembly.id).encode()) + + for item in items: + result_hash.update(str(item.get_item_hash()).encode()) + + return str(result_hash.digest()) + + items_forward = list(assembly.get_bom_items().order_by('pk')) + items_reverse = list(assembly.get_bom_items().order_by('-pk')) + self.assertEqual(items_forward, list(reversed(items_reverse))) + + # Sanity check: hashing the *same* items in a different order produces a + # different result - so ordering genuinely matters here + self.assertNotEqual(hash_items(items_forward), hash_items(items_reverse)) + + # Simulate the underlying queryset returning BOM items in a non pk-ascending + # order (as could occur against a real database with no ORDER BY applied). + # get_bom_hash() must be unaffected, always normalizing to the same order. + reversed_queryset = assembly.get_bom_items().order_by('-pk') + with mock.patch.object(Part, 'get_bom_items', return_value=reversed_queryset): + hash_from_reversed_source = assembly.get_bom_hash() + + self.assertEqual(hash_from_reversed_source, hash_items(items_forward)) + def test_bom_validated(self): """Test for caching of 'bom_validated' property.""" from part.tasks import validate_bom @@ -509,3 +595,112 @@ class BomItemTest(TestCase): check(valid=False) self.assertIsNotNone(assembly.bom_checked_date) + + def test_piece_count_default(self): + """Test that piece_count defaults to 1 and does not change existing behavior.""" + item = BomItem.objects.get(part=100, sub_part=50) + + # Default value should be 1 + self.assertEqual(item.piece_count, 1) + + # With piece_count=1, get_required_quantity should behave as before + item.set_quantity(10) + item.attrition = 0 + item.setup_quantity = 0 + item.rounding_multiple = None + item.save() + + # 10 * 1 (piece_count) * 5 (build_quantity) = 50 + self.assertEqual(item.get_required_quantity(5), 50) + + def test_piece_count_multiplier(self): + """Test that piece_count correctly multiplies the required quantity. + + Example: Cutting wire into 200mm lengths, need 10 pieces per assembly. + quantity=200 (mm per piece), piece_count=10, build_quantity=5 + Total = 200 * 10 * 5 = 10000 mm + """ + item = BomItem.objects.get(part=100, sub_part=50) + + item.set_quantity(200) + item.piece_count = 10 + item.attrition = 0 + item.setup_quantity = 0 + item.rounding_multiple = None + item.save() + + # 200 * 10 * 5 = 10000 + self.assertEqual(item.get_required_quantity(5), 10000) + + # 200 * 10 * 1 = 2000 + self.assertEqual(item.get_required_quantity(1), 2000) + + # 200 * 10 * 10 = 20000 + self.assertEqual(item.get_required_quantity(10), 20000) + + def test_piece_count_with_attrition(self): + """Test piece_count combined with attrition percentage.""" + item = BomItem.objects.get(part=100, sub_part=50) + + item.set_quantity(100) + item.piece_count = 5 + item.attrition = 10 # 10% attrition + item.setup_quantity = 0 + item.rounding_multiple = None + item.save() + + # Base: 100 * 5 * 2 = 1000 + # With 10% attrition: 1000 * 1.10 = 1100 + self.assertEqual(item.get_required_quantity(2), 1100) + + def test_piece_count_with_setup_quantity(self): + """Test piece_count combined with setup_quantity.""" + item = BomItem.objects.get(part=100, sub_part=50) + + item.set_quantity(50) + item.piece_count = 4 + item.attrition = 0 + item.setup_quantity = 20 + item.rounding_multiple = None + item.save() + + # Base: 50 * 4 * 3 = 600 + # With setup_quantity: 600 + 20 = 620 + self.assertEqual(item.get_required_quantity(3), 620) + + def test_piece_count_with_rounding(self): + """Test piece_count combined with rounding_multiple.""" + item = BomItem.objects.get(part=100, sub_part=50) + + item.set_quantity(7) + item.piece_count = 3 + item.attrition = 0 + item.setup_quantity = 0 + item.rounding_multiple = 25 + item.save() + + # Base: 7 * 3 * 2 = 42 + # Rounded up to nearest multiple of 25: 50 + self.assertEqual(item.get_required_quantity(2), 50) + + def test_piece_count_validation(self): + """Test that piece_count rejects invalid values (0, negative).""" + item = BomItem.objects.get(part=100, sub_part=50) + + # piece_count = 0 should be rejected (MinValueValidator(1)) + item.piece_count = 0 + with self.assertRaises(django_exceptions.ValidationError): + item.full_clean() + + # piece_count = -1 should also be rejected + item.piece_count = -1 + with self.assertRaises(django_exceptions.ValidationError): + item.full_clean() + + # piece_count = 1 is the minimum valid value + item.piece_count = 1 + item.full_clean() # Should not raise + + # piece_count = 100 is a valid value + item.piece_count = 100 + item.full_clean() # Should not raise diff --git a/src/backend/InvenTree/part/test_param.py b/src/backend/InvenTree/part/test_param.py index 41e6c3c4b0..6bd3e465af 100644 --- a/src/backend/InvenTree/part/test_param.py +++ b/src/backend/InvenTree/part/test_param.py @@ -252,7 +252,7 @@ class ParameterTests(TestCase): tmp.full_clean() # Test that invalid units fail - for unit in ['mmmmm', '-', 'x', int]: + for unit in ['mmmmm', '-', 'x', int, "piao's"]: tmp = ParameterTemplate(name='test', units=unit) with self.assertRaises(django_exceptions.ValidationError): tmp.full_clean() diff --git a/src/backend/InvenTree/part/test_part.py b/src/backend/InvenTree/part/test_part.py index 05e58d225e..57b21dc0cb 100644 --- a/src/backend/InvenTree/part/test_part.py +++ b/src/backend/InvenTree/part/test_part.py @@ -219,6 +219,40 @@ class PartTest(TestCase): with self.assertRaises(ValidationError): part_2.validate_unique() + def test_duplicate_no_ipn_revision(self): + """Test that we cannot create a duplicate Part when IPN and revision are both blank strings. + + Regression test: the underlying 'unique_part' database constraint treats + blank IPN/revision values (empty strings, as sent by the API when these + fields are omitted) as equal, so validate_unique() must catch this case + too, rather than raising an unhandled IntegrityError. Note that this is + distinct from *unset* (None/NULL) values, which the database constraint + does *not* treat as colliding (see test_revisions). + """ + cat = PartCategory.objects.get(pk=1) + + Part.objects.create( + category=cat, + name='dupe_test', + description='description', + IPN='', + revision='', + ) + + part = Part( + category=cat, + name='dupe_test', + description='description', + IPN='', + revision='', + ) + + with self.assertRaises(ValidationError): + part.validate_unique() + + with self.assertRaises(ValidationError): + part.save() + def test_attributes(self): """Test Part attributes.""" self.assertEqual(self.r1.name, 'R_2K2_0805') @@ -250,22 +284,6 @@ class PartTest(TestCase): barcode = self.r1.format_barcode() self.assertEqual('INV-PA3', barcode) - def test_sell_pricing(self): - """Check that the sell pricebreaks were loaded.""" - self.assertTrue(self.r1.has_price_breaks) - self.assertEqual(self.r1.price_breaks.count(), 2) - # check that the sell pricebreaks work - self.assertEqual(float(self.r1.get_price(1)), 0.15) - self.assertEqual(float(self.r1.get_price(10)), 1.0) - - def test_internal_pricing(self): - """Check that the sell pricebreaks were loaded.""" - self.assertTrue(self.r1.has_internal_price_breaks) - self.assertEqual(self.r1.internal_price_breaks.count(), 2) - # check that the sell pricebreaks work - self.assertEqual(float(self.r1.get_internal_price(1)), 0.08) - self.assertEqual(float(self.r1.get_internal_price(10)), 0.5) - def test_metadata(self): """Unit tests for the metadata field.""" for model in [Part]: diff --git a/src/backend/InvenTree/part/test_pricing.py b/src/backend/InvenTree/part/test_pricing.py index 468b221d49..2bfd92e967 100644 --- a/src/backend/InvenTree/part/test_pricing.py +++ b/src/backend/InvenTree/part/test_pricing.py @@ -1,5 +1,7 @@ """Unit tests for Part pricing calculations.""" +from unittest import mock + from django.core.exceptions import ObjectDoesNotExist from django.test.utils import override_settings @@ -431,6 +433,38 @@ class PartPricingTests(InvenTreeTestCase): # Check that PartPricing objects have been created self.assertEqual(part.models.PartPricing.objects.count(), 101) + def test_check_missing_pricing_batches_scheduling(self): + """check_missing_pricing() must batch its scheduling calls, not scan the task queue per part. + + Regression test: without batching, each PartPricing.schedule_for_update() call triggers + offload_task() -> check_existing_task(), which scans and unpickles every row in the task + queue to look for a duplicate. Calling this once per part inside check_missing_pricing's + loops made scheduling cost grow with the queue backlog, which is what caused a background + worker timeout in production (Sentry: "Task exceeded maximum timeout value (90 seconds)" + raised from check_existing_task). + """ + from part.tasks import check_missing_pricing + + # Create some parts (deliberately not using TESTING_PRICING here, so that + # schedule_for_update() actually offloads via the task queue rather than running inline) + for ii in range(20): + part.models.Part.objects.create( + name=f'Part_{ii}', description='A test part' + ) + + # Ensure there is no pricing data + part.models.PartPricing.objects.all().delete() + + with self.captureOnCommitCallbacks(execute=True): + with mock.patch('InvenTree.tasks.check_existing_task') as mock_check: + check_missing_pricing() + + # Scheduling was batched - the per-call duplicate-check scan never ran + mock_check.assert_not_called() + + # PartPricing objects were still created and scheduled for a background update + self.assertEqual(part.models.PartPricing.objects.count(), 21) + @override_settings(TESTING_PRICING=True) def test_delete_part_with_stock_items(self): """Test deleting a part instance with stock items. diff --git a/src/backend/InvenTree/plugin/api.py b/src/backend/InvenTree/plugin/api.py index 400f0004df..9b1685e158 100644 --- a/src/backend/InvenTree/plugin/api.py +++ b/src/backend/InvenTree/plugin/api.py @@ -10,7 +10,7 @@ import django_filters.rest_framework.filters as rest_filters from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework.filterset import FilterSet from drf_spectacular.utils import extend_schema -from rest_framework import status +from rest_framework import permissions, status from rest_framework.exceptions import NotFound from rest_framework.response import Response from rest_framework.views import APIView @@ -174,7 +174,10 @@ class PluginDetail(RetrieveDestroyAPI): queryset = PluginConfig.objects.all() serializer_class = PluginSerializers.PluginConfigSerializer - permission_classes = [InvenTree.permissions.IsSuperuserOrReadOnlyOrScope] + permission_classes = [ + permissions.IsAuthenticated, + InvenTree.permissions.IsSuperuserOrReadOnlyOrScope, + ] lookup_field = 'key' lookup_url_kwarg = 'plugin' @@ -201,6 +204,7 @@ class PluginAdminDetail(RetrieveAPI): queryset = PluginConfig.objects.all() serializer_class = PluginSerializers.PluginAdminDetailSerializer + permission_classes = [InvenTree.permissions.IsAdminOrAdminScope] lookup_field = 'key' lookup_url_kwarg = 'plugin' @@ -292,7 +296,10 @@ class PluginSettingList(ListAPI): queryset = PluginSetting.objects.all() serializer_class = PluginSerializers.PluginSettingSerializer - permission_classes = [InvenTree.permissions.GlobalSettingsPermissions] + permission_classes = [ + permissions.IsAuthenticated, + InvenTree.permissions.GlobalSettingsPermissions, + ] filter_backends = [DjangoFilterBackend] @@ -351,7 +358,10 @@ def check_plugin( if not plugin_cfg.active: raise NotFound(detail=f"Plugin '{ref}' is not active") - plugin = plugin_cfg.plugin + # Look up via the registry rather than `plugin_cfg.plugin`: the latter can be a + # stale, un-instantiated plugin class in this worker if the plugin was activated + # by a different process (registry.get_plugin() forces a reload check first). + plugin = registry.get_plugin(plugin_cfg.key) if not plugin: raise NotFound(detail=f"Plugin '{ref}' not installed") @@ -365,7 +375,10 @@ class PluginAllSettingList(APIView): - GET: return all settings for a plugin config """ - permission_classes = [InvenTree.permissions.GlobalSettingsPermissions] + permission_classes = [ + permissions.IsAuthenticated, + InvenTree.permissions.GlobalSettingsPermissions, + ] @extend_schema( responses={200: PluginSerializers.PluginSettingSerializer(many=True)} @@ -393,6 +406,11 @@ class PluginSettingDetail(RetrieveUpdateAPI): queryset = PluginSetting.objects.all() serializer_class = PluginSerializers.PluginSettingSerializer + permission_classes = [ + permissions.IsAuthenticated, + InvenTree.permissions.GlobalSettingsPermissions, + ] + def get_object(self): """Lookup the plugin setting object, based on the URL. @@ -415,9 +433,6 @@ class PluginSettingDetail(RetrieveUpdateAPI): setting_key, plugin=plugin.plugin_config() ) - # Staff permission required - permission_classes = [InvenTree.permissions.GlobalSettingsPermissions] - class PluginUserSettingList(APIView): """List endpoint for all user settings for a specific plugin. diff --git a/src/backend/InvenTree/plugin/base/barcodes/api.py b/src/backend/InvenTree/plugin/base/barcodes/api.py index c67a9bed2b..781ec19548 100644 --- a/src/backend/InvenTree/plugin/base/barcodes/api.py +++ b/src/backend/InvenTree/plugin/base/barcodes/api.py @@ -153,7 +153,9 @@ class BarcodeView(CreateAPIView): for current_plugin in plugins: try: - result = current_plugin.scan(barcode) + result = current_plugin.scan(barcode, user=request.user, **kwargs) + except PermissionDenied as exc: + raise exc except Exception: log_error('BarcodeView.scan_barcode', plugin=current_plugin.slug) continue @@ -282,7 +284,7 @@ class BarcodeAssign(BarcodeView): # First check if the provided barcode matches an existing database entry if inventree_barcode_plugin: - result = inventree_barcode_plugin.scan(barcode) + result = inventree_barcode_plugin.scan(barcode, user=request.user, **kwargs) if result is not None: result['error'] = _('Barcode matches existing item') @@ -387,8 +389,6 @@ class BarcodePOAllocate(BarcodeView): - A SupplierPart object """ - role_required = ['purchase_order.add'] - serializer_class = barcode_serializers.BarcodePOAllocateSerializer def get_supplier_part( @@ -442,6 +442,13 @@ class BarcodePOAllocate(BarcodeView): def handle_barcode(self, barcode: str, request, **kwargs): """Scan the provided barcode data.""" + if not check_user_permission(request.user, order.models.PurchaseOrder, 'add'): + raise PermissionDenied({ + 'error': _( + 'You do not have the required permissions for purchase orders' + ) + }) + # The purchase order is provided as part of the request purchase_order = kwargs.get('purchase_order') @@ -459,7 +466,9 @@ class BarcodePOAllocate(BarcodeView): manufacturer_part=response.get('manufacturerpart', None), ) response['success'] = _('Matched supplier part') - response['supplierpart'] = supplier_part.format_matched_response() + response['supplierpart'] = supplier_part.format_matched_response( + user=request.user + ) except ValidationError as e: response['error'] = str(e) @@ -489,12 +498,17 @@ class BarcodePOReceive(BarcodeView): - location: The destination location for the received item (optional) """ - role_required = ['purchase_order.add'] - serializer_class = barcode_serializers.BarcodePOReceiveSerializer def handle_barcode(self, barcode: str, request, **kwargs): """Handle a barcode scan for a purchase order item.""" + if not check_user_permission(request.user, order.models.PurchaseOrder, 'add'): + raise PermissionDenied({ + 'error': _( + 'You do not have the required permissions for purchase orders' + ) + }) + logger.debug("BarcodePOReceive: scanned barcode - '%s'", barcode) # Extract optional fields from the dataset @@ -524,7 +538,7 @@ class BarcodePOReceive(BarcodeView): filter(lambda plugin: plugin.name == 'InvenTreeBarcode', plugins) ) - if result := internal_barcode_plugin.scan(barcode): + if result := internal_barcode_plugin.scan(barcode, user=request.user, **kwargs): if 'stockitem' in result: response['error'] = _('Item has already been received') self.log_scan(request, response, False) @@ -533,10 +547,23 @@ class BarcodePOReceive(BarcodeView): # Now, look just for "supplier-barcode" plugins plugins = registry.with_mixin(PluginMixinEnum.SUPPLIER_BARCODE) + plugin_slug = None + plugin_response = None + plugin_error = None + + no_supplier_plugin_error = [] + + supplier_purchase_order = None + + plugin_supplier = None + + supplier_part = None + for current_plugin in plugins: try: + # Will either Output Debugresponse if No_Match is True or return the regular response if No_Match is False result = current_plugin.scan_receive_item( barcode, request.user, @@ -546,12 +573,58 @@ class BarcodePOReceive(BarcodeView): line_item=line_item, auto_allocate=auto_allocate, ) + except Exception: log_error('BarcodePOReceive.handle_barcode', plugin=current_plugin.slug) continue - if result is None: - continue + no_match = result.get('no_match', True) + + # No_Match Determines if it found a exact match for all the required fields from scan_recieve_item + if no_match is True: + supplier_found = False + + try: + plugin_slug = current_plugin.slug + supplier_purchase_order = result.get('PO') + plugin_supplier = result.get('supplier') + supplier_part = result.get('supplier_part') + except KeyError as e: + log_error( + f'BarcodePOReceive.handle_barcode debugresponse: KeyError {e}' + ) + continue + + # Supplier does not have associated Supplier ID + if plugin_supplier is None: + no_supplier_plugin_error.append(plugin_slug) + continue + + # No Purchase Order or Supplier Part Found + if supplier_purchase_order is None and supplier_part is None: + continue + + # Purchase Order exists and is found but Supplier part does not exist + if supplier_purchase_order != None and supplier_part is None: + # Supplier was Found + supplier_found = True + plugin_error = _('Purchase order Found\rNo supplier Part Match') + + # Supplier Part is Found but Purchase Order does not exist + elif supplier_purchase_order is None and supplier_part != None: + # Supplier was Found + supplier_found = True + plugin_error = _('Supplier Part Found\rNo Purchase Order Match') + + # Supplier for PO or Supplier part in barcode was found + if supplier_found is True: + # Adds info on for what was found in the barcode + response['supplier_matches'] = { + 'purchase_order': supplier_purchase_order, + 'no_match': no_match, + 'supplier': plugin_supplier, + 'supplier_part': supplier_part, + } if 'error' in result: logger.info( @@ -569,13 +642,20 @@ class BarcodePOReceive(BarcodeView): response['plugin'] = plugin.name if plugin else None - if plugin_response: + # If there is a plugin response, and there is a match (no_match = false), combine the dictionaries + if plugin_response and plugin_response.get('no_match') is False: response = {**response, **plugin_response} + elif no_supplier_plugin_error: + response['no_supplier_plugin_error'] = no_supplier_plugin_error # A plugin has not been found! if plugin is None: response['error'] = _('No plugin match for supplier barcode') + # A plugin was found, with a Error + elif plugin_error: + response['error'] = plugin_error + self.log_scan(request, response, 'success' in response) if 'error' in response: @@ -597,8 +677,6 @@ class BarcodeSOAllocate(BarcodeView): - Quantity """ - role_required = ['sales_order.add'] - serializer_class = barcode_serializers.BarcodeSOAllocateSerializer def get_line_item(self, stock_item, **kwargs): @@ -666,6 +744,11 @@ class BarcodeSOAllocate(BarcodeView): line: SalesOrderLineItem ID value (optional) shipment: SalesOrderShipment ID value (optional) """ + if not check_user_permission(request.user, order.models.SalesOrder, 'add'): + raise PermissionDenied({ + 'error': _('You do not have the required permissions for sales orders') + }) + logger.debug("BarcodeSOAllocate: scanned barcode - '%s'", barcode) response = self.scan_barcode(barcode, request, **kwargs) @@ -765,6 +848,16 @@ class BarcodeScanResultMixin: """Return the queryset for the BarcodeScan API.""" queryset = super().get_queryset() + try: + user = self.request.user + except AttributeError: + raise PermissionDenied('User information is not available') + + # Allow staff users access to all BarcodeScanResult objects + if not user.is_staff: + # All other users are limited to viewing their own barcode scan history + queryset = queryset.filter(user=user) + # Pre-fetch user data queryset = queryset.prefetch_related('user') @@ -787,11 +880,11 @@ class BarcodeScanResultList(BarcodeScanResultMixin, BulkDeleteMixin, ListAPI): filterset_class = BarcodeScanResultFilter filter_backends = SEARCH_ORDER_FILTER - ordering_fields = ['user', 'plugin', 'timestamp', 'endpoint', 'result'] + ordering_fields = ['user', 'timestamp', 'endpoint', 'result'] ordering = '-timestamp' - search_fields = ['plugin'] + search_fields = ['data'] class BarcodeScanResultDetail(BarcodeScanResultMixin, RetrieveDestroyAPI): diff --git a/src/backend/InvenTree/plugin/base/barcodes/mixins.py b/src/backend/InvenTree/plugin/base/barcodes/mixins.py index c744cc04f2..298cbaeb39 100644 --- a/src/backend/InvenTree/plugin/base/barcodes/mixins.py +++ b/src/backend/InvenTree/plugin/base/barcodes/mixins.py @@ -42,7 +42,7 @@ class BarcodeMixin: """Does this plugin have everything needed to process a barcode.""" return True - def scan(self, barcode_data): + def scan(self, barcode_data: str, user, **kwargs) -> dict | None: """Scan a barcode against this plugin. This method is explicitly called from the /scan/ API endpoint, @@ -261,7 +261,7 @@ class SupplierBarcodeMixin(BarcodeMixin): 'extract_barcode_fields must be implemented by each plugin' ) - def scan(self, barcode_data: str) -> dict | None: + def scan(self, barcode_data: str, user, **kwargs) -> dict | None: """Perform a generic 'scan' operation on a supplier barcode. The supplier barcode may provide sufficient information to match against @@ -297,7 +297,7 @@ class SupplierBarcodeMixin(BarcodeMixin): for k, v in matches.items(): if v and hasattr(v, 'pk'): has_match = True - data[k] = v.format_matched_response() + data[k] = v.format_matched_response(user=user) if not has_match: return None @@ -320,7 +320,7 @@ class SupplierBarcodeMixin(BarcodeMixin): location=None, auto_allocate: bool = True, **kwargs, - ) -> dict | None: + ) -> dict: """Attempt to receive an item against a PurchaseOrder via barcode scanning. Arguments: @@ -344,38 +344,62 @@ class SupplierBarcodeMixin(BarcodeMixin): # Extract supplier information supplier = supplier or self.get_supplier(cache=True) - if not supplier: + """Construct Debug Response + This is returned if a perfect match is not found with the info provided from the barcode + + Response Info: + 'supplier': get supplier ID + 'PO': Represented for "Purchase Order", find PO number to supplier + 'supplier_part': find supplier part info to supplier + 'no_match': Boolean, did we find a perfect match with info given? False is Yes, True is No + """ + debug_response = {} + + if supplier is None: # No supplier information available - return None + debug_response['supplier'] = None + else: + debug_response['supplier'] = supplier.name # Extract purchase order information purchase_order = purchase_order or self.get_purchase_order() - if not purchase_order or purchase_order.supplier != supplier: + if purchase_order is None or purchase_order.supplier != supplier: # Purchase order does not match supplier - return None + debug_response['PO'] = None + else: + debug_response['PO'] = purchase_order.reference supplier_part = self.get_supplier_part() - if not supplier_part: + if supplier_part is None: # No supplier part information available - return None + debug_response['supplier_part'] = None + else: + debug_response['supplier_part'] = str(supplier_part.part) # Attempt to find matching line item - if not line_item: + if not line_item and purchase_order != None: line_items = purchase_order.lines.filter(part=supplier_part) if line_items.count() == 1: line_item = line_items.first() - if not line_item: - # No line item information available - return None + # If Purchase Order or Supplier Part does not exist, throw debug response + if debug_response['PO'] is None or debug_response['supplier_part'] is None: + debug_response['no_match'] = True + return debug_response + + if not line_item or not line_item.part: + return {'error': _('No matching line item found'), 'no_match': False} if line_item.part != supplier_part: - return {'error': _('Supplier part does not match line item')} + return { + 'error': _('Supplier part does not match line item'), + 'no_match': False, + } if line_item.is_completed(): - return {'error': _('Line item is already completed')} + return {'error': _('Line item is already completed'), 'no_match': False} # Extract location information for the line item location = ( @@ -406,7 +430,8 @@ class SupplierBarcodeMixin(BarcodeMixin): 'supplier_part': supplier_part.pk, 'purchase_order': purchase_order.pk, 'location': location.pk if location else None, - } + }, + 'no_match': False, } if action_required: diff --git a/src/backend/InvenTree/plugin/base/barcodes/test_barcode.py b/src/backend/InvenTree/plugin/base/barcodes/test_barcode.py index cec6fc68ad..ef2e69d97d 100644 --- a/src/backend/InvenTree/plugin/base/barcodes/test_barcode.py +++ b/src/backend/InvenTree/plugin/base/barcodes/test_barcode.py @@ -15,6 +15,7 @@ class BarcodeAPITest(InvenTreeAPITestCase): """Tests for barcode api.""" fixtures = ['category', 'part', 'location', 'stock'] + roles = ['stock.view', 'stock_location.view', 'part.view'] def setUp(self): """Setup for all tests.""" @@ -255,10 +256,138 @@ class BarcodeAPITest(InvenTreeAPITestCase): self.assertIn('object does not exist', str(response.data[k])) +class BarcodeScanResultAPITest(InvenTreeAPITestCase): + """Tests for the BarcodeScanResult list / detail API endpoints.""" + + def setUp(self): + """Create barcode scan results for two different users.""" + super().setUp() + + from django.contrib.auth import get_user_model + + self.other_user = get_user_model().objects.create_user( + username='otheruser', password='otherpassword', email='other@testing.com' + ) + + self.own_result = BarcodeScanResult.objects.create( + data='own-barcode', user=self.user + ) + self.other_result = BarcodeScanResult.objects.create( + data='other-barcode', user=self.other_user + ) + + def test_list_non_staff(self): + """A non-staff user can only see their own barcode scan history.""" + self.user.is_staff = False + self.user.save() + + response = self.get(reverse('api-barcode-scan-result-list'), expected_code=200) + + pks = [item['pk'] for item in response.data] + + self.assertIn(self.own_result.pk, pks) + self.assertNotIn(self.other_result.pk, pks) + + def test_list_staff(self): + """A staff user can see barcode scan history for all users.""" + self.user.is_staff = True + self.user.save() + + response = self.get(reverse('api-barcode-scan-result-list'), expected_code=200) + + pks = [item['pk'] for item in response.data] + + self.assertIn(self.own_result.pk, pks) + self.assertIn(self.other_result.pk, pks) + + def test_detail_non_staff(self): + """A non-staff user cannot retrieve another user's barcode scan result.""" + self.user.is_staff = False + self.user.save() + + self.get( + reverse( + 'api-barcode-scan-result-detail', kwargs={'pk': self.own_result.pk} + ), + expected_code=200, + ) + + self.get( + reverse( + 'api-barcode-scan-result-detail', kwargs={'pk': self.other_result.pk} + ), + expected_code=404, + ) + + def test_detail_staff(self): + """A staff user can retrieve any user's barcode scan result.""" + self.user.is_staff = True + self.user.save() + + self.get( + reverse( + 'api-barcode-scan-result-detail', kwargs={'pk': self.own_result.pk} + ), + expected_code=200, + ) + + self.get( + reverse( + 'api-barcode-scan-result-detail', kwargs={'pk': self.other_result.pk} + ), + expected_code=200, + ) + + +class POAllocateTest(InvenTreeAPITestCase): + """Unit tests for the barcode endpoint for allocating items to a purchase order.""" + + fixtures = ['category', 'company', 'part', 'location', 'stock'] + roles = ['part.view'] + + @classmethod + def setUpTestData(cls): + """Setup for all tests.""" + super().setUpTestData() + + cls.supplier = company.models.Company.objects.filter(is_supplier=True).first() + cls.purchase_order = order.models.PurchaseOrder.objects.create( + supplier=cls.supplier + ) + + def postBarcode(self, barcode, expected_code=None, **kwargs): + """Post barcode and return results.""" + data = {'barcode': barcode, **kwargs} + + response = self.post( + reverse('api-barcode-po-allocate'), data=data, expected_code=expected_code + ) + + return response.data + + def test_permission_denied(self): + """A user without the 'purchase_order.add' role cannot allocate against a PO via barcode scan.""" + response = self.postBarcode( + 'abcde', purchase_order=self.purchase_order.pk, expected_code=403 + ) + + self.assertIn('do not have the required permissions', str(response['error'])) + + # Once the role is granted, the request proceeds past the permission check + # (still fails with 400, as 'abcde' does not match any barcode plugin - + # but that is a *different* error to the permission check above) + self.assignRole('purchase_order.add') + + self.postBarcode( + 'abcde', purchase_order=self.purchase_order.pk, expected_code=400 + ) + + class SOAllocateTest(InvenTreeAPITestCase): """Unit tests for the barcode endpoint for allocating items to a sales order.""" fixtures = ['category', 'company', 'part', 'location', 'stock'] + roles = ['stock.view'] @classmethod def setUpTestData(cls): @@ -307,6 +436,36 @@ class SOAllocateTest(InvenTreeAPITestCase): return response.data + def test_permission_denied(self): + """A user without the 'sales_order.add' role cannot allocate stock via barcode scan.""" + self.clearRoles() + + response = self.post( + reverse('api-barcode-so-allocate'), + data={ + 'barcode': self.stock_item.format_barcode(), + 'sales_order': self.sales_order.pk, + }, + expected_code=403, + ) + + self.assertIn( + 'do not have the required permissions', str(response.data['error']) + ) + + # No allocation should have been created + self.assertEqual(self.line_item.allocated_quantity(), 0) + + # Restore the required roles - the request should now succeed + self.assignRole('sales_order.add') + self.assignRole('stock.view') + + self.postBarcode( + self.stock_item.format_barcode(), + sales_order=self.sales_order.pk, + expected_code=200, + ) + def test_no_data(self): """Test when no data is provided.""" result = self.postBarcode('', expected_code=400) @@ -343,10 +502,14 @@ class SOAllocateTest(InvenTreeAPITestCase): # Test with barcode which points to a *part* instance item.part.assign_barcode(barcode_data='abcde') + # missing permission for viewing the part - error + self.postBarcode('abcde', sales_order=self.sales_order.pk, expected_code=403) + + # Add part.view role and test again + self.assignRole('part.view') result = self.postBarcode( 'abcde', sales_order=self.sales_order.pk, expected_code=400 ) - self.assertIn('does not match an existing stock item', str(result['error'])) def test_submit(self): diff --git a/src/backend/InvenTree/plugin/base/event/events.py b/src/backend/InvenTree/plugin/base/event/events.py index 1a77432804..c834e02ae4 100644 --- a/src/backend/InvenTree/plugin/base/event/events.py +++ b/src/backend/InvenTree/plugin/base/event/events.py @@ -1,5 +1,9 @@ """Functions for triggering and responding to server side events.""" +import contextvars +from collections import defaultdict +from contextlib import contextmanager + from django.conf import settings from django.db import transaction from django.db.models.signals import post_delete, post_save @@ -11,13 +15,79 @@ from opentelemetry import trace import InvenTree.exceptions from common.settings import get_global_setting from InvenTree.ready import canAppAccessDatabase, isImportingData -from InvenTree.tasks import offload_task +from InvenTree.tasks import bulk_offload_task, offload_task from plugin import PluginMixinEnum from plugin.registry import registry tracer = trace.get_tracer(__name__) logger = structlog.get_logger('inventree') +# Active event batch for the current context (see batch_events()), if any +_event_batch: contextvars.ContextVar = contextvars.ContextVar( + 'event_batch', default=None +) + + +class EventBatch: + """Collects trigger_event() calls made within a batch_events() scope. + + Entries are grouped by event name, so that each distinct event triggered + within the batch is flushed via its own bulk_trigger_event() call. + """ + + def __init__(self): + """Initialize an empty batch.""" + self.entries: dict[str, list] = defaultdict(list) + + def add(self, event: str, *args, **kwargs) -> None: + """Record a single trigger_event() call against this batch.""" + self.entries[event].append((args, kwargs)) + + def flush(self) -> None: + """Fire a bulk_trigger_event() call for each event name collected so far.""" + entries, self.entries = self.entries, defaultdict(list) + + for event, event_entries in entries.items(): + bulk_trigger_event(event, event_entries) + + +@contextmanager +def batch_events(): + """Batch trigger_event() calls made within this scope into bulk_trigger_event() calls. + + Any trigger_event() call made (directly, or indirectly via a nested function call) + while this context is active is queued instead of immediately offloaded. The queued + events are flushed - grouped by event name, one bulk_trigger_event() call per name - + when the current database transaction commits (or immediately, if no transaction is + active). If the transaction is instead rolled back, the queued events are discarded, + rather than being fired for a write that never happened. + + Nesting is not supported: a nested batch_events() call reuses the outer batch, and + only the outermost call schedules a flush. + + This does not change the behavior of code that triggers events *outside* of this + context - trigger_event() still fires immediately in that case. This allows existing + single-item entrypoints (e.g. StockItem.stocktake()) to be reused unmodified by both + single-item and bulk callers: bulk callers simply wrap their loop in batch_events(). + + Yields: + EventBatch: The current event batch, which can be used to add events directly. + + """ + if _event_batch.get() is not None: + # Already inside a batch - extend it, rather than creating a nested one + yield _event_batch.get() + return + + batch = EventBatch() + token = _event_batch.set(batch) + + try: + yield batch + finally: + _event_batch.reset(token) + transaction.on_commit(batch.flush) + @tracer.start_as_current_span('trigger_event') def trigger_event(event: str, *args, **kwargs) -> None: @@ -45,6 +115,11 @@ def trigger_event(event: str, *args, **kwargs) -> None: logger.debug("Ignoring triggered event '%s' - database not ready", event) return + if (batch := _event_batch.get()) is not None: + # A batch_events() context is active - queue this event rather than firing it now + batch.add(event, *args, **kwargs) + return + logger.debug("Event triggered: '%s'", event) force_async = kwargs.pop('force_async', True) @@ -58,6 +133,60 @@ def trigger_event(event: str, *args, **kwargs) -> None: offload_task(register_event, event, *args, group='plugin', **kwargs) +@tracer.start_as_current_span('bulk_trigger_event') +def bulk_trigger_event(event: str, entries: list) -> None: + """Trigger the same event multiple times, in a single bulk database write. + + Equivalent to calling trigger_event(event, *args, **kwargs) once per (args, kwargs) + pair in 'entries', but queues all of the resulting background tasks via a single + bulk_offload_task() call, rather than one INSERT per event. + + Arguments: + event: The event to trigger + entries: List of (args, kwargs) tuples, one per event instance to register + + These events will be stored in the database, and the worker will respond to them later on. + """ + if not entries: + return + + if not get_global_setting('ENABLE_PLUGINS_EVENTS', False): + # Do nothing if plugin events are not enabled + return + + # Ensure event name is stringified + event = str(event).strip() + + # Make sure the database can be accessed and is not being tested rn + if ( + not canAppAccessDatabase(allow_shell=True) + and not settings.PLUGIN_TESTING_EVENTS + ): + logger.debug("Ignoring bulk triggered event '%s' - database not ready", event) + return + + logger.debug("Bulk event triggered: '%s' (%s entries)", event, len(entries)) + + force_async = True + + # If we are running in testing mode, we can enable or disable async processing + if settings.PLUGIN_TESTING_EVENTS: + force_async = settings.PLUGIN_TESTING_EVENTS_ASYNC + + task_entries = [] + + for args, kwargs in entries: + kwargs = dict(kwargs) + # 'force_async' is a bulk_offload_task() control flag, not event data - it is + # resolved once for the whole batch above, so strip any per-entry override + kwargs.pop('force_async', None) + task_entries.append(((event, *args), kwargs)) + + bulk_offload_task( + register_event, task_entries, group='plugin', force_async=force_async + ) + + @tracer.start_as_current_span('register_event') def register_event(event, *args, **kwargs): """Register the event with any interested plugins. diff --git a/src/backend/InvenTree/plugin/base/event/test_events.py b/src/backend/InvenTree/plugin/base/event/test_events.py new file mode 100644 index 0000000000..77c5c5f998 --- /dev/null +++ b/src/backend/InvenTree/plugin/base/event/test_events.py @@ -0,0 +1,134 @@ +"""Unit tests for event triggering functions.""" + +from django.db import transaction +from django.test import TestCase + +from django_q.models import OrmQ + +from common.models import InvenTreeSetting +from plugin.base.event.events import batch_events, bulk_trigger_event, trigger_event + + +class BulkEventTriggerTests(TestCase): + """Unit tests for the bulk_trigger_event function.""" + + def test_bulk_trigger_event(self): + """Test that bulk_trigger_event queues events in a single bulk database write.""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + entries = [ + ((idx, idx + 1), {'animal': f'animal_{idx}', 'count': idx}) + for idx in range(10) + ] + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + # Start with a blank slate + OrmQ.objects.all().delete() + + # Queuing all 10 events should only take two database queries: + # one to check the 'ENABLE_PLUGINS_EVENTS' setting, and one bulk_create + with self.assertNumQueries(2): + bulk_trigger_event('test.event', entries) + + self.assertEqual(OrmQ.objects.count(), 10) + + # Read out the pending tasks, and check that the args / kwargs match + queued_tasks = OrmQ.objects.all().order_by('id') + + for task, (args, kwargs) in zip(queued_tasks, entries, strict=True): + self.assertEqual(task.func(), 'plugin.base.event.events.register_event') + self.assertEqual(task.group(), 'plugin') + self.assertEqual(task.args(), ('test.event', *args)) + self.assertEqual(task.kwargs(), kwargs) + + +class BatchEventsTests(TestCase): + """Unit tests for the batch_events() context manager.""" + + def setUp(self): + """Enable plugin events for all tests in this class.""" + super().setUp() + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + OrmQ.objects.all().delete() + + def test_events_queued_and_flushed_on_commit(self): + """Events triggered inside batch_events() are queued and flushed as one bulk write on commit.""" + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), batch_events(): + for idx in range(10): + trigger_event('test.event', id=idx, value=f'v{idx}') + + # Nothing should be queued yet - the batch only flushes on commit + self.assertEqual(OrmQ.objects.count(), 0) + + self.assertEqual(OrmQ.objects.count(), 10) + + queued_tasks = OrmQ.objects.all().order_by('id') + + for idx, task in enumerate(queued_tasks): + self.assertEqual(task.args(), ('test.event',)) + self.assertEqual(task.kwargs(), {'id': idx, 'value': f'v{idx}'}) + + def test_events_grouped_by_name(self): + """Events with different names in the same batch are flushed as separate bulk writes.""" + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), batch_events(): + for idx in range(5): + trigger_event('event.a', id=idx) + for idx in range(3): + trigger_event('event.b', id=idx) + + self.assertEqual(OrmQ.objects.count(), 8) + self.assertEqual( + sum(1 for task in OrmQ.objects.all() if task.args() == ('event.a',)), 5 + ) + self.assertEqual( + sum(1 for task in OrmQ.objects.all() if task.args() == ('event.b',)), 3 + ) + + def test_events_discarded_on_rollback(self): + """Events queued in a batch are discarded, not fired, if the transaction rolls back.""" + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + with self.captureOnCommitCallbacks(execute=True): + try: + with transaction.atomic(), batch_events(): + trigger_event('test.event', id=1) + raise ValueError('boom') + except ValueError: + pass + + self.assertEqual(OrmQ.objects.count(), 0) + + def test_events_outside_batch_fire_immediately(self): + """Events triggered outside any batch_events() context are unaffected - fired immediately.""" + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + trigger_event('test.event', id=1) + + # No transaction commit or captureOnCommitCallbacks needed - it was never queued + self.assertEqual(OrmQ.objects.count(), 1) + + def test_nested_batch_events_share_one_flush(self): + """A nested batch_events() call reuses the outer batch, rather than flushing twice.""" + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), batch_events(): + trigger_event('test.event', id=1) + with batch_events(): + trigger_event('test.event', id=2) + self.assertEqual(OrmQ.objects.count(), 0) + + self.assertEqual(OrmQ.objects.count(), 2) diff --git a/src/backend/InvenTree/plugin/base/integration/AppMixin.py b/src/backend/InvenTree/plugin/base/integration/AppMixin.py index b3690afee1..507d188ccc 100644 --- a/src/backend/InvenTree/plugin/base/integration/AppMixin.py +++ b/src/backend/InvenTree/plugin/base/integration/AppMixin.py @@ -51,7 +51,9 @@ class AppMixin: """ from common.settings import get_global_setting - if settings.PLUGIN_TESTING or get_global_setting('ENABLE_PLUGINS_APP'): + if settings.PLUGIN_TESTING or get_global_setting( + 'ENABLE_PLUGINS_APP', create=False + ): logger.info('Registering IntegrationPlugin apps') apps_changed = False diff --git a/src/backend/InvenTree/plugin/base/integration/ScheduleMixin.py b/src/backend/InvenTree/plugin/base/integration/ScheduleMixin.py index 140b0c8c84..624784f776 100644 --- a/src/backend/InvenTree/plugin/base/integration/ScheduleMixin.py +++ b/src/backend/InvenTree/plugin/base/integration/ScheduleMixin.py @@ -161,50 +161,64 @@ class ScheduleMixin: self.validate_scheduled_tasks() try: + from django.db import transaction + from django_q.models import Schedule - for key, task in self.scheduled_tasks.items(): - task_name = self.get_task_name(key) + from plugin.models import PluginConfig - obj = { - 'name': task_name, - 'schedule_type': task['schedule'], - 'minutes': task.get('minutes', None), - 'repeats': task.get('repeats', -1), - } + with transaction.atomic(): + # Lock this plugin's PluginConfig row for the duration of task + # registration. django_q's Schedule.name has no DB-level unique + # constraint, so without this lock, concurrent activation (e.g. + # multiple worker processes starting up at the same time) can + # both pass the 'does this task already exist' check below and + # each create a duplicate Schedule row for the same task name. + if config := self.plugin_config(): + PluginConfig.objects.select_for_update().get(pk=config.pk) - func_name = task['func'].strip() + for key, task in self.scheduled_tasks.items(): + task_name = self.get_task_name(key) - if '.' in func_name: - """Dotted notation indicates that we wish to run a globally defined function, from a specified Python module.""" - obj['func'] = func_name - else: - """Non-dotted notation indicates that we wish to call a 'member function' of the calling plugin. This is managed by the plugin registry itself.""" - slug = self.plugin_slug() - obj['func'] = 'plugin.registry.call_plugin_function' - obj['args'] = f"'{slug}', '{func_name}'" + obj = { + 'name': task_name, + 'schedule_type': task['schedule'], + 'minutes': task.get('minutes', None), + 'repeats': task.get('repeats', -1), + } - tasks = Schedule.objects.filter(name=task_name) + func_name = task['func'].strip() - if len(tasks) > 1: - logger.info( - "Found multiple tasks; Adding a new scheduled task '%s'", - task_name, - ) - tasks.delete() - Schedule.objects.create(**obj) - elif len(tasks) == 1: - # Scheduled task already exists - update it! - logger.info("Updating scheduled task '%s'", task_name) + if '.' in func_name: + """Dotted notation indicates that we wish to run a globally defined function, from a specified Python module.""" + obj['func'] = func_name + else: + """Non-dotted notation indicates that we wish to call a 'member function' of the calling plugin. This is managed by the plugin registry itself.""" + slug = self.plugin_slug() + obj['func'] = 'plugin.registry.call_plugin_function' + obj['args'] = f"'{slug}', '{func_name}'" - if instance := tasks.first(): - for item in obj: - setattr(instance, item, obj[item]) - instance.save() - else: - logger.info("Adding scheduled task '%s'", task_name) - # Create a new scheduled task - Schedule.objects.create(**obj) + tasks = Schedule.objects.filter(name=task_name) + + if len(tasks) > 1: + logger.info( + "Found multiple tasks; Adding a new scheduled task '%s'", + task_name, + ) + tasks.delete() + Schedule.objects.create(**obj) + elif len(tasks) == 1: + # Scheduled task already exists - update it! + logger.info("Updating scheduled task '%s'", task_name) + + if instance := tasks.first(): + for item in obj: + setattr(instance, item, obj[item]) + instance.save() + else: + logger.info("Adding scheduled task '%s'", task_name) + # Create a new scheduled task + Schedule.objects.create(**obj) except (ProgrammingError, OperationalError): # pragma: no cover # Database might not yet be ready diff --git a/src/backend/InvenTree/plugin/base/ui/tests.py b/src/backend/InvenTree/plugin/base/ui/tests.py index 0a4a94977b..f05eac0046 100644 --- a/src/backend/InvenTree/plugin/base/ui/tests.py +++ b/src/backend/InvenTree/plugin/base/ui/tests.py @@ -1,5 +1,8 @@ """Unit tests for base mixins for plugins.""" +from unittest import mock + +from django.core.exceptions import AppRegistryNotReady from django.urls import reverse from common.models import InvenTreeSetting @@ -86,6 +89,24 @@ class UserInterfaceMixinTests(InvenTreeAPITestCase): response = self.get(url) self.assertEqual(len(response.data), 3) + def test_ui_feature_list_app_registry_not_ready(self): + """A mid-reload AppRegistryNotReady should surface as a 503, not a 500. + + Regression test: the plugin registry can force-reload Django's app registry + (e.g. when ENABLE_PLUGINS_INTERFACE is toggled - see + common.setting.system.reload_plugin_registry) while other requests are still + being served, so this endpoint's own settings lookup can race that reload. + """ + url = reverse('api-plugin-ui-feature-list', kwargs={'feature': 'dashboard'}) + + with mock.patch( + 'plugin.base.ui.api.get_global_setting', side_effect=AppRegistryNotReady() + ): + response = self.get(url, expected_code=503) + + self.assertEqual(response.data['error'], 'AppRegistryNotReady') + self.assertEqual(response['Retry-After'], '1') + def test_ui_panels(self): """Test that the sample UI plugin provides custom panels.""" from part.models import Part diff --git a/src/backend/InvenTree/plugin/broken/broken_file.py b/src/backend/InvenTree/plugin/broken/broken_file.py index f56932e876..bf97149aef 100644 --- a/src/backend/InvenTree/plugin/broken/broken_file.py +++ b/src/backend/InvenTree/plugin/broken/broken_file.py @@ -7,4 +7,4 @@ class BrokenFileIntegrationPlugin(InvenTreePlugin): """An very broken plugin.""" -aaa = bb # noqa: F821 +aaa = bb # noqa: F821 # ty:ignore[unresolved-reference] diff --git a/src/backend/InvenTree/plugin/builtin/barcodes/inventree_barcode.py b/src/backend/InvenTree/plugin/builtin/barcodes/inventree_barcode.py index 10cf3189c8..c2f163fe8f 100644 --- a/src/backend/InvenTree/plugin/builtin/barcodes/inventree_barcode.py +++ b/src/backend/InvenTree/plugin/builtin/barcodes/inventree_barcode.py @@ -48,11 +48,11 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi }, } - def format_matched_response(self, label, model, instance): + def format_matched_response(self, label, model, instance, user, **kwargs): """Format a response for the scanned data.""" - return {label: instance.format_matched_response()} + return {label: instance.format_matched_response(user=user, **kwargs)} - def scan(self, barcode_data): + def scan(self, barcode_data, user, **kwargs): """Scan a barcode against this plugin. Here we are looking for a dict object which contains a reference to a particular InvenTree database object @@ -79,7 +79,7 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi try: instance = model.objects.get(pk=int(pk)) - return self.format_matched_response(label, model, instance) + return self.format_matched_response(label, model, instance, user=user) except (ValueError, model.DoesNotExist): pass @@ -111,7 +111,9 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi instance = model.objects.get(pk=pk) return { - **self.format_matched_response(label, model, instance), + **self.format_matched_response( + label, model, instance, user=user + ), 'success': succcess_message, } except (ValueError, model.DoesNotExist): @@ -129,7 +131,7 @@ class InvenTreeInternalBarcodePlugin(SettingsMixin, BarcodeMixin, InvenTreePlugi if instance is not None: return { - **self.format_matched_response(label, model, instance), + **self.format_matched_response(label, model, instance, user=user), 'success': succcess_message, } diff --git a/src/backend/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py b/src/backend/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py index 1dc1eb90b2..4ae09064af 100644 --- a/src/backend/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py +++ b/src/backend/InvenTree/plugin/builtin/barcodes/test_inventree_barcode.py @@ -11,6 +11,7 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase): """Tests for the integrated InvenTreeBarcode barcode plugin.""" fixtures = ['category', 'part', 'location', 'stock', 'company', 'supplier_part'] + roles = ['stock.view', 'stock_location.view', 'part.view'] def setUp(self): """Set up the test case.""" diff --git a/src/backend/InvenTree/plugin/builtin/events/auto_create_builds.py b/src/backend/InvenTree/plugin/builtin/events/auto_create_builds.py index f1667fcb98..4cd59f916a 100644 --- a/src/backend/InvenTree/plugin/builtin/events/auto_create_builds.py +++ b/src/backend/InvenTree/plugin/builtin/events/auto_create_builds.py @@ -6,6 +6,7 @@ from django.utils.translation import gettext_lazy as _ import structlog +import part.models from build.events import BuildEvents from build.models import Build from build.status_codes import BuildStatus @@ -56,7 +57,8 @@ class AutoCreateBuildsPlugin(EventMixin, InvenTreePlugin): """Process a build order when it is issued.""" # Iterate through all sub-assemblies for the build order for bom_item in build.part.get_bom_items().filter( - consumable=False, sub_part__assembly=True + part.models.BomItem.consumable_filter(consumable=False), + sub_part__assembly=True, ): subassembly = bom_item.sub_part diff --git a/src/backend/InvenTree/plugin/builtin/exporter/stocktake_exporter.py b/src/backend/InvenTree/plugin/builtin/exporter/stocktake_exporter.py index f2ffe8c66a..b03642e554 100644 --- a/src/backend/InvenTree/plugin/builtin/exporter/stocktake_exporter.py +++ b/src/backend/InvenTree/plugin/builtin/exporter/stocktake_exporter.py @@ -29,7 +29,13 @@ class PartStocktakeExportOptionsSerializer(serializers.Serializer): export_include_variant_items = serializers.BooleanField( default=False, label=_('Include Variant Items'), - help_text=_('Include part variant stock in pricing calculations'), + help_text=_('Include part variant stock in stocktake data'), + ) + + export_exclude_zero_stock_entries = serializers.BooleanField( + default=False, + label=_('Exclude Zero Stock Entries'), + help_text=_('Exclude parts with zero stock from the exported dataset'), ) @@ -43,7 +49,7 @@ class PartStocktakeExporter(DataExportMixin, InvenTreePlugin): SLUG = 'inventree-stocktake-exporter' TITLE = _('Part Stocktake Exporter') DESCRIPTION = _('Exporter for part stocktake data') - VERSION = '1.0.0' + VERSION = '1.1.1' AUTHOR = _('InvenTree contributors') ExportOptionsSerializer = PartStocktakeExportOptionsSerializer @@ -78,6 +84,9 @@ class PartStocktakeExporter(DataExportMixin, InvenTreePlugin): 'pk', 'name', 'IPN', + 'active', + 'component', + 'assembly', 'description', 'category', 'allocated_to_build_orders', @@ -124,26 +133,39 @@ class PartStocktakeExporter(DataExportMixin, InvenTreePlugin): export_pricing_data = context.get('export_pricing_data', True) include_external_items = context.get('export_include_external_items', False) include_variant_items = context.get('export_include_variant_items', False) + exclude_zero_stock = context.get('export_exclude_zero_stock_entries', False) data = super().export_data( queryset, serializer_class, headers, context, output, **kwargs ) - if export_pricing_data: - for row in data: - quantity = Decimal(row.get('total_in_stock', 0)) + output_data = [] - if not include_external_items: - quantity -= Decimal(row.get('external_stock', 0)) + for row in data: + quantity = Decimal(row.get('total_in_stock', 0)) - if not include_variant_items: - quantity -= Decimal(row.get('variant_stock', 0)) + if not include_external_items: + quantity -= Decimal(row.get('external_stock', 0)) - if quantity < 0: - quantity = Decimal(0) + if not include_variant_items: + quantity -= Decimal(row.get('variant_stock', 0)) - pricing_min = row.get('pricing_min', None) - pricing_max = row.get('pricing_max', None) + if quantity < 0: + quantity = Decimal(0) + + if exclude_zero_stock: + continue + + # Update the 'total in stock' count for this row + row['total_in_stock'] = float(quantity) + + if export_pricing_data: + pricing_min = row.get('pricing_min', None) or row.get( + 'pricing_max', None + ) + pricing_max = row.get('pricing_max', None) or row.get( + 'pricing_min', None + ) if pricing_min is not None: pricing_min = Decimal(pricing_min) @@ -157,4 +179,6 @@ class PartStocktakeExporter(DataExportMixin, InvenTreePlugin): pricing_max * quantity, rounding=10 ) - return data + output_data.append(row) + + return output_data diff --git a/src/backend/InvenTree/plugin/builtin/exporter/test_exporter.py b/src/backend/InvenTree/plugin/builtin/exporter/test_exporter.py index a22ecf2a63..cf1e9c9af8 100644 --- a/src/backend/InvenTree/plugin/builtin/exporter/test_exporter.py +++ b/src/backend/InvenTree/plugin/builtin/exporter/test_exporter.py @@ -37,7 +37,7 @@ class StocktakeExporterTest(InvenTreeAPITestCase): 'Minimum Unit Cost', 'Maximum Total Cost', ], - excluded_cols=['Active', 'External Stock', 'Variant Stock'], + excluded_cols=['External Stock', 'Variant Stock'], ) # Now, with additional parameters specific to the plugin @@ -60,7 +60,6 @@ class StocktakeExporterTest(InvenTreeAPITestCase): 'External Stock', 'Variant Stock', ], - excluded_cols=['Active'], ) # Finally, exclude pricing data entirely diff --git a/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py b/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py index 2f7d7b11ca..0b732bcb64 100644 --- a/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py +++ b/src/backend/InvenTree/plugin/builtin/integration/core_notifications.py @@ -1,5 +1,6 @@ """Core set of Notifications as a Plugin.""" +from django.conf import settings from django.contrib.auth.models import User from django.db.models import Model from django.template.loader import render_to_string @@ -52,6 +53,7 @@ class InvenTreeUINotifications(NotificationMixin, InvenTreePlugin): category=category, name=ctx.get('name'), message=ctx.get('message'), + link=ctx.get('link'), ) ) @@ -108,7 +110,11 @@ class InvenTreeEmailNotifications(NotificationMixin, SettingsMixin, InvenTreePlu if recipients: InvenTree.helpers_email.send_email( - subject, '', recipients, html_message=html_message + subject, + '', + recipients, + html_message=html_message, + force_async=not settings.TESTING, ) return True diff --git a/src/backend/InvenTree/plugin/builtin/integration/test_core_notifications.py b/src/backend/InvenTree/plugin/builtin/integration/test_core_notifications.py index fbff6bc894..bddb848745 100644 --- a/src/backend/InvenTree/plugin/builtin/integration/test_core_notifications.py +++ b/src/backend/InvenTree/plugin/builtin/integration/test_core_notifications.py @@ -44,8 +44,6 @@ class CoreNotificationTestTests(InvenTreeTestCase): # No email should be send self.assertEqual(len(mail.outbox), 0) - print('- get email plugin:') - plugin = registry.get_plugin('inventree-email-notification') self.assertIsNotNone(plugin, 'Email notification plugin should be available') diff --git a/src/backend/InvenTree/plugin/builtin/labels/inventree_machine.py b/src/backend/InvenTree/plugin/builtin/labels/inventree_machine.py index 42657d617c..2d5510b2c8 100644 --- a/src/backend/InvenTree/plugin/builtin/labels/inventree_machine.py +++ b/src/backend/InvenTree/plugin/builtin/labels/inventree_machine.py @@ -181,16 +181,17 @@ class InvenTreeLabelPlugin(LabelPrintingMixin, InvenTreePlugin): label=_('Options'), depends_on=['machine'], field_serializer='get_driver_options', + default={}, required=False, ) def get_driver_options(self, fields): """Returns the selected machines serializer.""" - _, driver = get_machine_and_driver(fields['machine']) + machine, driver = get_machine_and_driver(fields['machine']) if driver is None: return None return driver.get_printing_options_serializer( - self.context['request'], context=self.context + self.context['request'], context=self.context, machine=machine ) diff --git a/src/backend/InvenTree/plugin/builtin/labels/label_sheet.py b/src/backend/InvenTree/plugin/builtin/labels/label_sheet.py index 8d28f338b9..2db615794d 100644 --- a/src/backend/InvenTree/plugin/builtin/labels/label_sheet.py +++ b/src/backend/InvenTree/plugin/builtin/labels/label_sheet.py @@ -15,6 +15,7 @@ from common.models import DataOutput from InvenTree.helpers import str2bool from plugin import InvenTreePlugin from plugin.mixins import LabelPrintingMixin, SettingsMixin +from report.fetcher import InvenTreeURLFetcher from report.models import LabelTemplate logger = structlog.get_logger('inventree') @@ -168,7 +169,7 @@ class InvenTreeLabelSheetPlugin(LabelPrintingMixin, SettingsMixin, InvenTreePlug generated_file = ContentFile(html_data, 'labels.html') else: # Render HTML to PDF - html = weasyprint.HTML(string=html_data) + html = weasyprint.HTML(string=html_data, url_fetcher=InvenTreeURLFetcher()) document = html.render().write_pdf() generated_file = ContentFile(document, 'labels.pdf') diff --git a/src/backend/InvenTree/plugin/builtin/suppliers/test_supplier_barcodes.py b/src/backend/InvenTree/plugin/builtin/suppliers/test_supplier_barcodes.py index 5ae4a6dce7..10909ff6aa 100644 --- a/src/backend/InvenTree/plugin/builtin/suppliers/test_supplier_barcodes.py +++ b/src/backend/InvenTree/plugin/builtin/suppliers/test_supplier_barcodes.py @@ -14,6 +14,13 @@ class SupplierBarcodeTests(InvenTreeAPITestCase): """Tests barcode parsing for all suppliers.""" SCAN_URL = reverse('api-barcode-scan') + roles = [ + 'stock.view', + 'stock_location.view', + 'part.view', + 'company.view', + 'order.view', + ] @classmethod def setUpTestData(cls): @@ -176,6 +183,8 @@ class SupplierBarcodeTests(InvenTreeAPITestCase): class SupplierBarcodePOReceiveTests(InvenTreeAPITestCase): """Tests barcode scanning to receive a purchase order item.""" + roles = ['stock.view', 'stock_location.view', 'purchase_order.add'] + def setUp(self): """Create supplier part and purchase_order.""" super().setUp() @@ -248,6 +257,21 @@ class SupplierBarcodePOReceiveTests(InvenTreeAPITestCase): mouser_plugin = registry.get_plugin('mouserplugin') mouser_plugin.set_setting('SUPPLIER_ID', mouser.pk) + def test_permission_denied(self): + """A user without the 'purchase_order.add' role cannot receive stock via barcode scan.""" + url = reverse('api-barcode-po-receive') + + self.clearRoles() + + response = self.post(url, data={'barcode': DIGIKEY_BARCODE}, expected_code=403) + + self.assertIn( + 'do not have the required permissions', str(response.data['error']) + ) + + # No stock should have been received + self.assertFalse(StockItem.objects.filter(part__name='Test Part').exists()) + def test_receive(self): """Test receiving an item from a barcode.""" url = reverse('api-barcode-po-receive') @@ -428,6 +452,164 @@ class SupplierBarcodePOReceiveTests(InvenTreeAPITestCase): # Quantity should be pre-filled with the remaining quantity self.assertEqual(5, response.data['lineitem']['quantity']) + def test_receive_includes_no_match_false(self): + """Successful receive merges no_match=False from the plugin response.""" + self.purchase_order1.place_order() + url = reverse('api-barcode-po-receive') + + result = self.post(url, data={'barcode': DIGIKEY_BARCODE}, expected_code=200) + + self.assertIn('success', result.data) + self.assertIn('no_match', result.data) + self.assertFalse(result.data['no_match']) + + def test_partial_match_po_found_no_supplier_part(self): + """Barcode references a known PO but the SKU has no matching supplier part.""" + url = reverse('api-barcode-po-receive') + + # '1K72991337' matches purchase_order1 via supplier_reference; SKU is unknown + result = self.post( + url, data={'barcode': DIGIKEY_BARCODE_PO_NO_PART}, expected_code=400 + ) + + self.assertIn('error', result.data) + self.assertIn('Purchase order Found', result.data['error']) + self.assertIn('No supplier Part Match', result.data['error']) + + self.assertIn('supplier_matches', result.data) + matches = result.data['supplier_matches'] + self.assertIsNotNone(matches['purchase_order']) + # DRF's ValidationError converts None leaves to ErrorDetail('None') + self.assertEqual(str(matches['supplier_part']), 'None') + self.assertIsNotNone(matches['supplier']) + self.assertTrue(matches['no_match']) + + def test_partial_match_supplier_part_found_no_po(self): + """Barcode references a known supplier part but the PO reference has no match.""" + url = reverse('api-barcode-po-receive') + + # 'P296-LM358BIDDFRCT-ND' matches the existing supplier part; PO ref is unknown + result = self.post( + url, data={'barcode': DIGIKEY_BARCODE_PART_NO_PO}, expected_code=400 + ) + + self.assertIn('error', result.data) + self.assertIn('Supplier Part Found', result.data['error']) + self.assertIn('No Purchase Order Match', result.data['error']) + + self.assertIn('supplier_matches', result.data) + matches = result.data['supplier_matches'] + # DRF's ValidationError converts None leaves to ErrorDetail('None') + self.assertEqual(str(matches['purchase_order']), 'None') + self.assertIsNotNone(matches['supplier_part']) + self.assertIsNotNone(matches['supplier']) + self.assertTrue(matches['no_match']) + + def test_no_supplier_plugin_error(self): + """Plugins that cannot resolve a supplier are listed in no_supplier_plugin_error.""" + url = reverse('api-barcode-po-receive') + + digikey_plugin = registry.get_plugin('digikeyplugin') + original_supplier_id = digikey_plugin.get_setting('SUPPLIER_ID') + + # Use a non-existent PK so get_supplier() returns None + digikey_plugin.set_setting('SUPPLIER_ID', 99999) + if hasattr(digikey_plugin, '_supplier'): + del digikey_plugin._supplier + + try: + result = self.post( + url, data={'barcode': DIGIKEY_BARCODE}, expected_code=400 + ) + + self.assertIn('no_supplier_plugin_error', result.data) + self.assertIn('digikeyplugin', result.data['no_supplier_plugin_error']) + finally: + digikey_plugin.set_setting('SUPPLIER_ID', original_supplier_id) + if hasattr(digikey_plugin, '_supplier'): + del digikey_plugin._supplier + + def test_no_supplier_matches_when_both_missing(self): + """When neither PO nor supplier part can be resolved, no supplier_matches is set.""" + url = reverse('api-barcode-po-receive') + + # Completely unknown barcode — no PO, no part, no supplier + result = self.post( + url, data={'barcode': 'COMPLETELY-UNKNOWN-BARCODE-XYZ'}, expected_code=400 + ) + + self.assertIn('error', result.data) + self.assertNotIn('supplier_matches', result.data) + + def test_no_matching_line_item_in_po(self): + """Supplier part matches globally, but is not a line item on the resolved PO. + + Regression test: previously line_item stayed None in this case and + scan_receive_item raised an unhandled AttributeError, which was swallowed + by the calling code and surfaced as a misleading 'No plugin match' error. + """ + digikey_supplier = Company.objects.get(name='Supplier') + part = Part.objects.get(name='Test Part') + + # Supplier part matches the barcode SKU, but is not attached to purchase_order1 + SupplierPart.objects.create( + SKU='ORPHAN-SKU-NOT-ON-PO', part=part, supplier=digikey_supplier + ) + + url = reverse('api-barcode-po-receive') + result = self.post( + url, data={'barcode': DIGIKEY_BARCODE_PART_NOT_ON_PO}, expected_code=400 + ) + + self.assertEqual(result.data['error'], 'No matching line item found') + + def test_multiple_matching_line_items_in_po(self): + """Same supplier part appears on two line items of the same PO. + + line_item auto-detection requires a *unique* match; with two line items + referencing the same supplier part, it should fail cleanly instead of crashing. + """ + supplier_part = SupplierPart.objects.get(SKU='296-LM358BIDDFRCT-ND') + + # Add a second, separate line item for the same supplier part + self.purchase_order1.add_line_item( + supplier_part, 4, group=False, destination=self.loc_2 + ) + + url = reverse('api-barcode-po-receive') + result = self.post(url, data={'barcode': DIGIKEY_BARCODE}, expected_code=400) + + self.assertEqual(result.data['error'], 'No matching line item found') + + def test_explicit_line_item_missing_supplier_part(self): + """Explicitly-provided line item whose supplier part has been deleted. + + SupplierPart.part uses on_delete=SET_NULL, so a line item can end up with + part=None if its supplier part is deleted after the line item was created. + """ + digikey_supplier = Company.objects.get(name='Supplier') + part = Part.objects.get(name='Test Part') + + orphan_supplier_part = SupplierPart.objects.create( + SKU='TO-BE-DELETED', part=part, supplier=digikey_supplier + ) + line_item = self.purchase_order1.add_line_item( + orphan_supplier_part, 2, destination=self.loc_2 + ) + + orphan_supplier_part.delete() + line_item.refresh_from_db() + self.assertIsNone(line_item.part) + + url = reverse('api-barcode-po-receive') + result = self.post( + url, + data={'barcode': DIGIKEY_BARCODE, 'line_item': line_item.pk}, + expected_code=400, + ) + + self.assertEqual(result.data['error'], 'No matching line item found') + DIGIKEY_BARCODE = ( '[)>\x1e06\x1dP296-LM358BIDDFRCT-ND\x1d1PLM358BIDDFR\x1dK\x1d1K72991337\x1d' @@ -476,3 +658,25 @@ TME_QRCODE = ( ) TME_DATAMATRIX_CODE = 'PWBP-302 1PMPNWBP-302 Q1 K19361337/1' + +# DigiKey barcode: '1K72991337' matches purchase_order1 via supplier_reference, +# but 'PNONEXISTENT-SKU' has no matching supplier part in the test database. +DIGIKEY_BARCODE_PO_NO_PART = ( + '[)>\x1e06\x1dPNONEXISTENT-SKU-XXXX\x1d1PNONEXISTENT-MPN\x1dK\x1d1K72991337\x1d' + '10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK' +) + +# DigiKey barcode: 'P296-LM358BIDDFRCT-ND' matches the existing supplier part, +# but '1KBADORDER-XXXXX' matches no purchase order in the test database. +DIGIKEY_BARCODE_PART_NO_PO = ( + '[)>\x1e06\x1dP296-LM358BIDDFRCT-ND\x1d1PLM358BIDDFR\x1dK\x1d1KBADORDER-XXXXX\x1d' + '10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK' +) + +# DigiKey barcode: '1K72991337' matches purchase_order1 via supplier_reference, +# and 'PORPHAN-SKU-NOT-ON-PO' matches a real supplier part in the test database, +# but that supplier part is not attached to any line item of purchase_order1. +DIGIKEY_BARCODE_PART_NOT_ON_PO = ( + '[)>\x1e06\x1dPORPHAN-SKU-NOT-ON-PO\x1d1PORPHAN-MPN\x1dK\x1d1K72991337\x1d' + '10K85781337\x1d11K1\x1d4LPH\x1dQ10\x1d11ZPICK' +) diff --git a/src/backend/InvenTree/plugin/events.py b/src/backend/InvenTree/plugin/events.py index c4f9d8006b..a36bfb97e8 100644 --- a/src/backend/InvenTree/plugin/events.py +++ b/src/backend/InvenTree/plugin/events.py @@ -1,7 +1,13 @@ """Import helper for events.""" from generic.events import BaseEventEnum -from plugin.base.event.events import process_event, register_event, trigger_event +from plugin.base.event.events import ( + batch_events, + bulk_trigger_event, + process_event, + register_event, + trigger_event, +) class PluginEvents(BaseEventEnum): @@ -11,4 +17,11 @@ class PluginEvents(BaseEventEnum): PLUGIN_ACTIVATED = 'plugin_activated' -__all__ = ['PluginEvents', 'process_event', 'register_event', 'trigger_event'] +__all__ = [ + 'PluginEvents', + 'batch_events', + 'bulk_trigger_event', + 'process_event', + 'register_event', + 'trigger_event', +] diff --git a/src/backend/InvenTree/plugin/helpers.py b/src/backend/InvenTree/plugin/helpers.py index cd62e849f7..485f8c91b8 100644 --- a/src/backend/InvenTree/plugin/helpers.py +++ b/src/backend/InvenTree/plugin/helpers.py @@ -108,9 +108,6 @@ def handle_error(error, do_raise: bool = True, do_log: bool = True, log_name: st def get_entrypoints(): """Returns list for entrypoints for InvenTree plugins.""" - # on python before 3.12, we need to use importlib_metadata - if sys.version_info < (3, 12): - return entry_points().get('inventree_plugins', []) return entry_points(group='inventree_plugins') @@ -147,6 +144,7 @@ def get_git_log(path): datetime.datetime.fromtimestamp(commit.author_time).isoformat(), commit.message.decode().split('\n')[0], ] + repo.close() except KeyError: logger.debug('No HEAD tag found in git repo at path %s', path) except NotGitRepository: @@ -189,13 +187,11 @@ def get_modules(pkg, path=None): continue try: - if sys.version_info < (3, 12): - module = finder.find_module(name).load_module(name) - else: - spec = finder.find_spec(name) - module = module_from_spec(spec) - sys.modules[name] = module - spec.loader.exec_module(module) + spec = finder.find_spec(name, path) + module = module_from_spec(spec) + sys.modules[name] = module + spec.loader.exec_module(module) + pkg_names = getattr(module, '__all__', None) for k, v in vars(module).items(): if not k.startswith('_') and (pkg_names is None or k in pkg_names): diff --git a/src/backend/InvenTree/plugin/installer.py b/src/backend/InvenTree/plugin/installer.py index acf6584a8d..6f0dcfd6ce 100644 --- a/src/backend/InvenTree/plugin/installer.py +++ b/src/backend/InvenTree/plugin/installer.py @@ -3,8 +3,10 @@ import re import subprocess import sys +from typing import Optional from django.conf import settings +from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ @@ -17,7 +19,7 @@ from InvenTree.exceptions import log_error logger = structlog.get_logger('inventree') -def pip_command(*args): +def pip_command(*args) -> str: """Build and run a pip command using using the current python executable. Returns: The output of the pip command @@ -35,9 +37,12 @@ def pip_command(*args): logger.info('Running pip command: %s', ' '.join(command)) - return subprocess.check_output( + ret = subprocess.check_output( command, cwd=settings.BASE_DIR.parent, stderr=subprocess.STDOUT - ) + ).decode('utf-8') + if 'No module named pip' in ret: + raise ValidationError(_('Pip is not installed in the current environment')) + return ret def handle_pip_error(error, path: str) -> list: @@ -83,7 +88,7 @@ def get_install_info(packagename: str) -> dict: try: result = pip_command('show', packagename) - output = result.decode('utf-8').split('\n') + output = result.split('\n') for line in output: parts = line.split(':') @@ -117,8 +122,7 @@ def plugins_file_hash(): try: with pf.open('rb') as f: - # Note: Once we support 3.11 as a minimum, we can use hashlib.file_digest - return hashlib.sha256(f.read()).hexdigest() + return hashlib.file_digest(f, 'sha256').hexdigest() except Exception: log_error('plugins_file_hash', scope='plugins') return None @@ -158,18 +162,12 @@ def install_plugins_file(): return True -def update_plugins_file(install_name, full_package=None, version=None, remove=False): +def update_plugins_file(package_reference: str, remove: bool = False): """Add a plugin to the plugins file.""" if remove: - logger.info('Removing plugin from plugins file: %s', install_name) + logger.info('Removing plugin from plugins file: %s', package_reference) else: - logger.info('Adding plugin to plugins file: %s', install_name) - - # If a full package name is provided, use that instead - if full_package and full_package != install_name: - new_value = full_package - else: - new_value = f'{install_name}=={version}' if version else install_name + logger.info('Adding plugin to plugins file: %s', package_reference) pf = settings.PLUGIN_FILE @@ -179,7 +177,7 @@ def update_plugins_file(install_name, full_package=None, version=None, remove=Fa def compare_line(line: str): """Check if a line in the file matches the installname.""" - return re.match(rf'^{install_name}[\s=@]', line.strip()) + return re.match(rf'^{package_reference}[\s=@]', line.strip()) # First, read in existing plugin file try: @@ -206,13 +204,13 @@ def update_plugins_file(install_name, full_package=None, version=None, remove=Fa found = True if not remove: # Replace line with new install name - output.append(new_value) + output.append(package_reference) else: output.append(line) # Append plugin to file if not found and not remove: - output.append(new_value) + output.append(package_reference) # Write file back to disk try: @@ -227,13 +225,18 @@ def update_plugins_file(install_name, full_package=None, version=None, remove=Fa log_error('update_plugins_file', scope='plugins') -def install_plugin(url=None, packagename=None, user=None, version=None): +def install_plugin( + user: Optional[User] = None, + url: Optional[str] = None, + packagename: Optional[str] = None, + version: Optional[str] = None, +): """Install a plugin into the python virtual environment. Args: + user: user performing the installation packagename: Optional package name to install url: Optional URL to install from - user: Optional user performing the installation version: Optional version specifier """ if user and not user.is_superuser: @@ -245,47 +248,48 @@ def install_plugin(url=None, packagename=None, user=None, version=None): logger.info('install_plugin: %s, %s', url, packagename) # build up the command - install_name = ['install', '-U', '--disable-pip-version-check'] - - full_pkg = '' + package_ref: Optional[str] = None + index_url = None if url: - # use custom registration / VCS - if True in [ - identifier in url for identifier in ['git+https', 'hg+https', 'svn+svn'] - ]: + # VCS based install - this can just be a VCS reference + if url.startswith(('git+https://', 'hg+https://', 'svn+svn://')): # using a VCS provider - full_pkg = f'{packagename}@{url}' if packagename else url - elif url: - install_name.append('-i') - full_pkg = url + package_ref = f'{packagename}@{url}' if packagename else url + # http based index reference + elif url.startswith(('http://', 'https://')) and packagename: + package_ref = packagename + index_url = url + # Ignore url and just use default index elif packagename: - full_pkg = packagename + package_ref = packagename + else: + raise ValidationError(_('Invalid URL and no package name provided')) elif packagename: - # use pypi - full_pkg = packagename + # use default index - most often pypi + package_ref = packagename if version: - full_pkg = f'{full_pkg}=={version}' - - if not full_pkg: + package_ref = f'{packagename}=={version}' + else: raise ValidationError(_('No package name or URL provided for installation')) # Sanitize the package name for installation - if any(c in full_pkg for c in ';&|`$()'): + if any(c in package_ref for c in ';&|`$()'): raise ValidationError(_('Invalid characters in package name or URL')) - install_name.append(full_pkg) + # Execute installation via pip + cmd: list[str] = ['install', '-U', '--disable-pip-version-check'] + if index_url: + cmd += ['-i', index_url] ret = {} - - # Execute installation via pip try: - result = pip_command(*install_name) + result = pip_command(*cmd, package_ref) ret['result'] = ret['success'] = _('Installed plugin successfully') - ret['output'] = str(result, 'utf-8') + ret['output'] = result if packagename and (info := get_install_info(packagename)): if path := info.get('location'): @@ -299,7 +303,7 @@ def install_plugin(url=None, packagename=None, user=None, version=None): if version := ret.get('version'): # Save plugin to plugins file - update_plugins_file(packagename, full_package=full_pkg, version=version) + update_plugins_file(package_reference=package_ref) # Reload the plugin registry, to discover the new plugin from plugin.registry import registry @@ -389,7 +393,7 @@ def uninstall_plugin(cfg: plugin.models.PluginConfig, user=None, delete_config=T raise ValidationError(_('Plugin installation not found')) # Update the plugins file - update_plugins_file(package_name, remove=True) + update_plugins_file(package_reference=package_name, remove=True) if delete_config: logger.info('Deleting plugin configuration from database: %s', cfg.key) diff --git a/src/backend/InvenTree/plugin/models.py b/src/backend/InvenTree/plugin/models.py index bed2d80c8b..adc17d9f29 100644 --- a/src/backend/InvenTree/plugin/models.py +++ b/src/backend/InvenTree/plugin/models.py @@ -302,6 +302,43 @@ class PluginSetting(common.models.BaseInvenTreeSetting): on_delete=models.CASCADE, ) + def save(self, *args, **kwargs): + """When saving a plugin setting, enforce any config-level overrides.""" + from common.settings import plugin_setting_overrides + + if self.plugin_id and self.plugin: + overrides = plugin_setting_overrides(self.plugin.key) + if self.key in overrides: + self.value = str(overrides[self.key]) + + super().save(*args, **kwargs) + + @classmethod + def get_setting_default(cls, key, **kwargs): + """Return the default value for a plugin setting, respecting config overrides.""" + from common.settings import plugin_setting_overrides + + plugin = kwargs.get('plugin') + if plugin: + overrides = plugin_setting_overrides(plugin.key) + if key in overrides: + return overrides[key] + + return super().get_setting_default(key, **kwargs) + + @classmethod + def get_setting(cls, key, backup_value=None, **kwargs): + """Get the value of a plugin setting, respecting config overrides.""" + from common.settings import plugin_setting_overrides + + plugin = kwargs.get('plugin') + if plugin: + overrides = plugin_setting_overrides(plugin.key) + if key in overrides: + return overrides[key] + + return super().get_setting(key, backup_value=backup_value, **kwargs) + @classmethod def get_setting_definition(cls, key, **kwargs): """In the BaseInvenTreeSetting class, we have a class attribute named 'SETTINGS', which is a dict object that fully defines all the setting parameters. diff --git a/src/backend/InvenTree/plugin/plugin.py b/src/backend/InvenTree/plugin/plugin.py index 1e9518cc99..0c031b1608 100644 --- a/src/backend/InvenTree/plugin/plugin.py +++ b/src/backend/InvenTree/plugin/plugin.py @@ -7,6 +7,7 @@ import warnings from datetime import datetime from importlib.metadata import PackageNotFoundError, metadata from pathlib import Path +from sysconfig import get_path from typing import Optional from django.conf import settings @@ -517,7 +518,6 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase): return InvenTree.helpers.pui_url(f'/settings/admin/plugin/{config.pk}/') return InvenTree.helpers.pui_url('/settings/admin/plugin/') - # region package info @mark_final def _get_package_commit(self): """Get last git commit for the plugin.""" @@ -527,10 +527,9 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase): @mark_final def is_editable(cls): """Returns if the current part is editable.""" - from distutils.sysconfig import get_python_lib - pkg_name = cls.__name__.split('.')[0] - dist_info = list(Path(get_python_lib()).glob(f'{pkg_name}-*.dist-info')) + py_lib = get_path('platlib') + dist_info = list(Path(py_lib).glob(f'{pkg_name}-*.dist-info')) return bool(len(dist_info) == 1) @classmethod diff --git a/src/backend/InvenTree/plugin/registry.py b/src/backend/InvenTree/plugin/registry.py index 382a973906..6ee265a8c7 100644 --- a/src/backend/InvenTree/plugin/registry.py +++ b/src/backend/InvenTree/plugin/registry.py @@ -212,39 +212,89 @@ class PluginsRegistry: return plg - def get_plugin_config(self, slug: str, name: str | None = None): + def get_plugin_configs(self) -> Optional[dict[str, Any]]: + """Return a per-request cached mapping of {slug: PluginConfig} for all plugins. + + This is a general-purpose cache, shared by any registry method which needs to + look up (potentially many) PluginConfig instances - e.g. get_plugin_config(), + with_mixin(), calculate_plugin_hash() - so that a single request only ever + pre-fetches the full PluginConfig table once, rather than issuing a + per-plugin database query. + + Returns: + dict[str, PluginConfig]: Mapping of plugin slug to PluginConfig instance. + None if the database is not ready to be queried. + """ + # As we have already checked the registry hash, this is a valid cache key + cache_key = f'plugin_configs:{self.registry_hash}' + + configs = InvenTree.cache.get_session_cache(cache_key) + + if configs is None: + try: + # Pre-fetch the PluginConfig objects to avoid multiple database queries + from plugin.models import PluginConfig + + configs = {config.key: config for config in PluginConfig.objects.all()} + InvenTree.cache.set_session_cache(cache_key, configs) + except (ProgrammingError, OperationalError): + # The database is not ready yet + logger.warning('plugin.registry.get_plugin_configs: Database not ready') + return None + + return configs + + def get_plugin_config( + self, slug: str, name: str | None = None, configs: dict | None = None + ): """Return the matching PluginConfig instance for a given plugin. Arguments: slug: The plugin slug name: The plugin name (optional) + configs: A pre-fetched mapping of {slug: PluginConfig} to avoid multiple database queries (optional) + + Returns: + PluginConfig | None: The matching PluginConfig instance, or None if not found. """ import InvenTree.ready from plugin.models import PluginConfig - # Under certain circumstances, we want to avoid creating new PluginConfig instances in the database - can_create = ( - InvenTree.ready.canAppAccessDatabase( - allow_plugins=False, allow_shell=True, allow_test=True - ) - and not InvenTree.ready.isReadOnlyCommand() - ) + if configs is None: + configs = self.get_plugin_configs() - try: - cfg = PluginConfig.objects.filter(key=slug).first() + cfg = configs.get(slug) if configs is not None else None - if not cfg and can_create: - logger.debug( - "get_plugin_config: Creating new PluginConfig for '%s'", slug + if not cfg: + # Under certain circumstances, we want to avoid creating new PluginConfig instances in the database + can_create = ( + InvenTree.ready.canAppAccessDatabase( + allow_plugins=False, allow_shell=True, allow_test=True ) - cfg = PluginConfig.objects.create(key=slug) + and not InvenTree.ready.isReadOnlyCommand() + ) - except PluginConfig.DoesNotExist: # pragma: no cover - return None - except (IntegrityError, OperationalError, ProgrammingError): # pragma: no cover - return None + try: + cfg = PluginConfig.objects.filter(key=slug).first() - if name and cfg.name != name: + if not cfg and can_create: + logger.debug( + "get_plugin_config: Creating new PluginConfig for '%s'", slug + ) + cfg = PluginConfig.objects.create(key=slug) + + except ( + IntegrityError, + OperationalError, + ProgrammingError, + ): # pragma: no cover + return None + + if cfg is not None and configs is not None: + # Backfill the cache, so repeated lookups this request are free + configs[slug] = cfg + + if cfg and name and cfg.name != name: # Update the name if it has changed try: cfg.name = name @@ -313,25 +363,15 @@ class PluginsRegistry: active (bool, optional): Filter by 'active' status of plugin. Defaults to True. builtin (bool, optional): Filter by 'builtin' status of plugin. Defaults to None. """ - # We can store the PluginConfig objects against the session cache, - # which allows us to avoid hitting the database multiple times (per session) - # As we have already checked the registry hash, this is a valid cache key - cache_key = f'plugin_configs:{self.registry_hash}' + # Pre-fetch (and cache) the PluginConfig objects, to avoid hitting the + # database multiple times (per plugin) below - configs = InvenTree.cache.get_session_cache(cache_key) + configs = self.get_plugin_configs() - if not configs: - try: - # Pre-fetch the PluginConfig objects to avoid multiple database queries - from plugin.models import PluginConfig - - plugin_configs = PluginConfig.objects.all() - configs = {config.key: config for config in plugin_configs} - InvenTree.cache.set_session_cache(cache_key, configs) - except (ProgrammingError, OperationalError): - # The database is not ready yet - logger.warning('plugin.registry.with_mixin: Database not ready') - return [] + if configs is None: + # The database is not ready yet + logger.warning('plugin.registry.with_mixin: Database not ready') + return [] mixin = str(mixin).lower().strip() @@ -344,7 +384,7 @@ class PluginsRegistry: except MixinNotImplementedError: continue - config = configs.get(plugin.slug) or plugin.plugin_config() + config = self.get_plugin_config(plugin.slug, configs=configs) # No config - cannot use this plugin if not config: @@ -585,15 +625,9 @@ class PluginsRegistry: # Gather Modules if parent_path: - # On python 3.12 use new loader method - if sys.version_info < (3, 12): - raw_module = _load_source( - plugin_dir, str(parent_obj.joinpath('__init__.py')) - ) - else: - raw_module = SourceFileLoader( - plugin_dir, str(parent_obj.joinpath('__init__.py')) - ).load_module() + raw_module = SourceFileLoader( + plugin_dir, str(parent_obj.joinpath('__init__.py')) + ).load_module() else: raw_module = importlib.import_module(plugin_dir) @@ -683,6 +717,11 @@ class PluginsRegistry: if plg_key in configs: plg_db = configs[plg_key] + + # Handle edge case where PluginConfig has been created without a valid name + if plg_name and plg_db and plg_db.name != plg_name: + plg_db.name = plg_name + plg_db.save() else: plg_db = self.get_plugin_config(plg_key, plg_name) @@ -1026,12 +1065,23 @@ class PluginsRegistry: data = md5() + # Pre-fetch (and cache) the PluginConfig objects, to avoid hitting the + # database once per plugin below + configs = self.get_plugin_configs() or {} + # Hash for all loaded plugins - for slug, plug in self.plugins.items(): + # Note: Sort by slug, so the hash is independent of discovery order. + # Different processes can discover the same plugins in a different + # order, and the hash must represent the registry *state*, not the + # iteration order of any particular process. + for slug, plug in sorted(self.plugins.items(), key=lambda item: item[0]): data.update(str(slug).encode()) data.update(str(plug.name).encode()) data.update(str(plug.version).encode()) - data.update(str(plug.is_active()).encode()) + + config = configs.get(slug) or self.get_plugin_config(slug) + active = config.is_active() if config else False + data.update(str(active).encode()) for k in self.plugin_settings_keys(): try: diff --git a/src/backend/InvenTree/plugin/samples/integration/test_scheduled_task.py b/src/backend/InvenTree/plugin/samples/integration/test_scheduled_task.py index edf428f0f1..3252931771 100644 --- a/src/backend/InvenTree/plugin/samples/integration/test_scheduled_task.py +++ b/src/backend/InvenTree/plugin/samples/integration/test_scheduled_task.py @@ -1,6 +1,11 @@ """Unit tests for scheduled tasks.""" -from django.test import TestCase +import threading +from unittest import mock + +from django.db import connection +from django.db.models.query import QuerySet +from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature from plugin import InvenTreePlugin from plugin.helpers import MixinImplementationError @@ -92,6 +97,84 @@ class ExampleScheduledTaskPluginTests(TestCase): call_plugin_function('does_not_exist', 'member_func'), None +@skipUnlessDBFeature('has_select_for_update') +class ScheduleMixinConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for ScheduleMixin.register_tasks(). + + django_q's Schedule.name has no DB-level unique constraint, so two concurrent activation passes (e.g. multiple + worker processes starting up together) could both find zero matching Schedule + rows for a task and both create one - leaving a duplicate scheduled task that + then fires twice per interval. + + register_tasks() now locks the plugin's PluginConfig row (select_for_update) + for the duration of task registration, so only one of two concurrent calls may + proceed through the check-then-write at a time. + + This relies on genuine database-level row locking, which SQLite does not + provide - select_for_update() is silently a no-op there (Django's sqlite + backend reports has_select_for_update=False), so both threads can race + through the check-then-write and a "database is locked" error from one + thread can roll back an otherwise-successful transaction, making the test + flaky under sqlite for reasons unrelated to the code under test. Only run + it against backends where the lock is real (e.g. postgres, mysql). + """ + + def test_concurrent_register_tasks_does_not_duplicate(self): + """Two concurrent register_tasks() calls for the same plugin must not create duplicate Schedule rows.""" + from django_q.models import Schedule + + plg = registry.plugins['schedule'] + self.assertTrue(plg) + + # Warm the plugin-config cache in the main thread first, so the race + # window below only covers register_tasks() itself, not the (variable + # latency) first-time cache population that plugin_config() may trigger + self.assertIsNotNone(plg.plugin_config()) + + # Start from a clean slate + Schedule.objects.filter(name__istartswith='plugin.schedule.').delete() + + start_barrier = threading.Barrier(2, timeout=15) + errors = [] + + # Wrap select_for_update() so both threads reach the (real, database-level) + # PluginConfig row lock at the same time - one wins the lock and proceeds + # through its full check-then-write, the other blocks until the winner's + # transaction completes. + original_select_for_update = QuerySet.select_for_update + + def synced_select_for_update(self_qs, *args, **kwargs): + start_barrier.wait(timeout=15) + return original_select_for_update(self_qs, *args, **kwargs) + + def run(): + try: + plg.register_tasks() + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + thread_a = threading.Thread(target=run) + thread_b = threading.Thread(target=run) + + with mock.patch.object(QuerySet, 'select_for_update', synced_select_for_update): + thread_a.start() + thread_b.start() + thread_a.join(timeout=10) + thread_b.join(timeout=10) + + self.assertEqual(errors, []) + + # Exactly one Schedule row per task, not two + for task_name in plg.get_task_names(): + self.assertEqual( + Schedule.objects.filter(name=task_name).count(), + 1, + f'Duplicate Schedule row created for {task_name}', + ) + + class ScheduledTaskPluginTests(TestCase): """Tests for ScheduledTaskPluginTests mixin base.""" diff --git a/src/backend/InvenTree/plugin/samples/integration/transition.py b/src/backend/InvenTree/plugin/samples/integration/transition.py index 6ebd3c4930..8cc79ebc62 100644 --- a/src/backend/InvenTree/plugin/samples/integration/transition.py +++ b/src/backend/InvenTree/plugin/samples/integration/transition.py @@ -37,7 +37,7 @@ class SampleTransitionPlugin(TransitionMixin, InvenTreePlugin): msg = 'Return order without responsible owner can not be completed!' # Trigger whoever created the return order - instance.created_by + trigger_notification( instance, 'sampel_123_456', @@ -46,7 +46,12 @@ class SampleTransitionPlugin(TransitionMixin, InvenTreePlugin): ) raise ValidationError(msg) - + if ( + instance.responsible + and instance.responsible.owner.username == 'testuser' + ): + # If the responsible user is "testuser", we will stop the transition + return '123#abc!' return False # Do not act TRANSITION_HANDLERS = [ReturnChangeHandler()] diff --git a/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py b/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py index 4ea7d761b8..4500da8c7c 100644 --- a/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py +++ b/src/backend/InvenTree/plugin/samples/supplier/supplier_sample.py @@ -66,7 +66,7 @@ class SampleSupplierPlugin(SupplierMixin, InvenTreePlugin): name=p['name'], description=p['description'], exact=p['sku'] == term, - price=f'{p["price"][1][0]:.2f}€', + price=f'{p["price"][1][0]:.2f}€', # ty:ignore[not-subscriptable] link=p['link'], image_url=p['image_url'], existing_part=getattr( diff --git a/src/backend/InvenTree/plugin/serializers.py b/src/backend/InvenTree/plugin/serializers.py index b12d0d3590..1b77b6063f 100644 --- a/src/backend/InvenTree/plugin/serializers.py +++ b/src/backend/InvenTree/plugin/serializers.py @@ -283,10 +283,23 @@ class PluginSettingSerializer(GenericReferencedSettingSerializer): """Serializer for the PluginSetting model.""" MODEL = PluginSetting - EXTRA_FIELDS = ['plugin'] + EXTRA_FIELDS = ['plugin', 'read_only'] plugin = serializers.CharField(source='plugin.key', read_only=True) + read_only = serializers.SerializerMethodField( + read_only=True, + help_text=_('Indicates if the setting is overridden by configuration'), + label=_('Override'), + ) + + def get_read_only(self, obj) -> bool: + """Return True if this plugin setting is locked by configuration.""" + from common.settings import plugin_setting_overrides + + overrides = plugin_setting_overrides(obj.plugin.key) + return obj.key in overrides + class PluginUserSettingSerializer(GenericReferencedSettingSerializer): """Serializer for the PluginUserSetting model.""" diff --git a/src/backend/InvenTree/plugin/test_api.py b/src/backend/InvenTree/plugin/test_api.py index 820c5c96fa..4b37cc8c98 100644 --- a/src/backend/InvenTree/plugin/test_api.py +++ b/src/backend/InvenTree/plugin/test_api.py @@ -7,7 +7,7 @@ from rest_framework.exceptions import NotFound from InvenTree.unit_test import InvenTreeAPITestCase, PluginMixin from plugin.api import check_plugin -from plugin.models import PluginConfig +from plugin.models import PluginConfig, PluginSetting class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase): @@ -126,6 +126,15 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase): ).data self.assertEqual(data['success'], 'Installed plugin successfully') + # valid (kindoff) - Pypi and nonsense uri + data = self.post( + url, + {'confirm': True, 'packagename': self.PKG_NAME, 'url': 'lol://example.com'}, + expected_code=201, + max_query_time=30, + max_query_count=450, + ).data + # invalid tries # no input data = self.post(url, {}, expected_code=400).data @@ -672,3 +681,192 @@ class PluginFullAPITest(PluginMixin, InvenTreeAPITestCase): # Successful uninstallation with self.assertRaises(PluginConfig.DoesNotExist): PluginConfig.objects.get(key=slug) + + +class PluginLockedSettingsTest(PluginMixin, InvenTreeAPITestCase): + """Tests for locked plugin settings (overridden via configuration). + + When a plugin setting is specified in PLUGIN_SETTING_OVERRIDES: + - The API reports read_only=True for that setting + - The stored value always reflects the override, even after a PATCH attempt + - Other settings on the same plugin remain editable (read_only=False) + """ + + superuser = True + + PLUGIN_SLUG = 'sample' + + # Two settings from the sample plugin used across these tests + LOCKED_KEY = 'API_KEY' + LOCKED_VALUE = 'locked-api-key-value' + + LOCKED_NUMERIC_KEY = 'NUMERICAL_SETTING' + LOCKED_NUMERIC_VALUE = 42 + + UNLOCKED_KEY = 'CHOICE_SETTING' + + def setUp(self): + """Activate the sample plugin and confirm it is ready.""" + super().setUp() + + from plugin.registry import registry + + registry.set_plugin_state(self.PLUGIN_SLUG, True) + + self.cfg = PluginConfig.objects.filter(key=self.PLUGIN_SLUG).first() + self.assertIsNotNone(self.cfg) + + def _setting_url(self, key): + return reverse( + 'api-plugin-setting-detail', kwargs={'plugin': self.PLUGIN_SLUG, 'key': key} + ) + + # ------------------------------------------------------------------ + # Helper that supplies the override context for all locked-setting tests + # ------------------------------------------------------------------ + def _overrides(self): + return { + self.PLUGIN_SLUG: { + self.LOCKED_KEY: self.LOCKED_VALUE, + self.LOCKED_NUMERIC_KEY: self.LOCKED_NUMERIC_VALUE, + } + } + + def test_locked_setting_read_only_flag(self): + """Locked settings must be reported as read_only=True via the API.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + response = self.get(self._setting_url(self.LOCKED_KEY), expected_code=200) + self.assertTrue(response.data['read_only']) + + def test_unlocked_setting_not_read_only(self): + """Settings that are NOT overridden must be reported as read_only=False.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + response = self.get(self._setting_url(self.UNLOCKED_KEY), expected_code=200) + self.assertFalse(response.data['read_only']) + + def test_locked_setting_returns_override_value(self): + """GET on a locked setting must return the configured override value.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + response = self.get(self._setting_url(self.LOCKED_KEY), expected_code=200) + self.assertEqual(response.data['value'], self.LOCKED_VALUE) + + def test_locked_setting_model_get(self): + """PluginSetting.get_setting() must return the override value directly.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + value = PluginSetting.get_setting(self.LOCKED_KEY, plugin=self.cfg) + self.assertEqual(value, self.LOCKED_VALUE) + + numeric = PluginSetting.get_setting( + self.LOCKED_NUMERIC_KEY, plugin=self.cfg + ) + self.assertEqual(numeric, self.LOCKED_NUMERIC_VALUE) + + def test_locked_setting_patch_ignored(self): + """PATCH to a locked setting must not change the value; override is re-applied.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + response = self.patch( + self._setting_url(self.LOCKED_KEY), + {'value': 'attacker-supplied-value'}, + expected_code=200, + ) + # The response value must reflect the override, not the submitted value + self.assertEqual(response.data['value'], self.LOCKED_VALUE) + + # Confirm persistence: a subsequent GET also returns the locked value + response = self.get(self._setting_url(self.LOCKED_KEY), expected_code=200) + self.assertEqual(response.data['value'], self.LOCKED_VALUE) + + def test_locked_numeric_setting_patch_ignored(self): + """PATCH to a locked numeric setting must not change the value.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + response = self.patch( + self._setting_url(self.LOCKED_NUMERIC_KEY), + {'value': 999}, + expected_code=200, + ) + self.assertEqual(int(response.data['value']), self.LOCKED_NUMERIC_VALUE) + + def test_unlocked_setting_can_be_changed(self): + """Settings not in the override dict must still be freely editable.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + # Set an initial known value + self.patch( + self._setting_url(self.UNLOCKED_KEY), {'value': 'A'}, expected_code=200 + ) + response = self.get(self._setting_url(self.UNLOCKED_KEY), expected_code=200) + self.assertEqual(response.data['value'], 'A') + + # Change it again to confirm mutability + self.patch( + self._setting_url(self.UNLOCKED_KEY), {'value': 'B'}, expected_code=200 + ) + response = self.get(self._setting_url(self.UNLOCKED_KEY), expected_code=200) + self.assertEqual(response.data['value'], 'B') + + def test_locked_setting_model_save_enforced(self): + """Saving a PluginSetting instance directly must enforce the override value.""" + with self.settings(PLUGIN_SETTING_OVERRIDES=self._overrides()): + # Retrieve (or create) the DB object and try to write a different value + obj = PluginSetting.get_setting_object(self.LOCKED_KEY, plugin=self.cfg) + self.assertIsNotNone(obj) + + obj.value = 'should-be-overwritten' + obj.save() + + # Re-fetch from DB to confirm the override was enforced + obj.refresh_from_db() + self.assertEqual(obj.value, self.LOCKED_VALUE) + + def test_no_overrides_settings_are_editable(self): + """Without any PLUGIN_SETTING_OVERRIDES, all settings default to read_only=False.""" + with self.settings(PLUGIN_SETTING_OVERRIDES={}): + for key in [self.LOCKED_KEY, self.LOCKED_NUMERIC_KEY, self.UNLOCKED_KEY]: + response = self.get(self._setting_url(key), expected_code=200) + self.assertFalse( + response.data['read_only'], msg=f'{key} should not be read_only' + ) + + +class PluginUnauthenticatedAccessTest(PluginMixin, InvenTreeAPITestCase): + """Ensure plugin API endpoints reject unauthenticated requests. + + Tests the four endpoints hardened on the permissions-fix branch: + - PluginDetail (api-plugin-detail) + - PluginSettingList (api-plugin-setting-list) + - PluginAllSettingList (api-plugin-settings) + - PluginSettingDetail (api-plugin-setting-detail) + """ + + superuser = True + PLUGIN_SLUG = 'sample' + SETTING_KEY = 'API_KEY' + + def setUp(self): + """Activate sample plugin, then log out to simulate an anonymous client.""" + super().setUp() + from plugin.registry import registry + + registry.set_plugin_state(self.PLUGIN_SLUG, True) + self.client.logout() + + def test_plugin_detail_unauthenticated(self): + """GET /api/plugins// must return 401 for unauthenticated users.""" + url = reverse('api-plugin-detail', kwargs={'plugin': self.PLUGIN_SLUG}) + self.get(url, expected_code=401) + + def test_plugin_setting_list_unauthenticated(self): + """GET /api/plugins/settings/ must return 401 for unauthenticated users.""" + self.get(reverse('api-plugin-setting-list'), expected_code=401) + + def test_plugin_all_settings_unauthenticated(self): + """GET /api/plugins//settings/ must return 401 for unauthenticated users.""" + url = reverse('api-plugin-settings', kwargs={'plugin': self.PLUGIN_SLUG}) + self.get(url, expected_code=401) + + def test_plugin_setting_detail_unauthenticated(self): + """GET /api/plugins//settings// must return 401 for unauthenticated users.""" + url = reverse( + 'api-plugin-setting-detail', + kwargs={'plugin': self.PLUGIN_SLUG, 'key': self.SETTING_KEY}, + ) + self.get(url, expected_code=401) diff --git a/src/backend/InvenTree/plugin/test_plugin.py b/src/backend/InvenTree/plugin/test_plugin.py index c918eadc3d..e4fb3ad27d 100644 --- a/src/backend/InvenTree/plugin/test_plugin.py +++ b/src/backend/InvenTree/plugin/test_plugin.py @@ -538,6 +538,30 @@ class RegistryTests(TestQueryMixin, PluginRegistryMixin, TestCase): registry.registry_hash = 'abc' self.assertTrue(registry.check_reload()) + def test_registry_hash_order_independence(self): + """Test that the registry hash does not depend on plugin iteration order. + + Different processes (gunicorn workers, background worker, shell) can + discover the same set of plugins in a different order. If the hash + depends on iteration order, processes disagree about the hash for the + same registry state, and ping-pong each other into endless reloads + via check_reload. + """ + original_plugins = registry.plugins + + # Reversing a dict with fewer than 2 entries would not change anything + self.assertGreater(len(original_plugins), 1) + + try: + hash_original = registry.calculate_plugin_hash() + + # Simulate a process which discovered the same plugins in reverse order + registry.plugins = dict(reversed(list(original_plugins.items()))) + + self.assertEqual(hash_original, registry.calculate_plugin_hash()) + finally: + registry.plugins = original_plugins + def test_builtin_mandatory_plugins(self): """Test that mandatory builtin plugins are always loaded.""" from plugin.models import PluginConfig diff --git a/src/backend/InvenTree/plugin/testing/label_machines.py b/src/backend/InvenTree/plugin/testing/label_machines.py index 084e0519d0..54967d87a7 100644 --- a/src/backend/InvenTree/plugin/testing/label_machines.py +++ b/src/backend/InvenTree/plugin/testing/label_machines.py @@ -1,6 +1,7 @@ """Plugins for testing label machines.""" import structlog +from rest_framework import serializers from machine.machine_type import BaseDriver from plugin import InvenTreePlugin @@ -46,6 +47,52 @@ class TestingLabelPrinterDriver(LabelPrinterBaseDriver): return x * y +class TestingLabelPrinterDriverOptions(LabelPrinterBaseDriver): + """Test driver for label printing.""" + + SLUG = 'test-label-printer-options' + NAME = 'Test label printer options' + DESCRIPTION = 'This is a test label printer driver for testing.' + + MACHINE_SETTINGS = { + 'LABEL': { + 'name': 'Label Media', + 'description': 'Select label media type', + 'choices': [('12', '12mm'), ('18', '18mm'), ('24', '24mm')], + 'default': '12', + 'required': True, + } + } + + def print_label(self, machine, label, item, **kwargs) -> None: + """Override print_label.""" + # Simply output some warning messages, + # which we can check for in the unit test + logger.warn('Printing Label: TestingLabelPrinterDriverOptions') + logger.warn(f'machine: {machine.pk}') + logger.warn(f'label: {label.pk}') + logger.warn(f'item: {item.pk}') + + for k, v in kwargs['printing_options'].items(): + logger.warn(f'options: {k}: {v}') + + class PrintingOptionsSerializer(LabelPrinterBaseDriver.PrintingOptionsSerializer): + """Printing options serializer for print driver testing.""" + + def __init__(self, machine=None, *args, **kwargs): + """Initialize the printing options serializer.""" + super().__init__(*args, **kwargs) + + self.fields['label'].default = machine.get_setting('LABEL', 'D') + + label = serializers.ChoiceField( + label='Label Media', + help_text='Select label media type', + choices=[('12', '12mm'), ('18', '18mm'), ('24', '24mm')], + default='12', + ) + + class TestingLabelPrinterDriverError1(LabelPrinterBaseDriver): """Test driver for label printing.""" @@ -93,6 +140,7 @@ class LabelPrinterMachineTest(MachineDriverMixin, SettingsMixin, InvenTreePlugin """Return a list of drivers registered by this plugin.""" return [ TestingLabelPrinterDriver, + TestingLabelPrinterDriverOptions, TestingLabelPrinterDriverError1, TestingLabelPrinterDriverError2, TestingLabelPrinterDriverNotImplemented, diff --git a/src/backend/InvenTree/report/api.py b/src/backend/InvenTree/report/api.py index 9e62735c10..a62d2b7a98 100644 --- a/src/backend/InvenTree/report/api.py +++ b/src/backend/InvenTree/report/api.py @@ -7,8 +7,8 @@ from django.utils.translation import gettext_lazy as _ from django.views.decorators.cache import never_cache import django_filters.rest_framework.filters as rest_filters -from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework.filterset import FilterSet +from rest_framework.exceptions import PermissionDenied from rest_framework.generics import GenericAPIView from rest_framework.response import Response @@ -16,9 +16,11 @@ import InvenTree.permissions import report.helpers import report.models import report.serializers +import users.permissions from common.models import DataOutput from common.serializers import DataOutputSerializer -from InvenTree.filters import InvenTreeSearchFilter +from InvenTree.api import meta_path +from InvenTree.filters import SEARCH_ORDER_FILTER from InvenTree.mixins import ListCreateAPI, RetrieveUpdateDestroyAPI from plugin import PluginMixinEnum from plugin.builtin.labels.inventree_label import InvenTreeLabelPlugin @@ -78,7 +80,7 @@ class ReportFilter(ReportFilterBase): """Filter options.""" model = report.models.ReportTemplate - fields = ['landscape'] + fields = ['landscape', 'merge', 'attach_to_model', 'enabled', 'model_type'] class LabelFilter(ReportFilterBase): @@ -88,7 +90,7 @@ class LabelFilter(ReportFilterBase): """Filter options.""" model = report.models.LabelTemplate - fields = [] + fields = ['enabled'] class LabelPrint(GenericAPIView): @@ -160,6 +162,14 @@ class LabelPrint(GenericAPIView): template = serializer.validated_data['template'] + model_class = template.get_model() + if model_class and not users.permissions.check_user_permission( + request.user, model_class, 'view' + ): + raise PermissionDenied( + _('You do not have permission to view this model type') + ) + if template.width <= 0 or template.height <= 0: raise ValidationError({'template': _('Invalid label dimensions')}) @@ -173,7 +183,7 @@ class LabelPrint(GenericAPIView): plugin = self.get_plugin_class(plugin_key, raise_error=True) - instances = template.get_model().objects.filter(pk__in=items) + instances = model_class.objects.filter(pk__in=items) # Sort the instances by the order of the provided items instances = sorted(instances, key=lambda item: items.index(item.pk)) @@ -235,9 +245,9 @@ class LabelTemplateList(TemplatePermissionMixin, LabelTemplateMixin, ListCreateA """API endpoint for viewing list of LabelTemplate objects.""" filterset_class = LabelFilter - filter_backends = [DjangoFilterBackend, InvenTreeSearchFilter] + filter_backends = SEARCH_ORDER_FILTER search_fields = ['name', 'description'] - ordering_fields = ['name', 'enabled'] + ordering_fields = ['name', 'enabled', 'width', 'height'] class LabelTemplateDetail( @@ -260,9 +270,18 @@ class ReportPrint(GenericAPIView): serializer.is_valid(raise_exception=True) template = serializer.validated_data['template'] + + model_class = template.get_model() + if model_class and not users.permissions.check_user_permission( + request.user, model_class, 'view' + ): + raise PermissionDenied( + _('You do not have permission to view this model type') + ) + items = serializer.validated_data['items'] - instances = template.get_model().objects.filter(pk__in=items) + instances = model_class.objects.filter(pk__in=items) # Sort the instances by the order of the provided items instances = sorted(instances, key=lambda item: items.index(item.pk)) @@ -321,7 +340,7 @@ class ReportTemplateList(TemplatePermissionMixin, ReportTemplateMixin, ListCreat """API endpoint for viewing list of ReportTemplate objects.""" filterset_class = ReportFilter - filter_backends = [DjangoFilterBackend, InvenTreeSearchFilter] + filter_backends = SEARCH_ORDER_FILTER search_fields = ['name', 'description'] ordering_fields = ['name', 'enabled'] @@ -337,6 +356,8 @@ class ReportSnippetList(TemplatePermissionMixin, ListCreateAPI): queryset = report.models.ReportSnippet.objects.all() serializer_class = report.serializers.ReportSnippetSerializer + filter_backends = SEARCH_ORDER_FILTER + search_fields = ['snippet', 'description'] class ReportSnippetDetail(TemplatePermissionMixin, RetrieveUpdateDestroyAPI): @@ -369,8 +390,14 @@ label_api_urls = [ include([ path( '/', - LabelTemplateDetail.as_view(), - name='api-label-template-detail', + include([ + meta_path(report.models.LabelTemplate), + path( + '', + LabelTemplateDetail.as_view(), + name='api-label-template-detail', + ), + ]), ), path('', LabelTemplateList.as_view(), name='api-label-template-list'), ]), @@ -386,8 +413,14 @@ report_api_urls = [ include([ path( '/', - ReportTemplateDetail.as_view(), - name='api-report-template-detail', + include([ + meta_path(report.models.ReportTemplate), + path( + '', + ReportTemplateDetail.as_view(), + name='api-report-template-detail', + ), + ]), ), path('', ReportTemplateList.as_view(), name='api-report-template-list'), ]), diff --git a/src/backend/InvenTree/report/apps.py b/src/backend/InvenTree/report/apps.py index e72ea19145..adec77df93 100644 --- a/src/backend/InvenTree/report/apps.py +++ b/src/backend/InvenTree/report/apps.py @@ -73,7 +73,9 @@ class ReportConfig(AppConfig): def cleanup(self): """Cleanup old label and report outputs.""" try: - from report.tasks import cleanup_old_report_outputs # type: ignore[import] + from report.tasks import ( + cleanup_old_report_outputs, # type: ignore[import] # ty: ignore[unresolved-import] + ) cleanup_old_report_outputs() except Exception: @@ -94,7 +96,7 @@ class ReportConfig(AppConfig): raise FileNotFoundError( 'Template file %s does not exist in %s', file_name, file ) - return ContentFile(file.open('r').read(), os.path.basename(file_name)) + return ContentFile(file.read_bytes(), os.path.basename(file_name)) def create_default_labels(self): """Create default label templates.""" diff --git a/src/backend/InvenTree/report/fetcher.py b/src/backend/InvenTree/report/fetcher.py new file mode 100644 index 0000000000..ae4bc982a4 --- /dev/null +++ b/src/backend/InvenTree/report/fetcher.py @@ -0,0 +1,69 @@ +"""WeasyPrint URL fetcher with security restrictions for report generation.""" + +from urllib.parse import urlparse + +import structlog +from weasyprint.urls import URLFetcher + +logger = structlog.get_logger('inventree') + + +class InvenTreeURLFetcher(URLFetcher): + """WeasyPrint URL fetcher restricted to safe origins.""" + + def __init__(self, **kwargs): + """Disable redirect following so a same-origin URL cannot be used for SSRF.""" + kwargs.setdefault('allow_redirects', False) + super().__init__(**kwargs) + + def fetch(self, url, headers=None): + """Validate *url* before delegating to the parent fetcher.""" + parsed = urlparse(url) + scheme = parsed.scheme.lower() + + if scheme in ('data', 'http', 'https'): + from InvenTree.helpers_model import ssrf_safe_context + + self._validate_http_url(url, parsed) + + # SSRF protection: guard the DNS resolution WeasyPrint performs internally + # when it actually opens the connection, not just the pre-check above - a + # hostname could otherwise pass validation with one IP and then be + # connected to via a different, private one moments later (DNS rebinding). + with ssrf_safe_context(): + return super().fetch(url, headers) + + if scheme == 'file': + logger.warning("InvenTreeURLFetcher: blocked file:// URL: '%s'", url) + raise ValueError( + f'file:// URLs are not permitted in report templates: {url}' + ) + + raise ValueError(f"URL scheme '{scheme}' is not permitted in report templates") + + def _validate_http_url(self, url: str, parsed) -> None: + """Raise if HTTP/HTTPS fetching is disabled or the URL is an SSRF risk.""" + from common.settings import get_global_setting + from InvenTree.helpers_model import validate_url_no_ssrf + + if not parsed.netloc: + # data: URIs — self-contained, no network access required. + return + + if not get_global_setting('REPORT_FETCH_URLS', cache=False): + logger.warning( + "InvenTreeURLFetcher: blocked URL '%s': remote fetching is disabled (REPORT_FETCH_URLS=False)", + url, + ) + raise ValueError( + f'Remote URL fetching is disabled in report templates: {url}' + ) + + try: + validate_url_no_ssrf(url) + except ValueError: + logger.warning( + "InvenTreeURLFetcher: blocked URL '%s': resolves to a private or reserved address", + url, + ) + raise diff --git a/src/backend/InvenTree/report/helpers.py b/src/backend/InvenTree/report/helpers.py index 58e3b11843..0b174fb023 100644 --- a/src/backend/InvenTree/report/helpers.py +++ b/src/backend/InvenTree/report/helpers.py @@ -3,6 +3,7 @@ import base64 import io import logging +import mimetypes from django.utils.translation import gettext_lazy as _ @@ -78,6 +79,33 @@ def report_page_size_default(): return page_size +def encode_file_base64(filename: str, data: bytes | None) -> str: + """Return a base-64 encoded data URI for raw file data. + + Unlike encode_image_base64, this preserves the original file bytes and + format as-is (no PIL decode/re-encode), so it works for any file type + (e.g. SVG logos) and does not alter the source data. + + Arguments: + filename: The filename associated with the data (used to guess the mime type) + data: The raw file data to encode + + Returns: + str -- Base64 encoded data URI e.g. 'data:image/png;base64,xxxxxxxxx', or an + empty string if no data is provided + """ + if not data: + return '' + + mime_type, _encoding = mimetypes.guess_type(str(filename)) + + if not mime_type: + mime_type = 'application/octet-stream' + + encoded = base64.b64encode(data).decode('ascii') + return f'data:{mime_type};base64,{encoded}' + + def encode_image_base64(image, img_format: str = 'PNG') -> str: """Return a base-64 encoded image which can be rendered in an tag. diff --git a/src/backend/InvenTree/report/mixins.py b/src/backend/InvenTree/report/mixins.py index d7b829ef4a..9c0d49a945 100644 --- a/src/backend/InvenTree/report/mixins.py +++ b/src/backend/InvenTree/report/mixins.py @@ -1,11 +1,45 @@ """Report mixin classes.""" -from typing import Generic, TypedDict, TypeVar +from collections.abc import Callable +from typing import Generic, Optional, TypedDict, TypeVar from django.db import models _Model = TypeVar('_Model', bound=models.Model, covariant=True) +REPORT_ATTRIBUTE_MARKER = '_report_attribute_description' + + +def report_attribute(description: Optional[str] = None) -> Callable: + """Mark a model property or method as discoverable for report documentation. + + Unlike `InvenTreeReportMixin.report_context`, which only documents context data + explicitly assembled for a particular model, this decorator can be applied to any + property or method (including those defined on mixins shared by multiple models) + to make it show up in the generated report context documentation. + + If no description is provided, the first line of the decorated function's + docstring is used instead. + + When decorating a `@property`, this decorator must be applied to the underlying + function, i.e. *below* the `@property` decorator: + + Example: + ```python + @property + @report_attribute(description="Format a minimal barcode string") + def barcode(self) -> str: + ... + ``` + """ + + def decorator(func: Callable) -> Callable: + doc = (func.__doc__ or '').strip().splitlines() + setattr(func, REPORT_ATTRIBUTE_MARKER, description or (doc[0] if doc else '')) + return func + + return decorator + class QuerySet(Generic[_Model]): """A custom QuerySet class used for type hinting in report context definitions. diff --git a/src/backend/InvenTree/report/models.py b/src/backend/InvenTree/report/models.py index cae928bdf4..2fbaf3e0bd 100644 --- a/src/backend/InvenTree/report/models.py +++ b/src/backend/InvenTree/report/models.py @@ -25,6 +25,7 @@ from pypdf import PdfWriter import InvenTree.exceptions import InvenTree.helpers import InvenTree.models +import InvenTree.ready import report.helpers import report.validators from common.models import DataOutput, RenderChoices, UpdatedUserMixin @@ -36,6 +37,8 @@ from plugin.registry import registry try: from weasyprint import HTML + + from report.fetcher import InvenTreeURLFetcher except OSError as err: # pragma: no cover print(f'OSError: {err}') print("Unable to import 'weasyprint' module.") @@ -277,7 +280,9 @@ class ReportTemplateBase( bytes: PDF data """ html = self.render_as_string(instance, context=context, **kwargs) - pdf = HTML(string=html).write_pdf(pdf_forms=True) + pdf = HTML(string=html, url_fetcher=InvenTreeURLFetcher()).write_pdf( + pdf_forms=True + ) return pdf @@ -574,10 +579,10 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): raise ValidationError(msg) except TemplateSyntaxError as e: msg = _('Template syntax error') - output.mark_failure(msg) + output.mark_failure(str(e) or msg) raise ValidationError(f'{msg}: {e!s}') except ValidationError as e: - output.mark_failure(str(e)) + output.mark_failure(','.join(e.messages)) raise e except Exception as e: msg = _('Error rendering report') @@ -613,10 +618,10 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): raise ValidationError(msg) except TemplateSyntaxError as e: msg = _('Template syntax error') - output.mark_failure(error=_('Template syntax error')) + output.mark_failure(error=str(e) or msg) raise ValidationError(f'{msg}: {e!s}') except ValidationError as e: - output.mark_failure(str(e)) + output.mark_failure(', '.join(e.messages)) raise e except Exception as e: msg = _('Error rendering report') @@ -639,6 +644,13 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): # Something went wrong during the report generation process log_report_error('ReportTemplate.print') + # If the error occurred in a worker thread, we do not want to raise an error, + # as this would cause the worker to retry the task indefinitely + if InvenTree.ready.isInWorkerThread(): + return + + # Raise a ValidationError with the error message + # This will be caught by the caller and displayed to the user raise ValidationError({ 'error': _('Error generating report'), 'detail': str(exc), @@ -673,6 +685,12 @@ class ReportTemplate(TemplateUploadMixin, ReportTemplateBase): log_report_error('ReportTemplate.print') msg = _('Error merging report outputs') output.mark_failure(error=msg) + + # If the error occurred in a worker thread, we do not want to raise an error, + # as this would cause the worker to retry the task indefinitely + if InvenTree.ready.isInWorkerThread(): + return + raise ValidationError(msg) # Save the generated report to the database diff --git a/src/backend/InvenTree/report/serializers.py b/src/backend/InvenTree/report/serializers.py index 1845724257..fbe0160823 100644 --- a/src/backend/InvenTree/report/serializers.py +++ b/src/backend/InvenTree/report/serializers.py @@ -37,9 +37,7 @@ class ReportSerializerBase(InvenTreeModelSerializer): _('User must be authenticated to save report templates') ) - instance = super().save(**kwargs) - instance.updated_by = user - instance.save(increment_revision=False) + instance = super().save(updated_by=user, **kwargs) return instance @@ -110,7 +108,7 @@ class ReportPrintSerializer(serializers.Serializer): fields = ['template', 'items'] template = serializers.PrimaryKeyRelatedField( - queryset=report.models.ReportTemplate.objects.all(), + queryset=report.models.ReportTemplate.objects.filter(enabled=True), many=False, required=True, allow_null=False, @@ -140,8 +138,18 @@ class LabelPrintSerializer(serializers.Serializer): def __init__(self, *args, **kwargs): """Override the constructor to add the extra plugin fields.""" - # Reset to a known state - self.Meta.fields = ['template', 'items', 'plugin'] + + # Give this instance its own 'Meta.fields' list, appended to below depending + # on which plugin is selected. `Meta` is otherwise a single class-level + # object shared by every instance of this serializer - mutating its 'fields' + # list in place would let concurrent requests selecting different plugins + # corrupt each other's field list. + class Meta(self.Meta): + """Per-instance metaclass options.""" + + fields = ['template', 'items', 'plugin'] + + self.Meta = Meta if plugin_serializer := kwargs.pop('plugin_serializer', None): for key, field in plugin_serializer.fields.items(): @@ -151,7 +159,7 @@ class LabelPrintSerializer(serializers.Serializer): super().__init__(*args, **kwargs) template = serializers.PrimaryKeyRelatedField( - queryset=report.models.LabelTemplate.objects.all(), + queryset=report.models.LabelTemplate.objects.filter(enabled=True), many=False, required=True, allow_null=False, diff --git a/src/backend/InvenTree/report/templatetags/barcode.py b/src/backend/InvenTree/report/templatetags/barcode.py index d6641a0abe..bc1abee247 100644 --- a/src/backend/InvenTree/report/templatetags/barcode.py +++ b/src/backend/InvenTree/report/templatetags/barcode.py @@ -1,6 +1,7 @@ """Template tags for rendering various barcodes.""" from django import template +from django.core.exceptions import ValidationError from django.utils.safestring import mark_safe import barcode as python_barcode @@ -70,7 +71,7 @@ def qrcode(data: str, **kwargs) -> str: data = str(data).strip() if not data: - raise ValueError("No data provided to 'qrcode' template tag") + raise ValidationError("qrcode: No data provided to 'qrcode' template tag") # Extract other arguments from kwargs fill_color = kwargs.pop('fill_color', 'black') @@ -115,7 +116,7 @@ def barcode(data: str, barcode_class='code128', **kwargs) -> str: data = str(data).strip() if not data: - raise ValueError("No data provided to 'barcode' template tag") + raise ValidationError("barcode: No data provided to 'barcode' template tag") constructor = python_barcode.get_barcode_class(barcode_class) @@ -134,17 +135,26 @@ def barcode(data: str, barcode_class='code128', **kwargs) -> str: @register.simple_tag() -def datamatrix(data: str, **kwargs) -> str: +def datamatrix( + data: str, + rectangular: bool = False, + fill_color: str = 'black', + back_color: str = 'white', + scale: float = 1.0, + border: int = 1, + fmt: str = 'PNG', + **kwargs, +) -> str: """Render a DataMatrix barcode. Arguments: data: Data to encode - - Keyword Arguments: - fill_color (str): Foreground color (default = 'black') - back_color (str): Background color (default = 'white') - scale (float): Matrix scaling factor (default = 1) - border (int): Border width (default = 1) + rectangular: Whether to generate a rectangular DataMatrix (default = False) + fill_color: Foreground color (default = 'black') + back_color: Background color (default = 'white') + scale: Scaling factor (default = 1) + border: Border width (default = 1) + fmt: Generated image format (default = 'PNG') Returns: image (str): base64 encoded image data @@ -154,14 +164,11 @@ def datamatrix(data: str, **kwargs) -> str: data = str(data).strip() if not data: - raise ValueError("No data provided to 'datamatrix' template tag") + raise ValidationError( + "datamatrix: No data provided to 'datamatrix' template tag" + ) - dm = DataMatrix(data) - - fill_color = kwargs.pop('fill_color', 'black') - back_color = kwargs.pop('back_color', 'white') - - border = kwargs.pop('border', 1) + dm = DataMatrix(data, rect=rectangular) try: border = int(border) @@ -180,8 +187,6 @@ def datamatrix(data: str, **kwargs) -> str: except Exception: bg = ImageColor.getcolor('white', 'RGB') - scale = kwargs.pop('scale', 1) - height = len(dm.matrix) + 2 * border width = len(dm.matrix[0]) + 2 * border @@ -193,7 +198,8 @@ def datamatrix(data: str, **kwargs) -> str: if value: img.putpixel((x + border, y + border), fg) - if scale != 1: - img = img.resize((int(width * scale), int(height * scale))) + img = img.resize( + (int(width * scale), int(height * scale)), Image.Resampling.NEAREST + ) - return image_data(img, fmt='PNG') + return image_data(img, fmt=fmt) diff --git a/src/backend/InvenTree/report/templatetags/report.py b/src/backend/InvenTree/report/templatetags/report.py index 330aa1980f..591eae7a33 100644 --- a/src/backend/InvenTree/report/templatetags/report.py +++ b/src/backend/InvenTree/report/templatetags/report.py @@ -1,6 +1,7 @@ """Custom template tags for report generation.""" import base64 +import copy import logging from datetime import date, datetime from decimal import Decimal, InvalidOperation @@ -10,14 +11,22 @@ from typing import Any, Optional from django import template from django.apps.registry import apps +from django.conf import settings from django.contrib.staticfiles.storage import staticfiles_storage from django.core.exceptions import SuspiciousFileOperation, ValidationError from django.core.files.storage import default_storage from django.db.models import Model from django.db.models.query import QuerySet +from django.utils import translation from django.utils.safestring import SafeString, mark_safe from django.utils.translation import gettext_lazy as _ +from babel import Locale +from babel.core import UnknownLocaleError +from babel.dates import format_date as babel_format_date +from babel.dates import format_datetime as babel_format_datetime +from babel.numbers import format_decimal as babel_format_decimal +from babel.numbers import parse_pattern from djmoney.contrib.exchange.exceptions import MissingRate from djmoney.contrib.exchange.models import convert_money from djmoney.money import Money @@ -39,6 +48,22 @@ register = template.Library() logger = logging.getLogger('inventree') +def get_locale(locale: Optional[str] = None) -> Locale: + """Resolve and return a babel Locale. + + Args: + locale: Optional locale string (e.g. 'en-us'). Falls back to LANGUAGE_CODE. + + Raises: + ValidationError: If the locale string is invalid. + """ + language = locale or settings.LANGUAGE_CODE + try: + return Locale.parse(translation.to_locale(language)) + except (UnknownLocaleError, ValueError) as e: + raise ValidationError(f"Invalid locale '{language}' - {e}") + + @register.simple_tag() def order_queryset(queryset: QuerySet, *args) -> QuerySet: """Order a database queryset based on the provided arguments. @@ -288,13 +313,16 @@ def asset(filename: str, raise_error: bool = False) -> str | None: else: return None - # In debug mode, return a web URL to the asset file (rather than a local file path) + # In debug mode, return a web URL to the asset file (rather than encoded data) if get_global_setting('REPORT_DEBUG_MODE', cache=False): return default_storage.url(str(full_path)) - storage_path = default_storage.path(str(full_path)) + file_data = get_media_file_contents(full_path, raise_error=raise_error) - return f'file://{storage_path}' + if not file_data: + return None + + return report.helpers.encode_file_base64(filename, file_data) @register.simple_tag() @@ -417,8 +445,13 @@ def uploaded_image( @register.simple_tag() -def encode_svg_image(filename: str) -> str: - """Return a base64-encoded svg image data string.""" +def encode_svg_image(filename: str, raise_error: bool = False) -> str: + """Return a base64-encoded svg image data string. + + Arguments: + filename: The filename of the svg image relative to the media root directory + raise_error: If True, raise an error if the file cannot be found (default = False) + """ if type(filename) is SafeString: # Prepend an empty string to enforce 'stringiness' filename = '' + filename @@ -431,7 +464,12 @@ def encode_svg_image(filename: str) -> str: # Read out the file contents # Note: This will check if the file exists, and raise an error if it does not - data = get_media_file_contents(filename) + data = get_media_file_contents(filename, raise_error=raise_error) + + # If the file is empty, return an empty string + # Note that if raise_error is True, the above function will raise a FileNotFoundError if the file does not exist + if not data: + return '' # Return the base64-encoded data return 'data:image/svg+xml;charset=utf-8;base64,' + base64.b64encode(data).decode( @@ -452,7 +490,7 @@ def part_image(part: Part, preview: bool = False, thumbnail: bool = False, **kwa TypeError: If provided part is not a Part instance """ if not part or not isinstance(part, Part): - raise TypeError(_('part_image tag requires a Part instance')) + raise ValidationError(_('part_image tag requires a Part instance')) image_filename = InvenTree.helpers.image2name(part.image, preview, thumbnail) @@ -478,28 +516,22 @@ def parameter( Returns: A Parameter object, or the provided default value if not found """ - if instance is None: - raise ValueError('parameter tag requires a valid Model instance') + if instance is None or not isinstance(instance, Model): + raise ValidationError('parameter tag requires a valid Model instance') - if not isinstance(instance, Model) or not hasattr(instance, 'parameters'): - raise TypeError("parameter tag requires a Model with 'parameters' attribute") + if not hasattr(instance, 'parameters'): + raise ValidationError( + "parameter tag requires a Model with 'parameters' attribute" + ) + + parameters = instance.parameters_list.all().prefetch_related('template') # First try with exact match - if ( - parameter := instance.parameters - .prefetch_related('template') - .filter(template__name=parameter_name) - .first() - ): + if parameter := parameters.filter(template__name=parameter_name).first(): return parameter # Next, try with case-insensitive match - if ( - parameter := instance.parameters - .prefetch_related('template') - .filter(template__name__iexact=parameter_name) - .first() - ): + if parameter := parameters.filter(template__name__iexact=parameter_name).first(): return parameter return None @@ -769,9 +801,98 @@ def modulo(x: Any, y: Any, cast: Optional[type] = None) -> Any: @register.simple_tag -def render_currency(money, **kwargs): - """Render a currency / Money object.""" - return InvenTree.helpers_model.render_currency(money, **kwargs) +def render_currency( + money: Money | str | int | float | Decimal, + decimal_places: Optional[int] = None, + currency: Optional[str] = None, + multiplier: Optional[Decimal] = None, + max_decimal_places: Optional[int] = None, + include_symbol: bool = True, + leading: Optional[int] = None, + fmt: Optional[str] = None, + locale: Optional[str] = None, + **kwargs, +) -> str: + """Render a currency / Money object to a formatted string. + + Arguments: + money: The Money instance to be rendered + currency: Optionally convert to the specified currency before rendering + multiplier: Optional multiplier to apply to the amount before rendering + decimal_places: Minimum (forced) decimal places, e.g. decimal_places=2 gives '.00'. Defaults to the locale/currency standard. + max_decimal_places: Maximum decimal places (optional digits beyond decimal_places), e.g. max_decimal_places=4 allows up to 4. + include_symbol: If True, include the currency symbol in the output + leading: Minimum number of leading digits to render before the decimal point (default = 1) + fmt: Optional Babel number pattern string. When provided, takes priority over all other formatting options. + locale: Optional locale override (e.g. 'en-us', 'de-de'). Defaults to server LANGUAGE_CODE. + """ + if money in [None, '']: + return '-' + + # If the supplied value is *not* a Money instance, attempt to convert it into one + if not isinstance(money, Money): + try: + money = Money( + Decimal(str(money)), + currency or get_global_setting('INVENTREE_DEFAULT_CURRENCY'), + ) + except Exception: + raise ValidationError(f'render_currency: invalid money value - {money!r}') + + if currency is not None: + try: + money = convert_money(money, currency) + except Exception: + pass + + if multiplier is not None: + try: + money *= Decimal(str(multiplier).strip()) + except Exception: + raise ValidationError( + f'render_currency: invalid multiplier value - {multiplier!r}' + ) + + locale = get_locale(locale) + + # If a custom fmt pattern is applied, that overrides other formatting options + if fmt: + pattern = parse_pattern(fmt) + return pattern.apply( + money.amount, + locale, + currency=money.currency.code if include_symbol else '', + currency_digits=False, + decimal_quantization=True, + ) + + pattern = copy.copy(locale.currency_formats['standard']) + + if decimal_places is None or not isinstance(decimal_places, (int, float)): + decimal_places = get_global_setting('PRICING_DECIMAL_PLACES_MIN', 0) + + if max_decimal_places is None or not isinstance(max_decimal_places, (int, float)): + max_decimal_places = get_global_setting('PRICING_DECIMAL_PLACES', 6) + + pattern.frac_prec = (decimal_places, max(decimal_places, max_decimal_places)) + + if leading is not None: + try: + leading = int(leading) or 0 + except (ValueError, TypeError): + leading = 0 + if leading > 0: + min_int, max_int = pattern.int_prec + pattern.int_prec = (max(leading, min_int), max(leading, max_int)) + + return pattern.apply( + money.amount, + locale, + currency=money.currency.code if include_symbol else '', + currency_digits=decimal_places is None and max_decimal_places is None, + decimal_quantization=decimal_places is not None + or max_decimal_places is not None, + ) @register.simple_tag @@ -868,82 +989,109 @@ def render_html_text(text: str, **kwargs): @register.simple_tag def format_number( number: int | float | Decimal, - decimal_places: Optional[int] = None, multiplier: Optional[int | float | Decimal] = None, integer: bool = False, - leading: int = 0, - separator: Optional[str] = None, + separator: bool = False, + leading: Optional[int] = None, + decimal_places: Optional[int] = None, + max_decimal_places: Optional[int] = None, + fmt: Optional[str] = None, + locale: Optional[str] = None, + **kwargs, ) -> str: """Render a number with optional formatting options. Arguments: number: The number to be formatted - decimal_places: Number of decimal places to render multiplier: Optional multiplier to apply to the number before formatting integer: Boolean, whether to render the number as an integer - leading: Number of leading zeros (default = 0) - separator: Character to use as a thousands separator (default = None) + separator: Boolean, whether to include a thousands separator + leading: Minimum number of leading digits to render (default = 1) + decimal_places: Number of decimal places to render (default = 0) + max_decimal_places: Maximum number of decimal places to render (default = 0) + separator: + fmt: Optional format string for the number - if provided, takes priority over 'decimal_places' and 'leading' + locale: Optional locale override (e.g. 'en-us', 'de-de'). When set, babel controls decimal and thousands separators. """ check_nulls('format_number', number) + # Check that the provided number is valid try: number = Decimal(str(number).strip()) except Exception: # If the number cannot be converted to a Decimal, just return the original value return str(number) + number = float(number) + if multiplier is not None: - number *= Decimal(str(multiplier).strip()) + number *= float(multiplier) if integer: - # Convert to integer - number = Decimal(int(number)) + number = int(number) - # Normalize the number (remove trailing zeroes) - number = number.normalize() + # Construct a formatting string for the number, based on the provided options + if not fmt: + fmt = '###,###,###,###,##0' # Default format string - this will be modified based on the provided options - if decimal_places is not None: - try: - decimal_places = int(decimal_places) - number = round(number, decimal_places) - except ValueError: - pass + # The 'leading' option specifies the minimum number of leading digits to render (not including decimal places) + if leading is not None: + try: + leading = int(leading) or 0 + except (ValueError, TypeError): + leading = 0 - # Re-encode, and normalize again - # Ensure that the output never uses scientific notation - value = Decimal(number) - value = ( - value.quantize(Decimal(1)) - if value == value.to_integral() - else value.normalize() + if leading > 1: + fmt = fmt[::-1].replace('#', '0', (leading - 1))[::-1] + + if not bool(separator): + fmt = fmt.replace(',', '') + + if decimal_places is not None or max_decimal_places is not None: + # Account for decimal places, if provided + + try: + decimal_places = int(decimal_places) or 0 + except (ValueError, TypeError): + decimal_places = 0 + + try: + max_decimal_places = int(max_decimal_places) or 0 + except (ValueError, TypeError): + max_decimal_places = 0 + + fmt += '.' + '0' * decimal_places + + if max_decimal_places > decimal_places: + fmt += '#' * (max_decimal_places - decimal_places) + elif not integer: + # No decimal places specified, allow any number of decimal places (up to the precision of the Decimal) + fmt += '.####################' + + babel_locale = get_locale(locale) + + return babel_format_decimal( + number, format=fmt, locale=babel_locale, numbering_system='latn' ) - if separator: - value = f'{value:,}' - value = value.replace(',', separator) - else: - value = f'{value}' - - if leading is not None: - try: - leading = int(leading) - value = '0' * leading + value - except ValueError: - pass - - return value - @register.simple_tag def format_datetime( - dt: datetime, timezone: Optional[str] = None, fmt: Optional[str] = None + dt: datetime, + timezone: Optional[str] = None, + fmt: Optional[str] = None, + locale: Optional[str] = None, + date_format: str = 'medium', + **kwargs, ): """Format a datetime object for display. Arguments: dt: The datetime object to format timezone: The timezone to use for the date (defaults to the server timezone) - fmt: The format string to use (defaults to ISO formatting) + fmt: The strftime format string to use. When provided, takes priority over locale and date_format. + locale: Optional locale override (e.g. 'en-us', 'de-de'). Used for locale-aware formatting when no fmt is given. + date_format: Babel date format style. One of 'full', 'long', 'medium' (default), 'short'. """ check_nulls('format_datetime', dt) @@ -951,18 +1099,27 @@ def format_datetime( if fmt: return dt.strftime(fmt) - else: - return dt.isoformat() + + return babel_format_datetime(dt, format=date_format, locale=get_locale(locale)) @register.simple_tag -def format_date(dt: date, timezone: Optional[str] = None, fmt: Optional[str] = None): +def format_date( + dt: date, + timezone: Optional[str] = None, + fmt: Optional[str] = None, + locale: Optional[str] = None, + date_format: str = 'medium', + **kwargs, +): """Format a date object for display. Arguments: dt: The date to format timezone: The timezone to use for the date (defaults to the server timezone) - fmt: The format string to use (defaults to ISO formatting) + fmt: The strftime format string to use. When provided, takes priority over locale and date_format. + locale: Optional locale override (e.g. 'en-us', 'de-de'). Used for locale-aware formatting when no fmt is given. + date_format: Babel date format style. One of 'full', 'long', 'medium' (default), 'short'. """ check_nulls('format_date', dt) @@ -973,8 +1130,8 @@ def format_date(dt: date, timezone: Optional[str] = None, fmt: Optional[str] = N if fmt: return dt.strftime(fmt) - else: - return dt.isoformat() + + return babel_format_date(dt, format=date_format, locale=get_locale(locale)) @register.simple_tag() diff --git a/src/backend/InvenTree/report/test_tags.py b/src/backend/InvenTree/report/test_tags.py index d8c4df23aa..f2762a8660 100644 --- a/src/backend/InvenTree/report/test_tags.py +++ b/src/backend/InvenTree/report/test_tags.py @@ -14,8 +14,9 @@ from djmoney.money import Money from PIL import Image from common.models import InvenTreeSetting, Parameter, ParameterTemplate +from common.settings import set_global_setting from InvenTree.unit_test import InvenTreeTestCase -from part.models import Part # TODO fix import: PartParameter, PartParameterTemplate +from part.models import Part from part.test_api import PartImageTestMixin from report.templatetags import barcode as barcode_tags from report.templatetags import report as report_tags @@ -88,7 +89,9 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): self.debug_mode(False) asset = report_tags.asset('test.txt') - self.assertEqual(asset, f'file://{settings.MEDIA_ROOT}/report/assets/test.txt') + # Non-debug mode returns a base64 data: URI (no file:// URLs) + self.assertIsNotNone(asset) + self.assertTrue(asset.startswith('data:text/plain;base64,')) # Test for attempted path traversal with self.assertRaises(ValidationError): @@ -182,7 +185,7 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): def test_part_image(self): """Unit tests for the 'part_image' tag.""" - with self.assertRaises(TypeError): + with self.assertRaises(ValidationError): report_tags.part_image(None) obj = Part.objects.create(name='test', description='test') @@ -225,11 +228,18 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): def test_logo_image(self): """Unit tests for the 'logo_image' tag.""" - # By default, should return the core InvenTree logo - for b in [True, False]: - self.debug_mode(b) - logo = report_tags.logo_image() - self.assertIn('inventree.png', logo) + # In debug mode, a web-accessible URL to the logo is returned + self.debug_mode(True) + logo = report_tags.logo_image() + self.assertIn('inventree.png', logo) + self.assertNotIn('file://', logo) + + # Outside of debug mode, an embeddable base64 data URI is returned instead + # of a file:// URL, which is no longer permitted in report templates + self.debug_mode(False) + logo = report_tags.logo_image() + self.assertNotIn('file://', logo) + self.assertTrue(logo.startswith('data:image/png;base64,')) def test_string_tags(self): """Simple tests for the string manipulation tags.""" @@ -357,26 +367,60 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): for x in ['10.000000', ' 10 ', 10.000000, 10]: self.assertEqual(fn(x), '10') + # Test with various formatting options self.assertEqual(fn(1234), '1234') self.assertEqual(fn(1234.5678, decimal_places=0), '1235') + self.assertEqual(fn(1234.5678, decimal_places=0, separator=True), '1,235') self.assertEqual(fn(1234.5678, decimal_places=1), '1234.6') self.assertEqual(fn(1234.5678, decimal_places=2), '1234.57') - self.assertEqual(fn(1234.5678, decimal_places=3), '1234.568') - self.assertEqual(fn(-9999.5678, decimal_places=2, separator=','), '-9,999.57') self.assertEqual( - fn(9988776655.4321, integer=True, separator=' '), '9 988 776 655' + fn(1234.5678, decimal_places=2, max_decimal_places=10), '1234.5678' ) + self.assertEqual(fn(1234.5678, decimal_places=3), '1234.568') + self.assertEqual(fn(-9999.5678, decimal_places=2, locale='fr-fr'), '-9999,57') + self.assertEqual( + fn(-9999.5678, decimal_places=2, locale='fr-fr', separator=True), + '-9\u202f999,57', + ) + self.assertEqual( + fn(9988776655.4321, integer=True, locale='de-de', separator=True), + '9.988.776.655', + ) + + # Test with 'leading' option + self.assertEqual(fn(5, leading=3), '005') + self.assertEqual(fn(123, leading=5), '00123') + self.assertEqual(fn(1234, leading=2, decimal_places=4), '1234.0000') + + # Test with custom 'fmt' format string (takes priority over decimal_places / separator) + self.assertEqual(fn(1234.5678, fmt='0.00'), '1234.57') + self.assertEqual(fn(1234.5678, fmt='#,##0.00'), '1,234.57') + self.assertEqual(fn(1234.5678, fmt='0.00', locale='de-de'), '1234,57') + self.assertEqual(fn(1234.5678, fmt='#,##0.00', locale='de-de'), '1.234,57') + # fmt bypasses decimal_places and separator options + self.assertEqual( + fn(1234.5678, fmt='0.00', decimal_places=4, separator=True), '1234.57' + ) + # integer conversion still applies before fmt is used + self.assertEqual( + fn(9988776655.4321, fmt='#,##0', integer=True), '9,988,776,655' + ) + # multiplier is applied before fmt is used + self.assertEqual(fn(100, fmt='0.00', multiplier=1.5), '150.00') # Test with multiplier self.assertEqual(fn(1000, multiplier=1.5), '1500') # Failure cases self.assertEqual(fn('abc'), 'abc') - self.assertEqual(fn(1234.456, decimal_places='a'), '1234.456') + self.assertEqual(fn(1234.456, decimal_places='a'), '1234') + self.assertEqual( + fn(1234.456, decimal_places='a', separator=True, locale='en-au'), '1,234' + ) self.assertEqual(fn(1234.456, leading='a'), '1234.456') @override_settings(TIME_ZONE='America/New_York') - def test_date_tags(self): + def test_datetime_tags(self): """Test for date formatting tags. - Source timezone is Australia/Sydney @@ -392,18 +436,20 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): tzinfo=ZoneInfo('Australia/Sydney'), ) - # Format a set of tests: timezone, format, expected + # Format a set of tests: timezone, format, locale, expected tests = [ - (None, None, '2024-03-12T21:30:00-04:00'), - (None, '%d-%m-%y', '12-03-24'), - ('UTC', None, '2024-03-13T01:30:00+00:00'), - ('UTC', '%d-%B-%Y', '13-March-2024'), - ('Europe/Amsterdam', None, '2024-03-13T02:30:00+01:00'), - ('Europe/Amsterdam', '%y-%m-%d %H:%M', '24-03-13 02:30'), + (None, None, 'en-us', 'Mar 12, 2024, 9:30:00 PM'), # noqa: RUF001 + (None, '%d-%m-%y', 'en-us', '12-03-24'), + ('UTC', None, 'en-us', 'Mar 13, 2024, 1:30:00 AM'), # noqa: RUF001 + ('UTC', '%d-%B-%Y', 'en-us', '13-March-2024'), + ('Europe/Amsterdam', None, 'de-de', '13.03.2024, 02:30:00'), + ('Europe/Amsterdam', '%y-%m-%d %H:%M', 'de-de', '24-03-13 02:30'), ] - for tz, fmt, expected in tests: - result = report_tags.format_datetime(time, tz, fmt) + for tz, fmt, locale, expected in tests: + result = report_tags.format_datetime( + time, timezone=tz, fmt=fmt, locale=locale + ) self.assertEqual(result, expected) def test_icon(self): @@ -484,6 +530,17 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): svg, ) + # Test with a missing SVG file - default behavior is to return an empty string + missing_path = 'missing_svg_image_123abc.svg' + self.assertEqual(report_tags.encode_svg_image(missing_path), '') + self.assertEqual( + report_tags.encode_svg_image(missing_path, raise_error=False), '' + ) + + # Test with a missing SVG file, with raise_error=True + with self.assertRaises(FileNotFoundError): + report_tags.encode_svg_image(missing_path, raise_error=True) + def test_part_parameter(self): """Test the part_parameter template tag.""" # Test with a valid part @@ -500,11 +557,11 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): self.assertEqual(report_tags.parameter(part, 'Template 1'), parameter) # Test with a null part - with self.assertRaises(ValueError): + with self.assertRaises(ValidationError): report_tags.parameter(None, 'name') # Test with an invalid model type - with self.assertRaises(TypeError): + with self.assertRaises(ValidationError): report_tags.parameter(parameter, 'name') def test_render_currency(self): @@ -517,21 +574,24 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): self.assertEqual(report_tags.render_currency(m, decimal_places=3), '$1,234.560') self.assertEqual( report_tags.render_currency( - Money(1234, 'USD'), currency='EUR', min_decimal_places=3 + Money(1234, 'USD'), currency='EUR', decimal_places=3 ), '$1,234.000', ) + + set_global_setting('PRICING_DECIMAL_PLACES_MIN', 2) + self.assertEqual( report_tags.render_currency( Money(1234, 'USD'), currency='EUR', max_decimal_places=1 ), - '$1,234.0', + '$1,234.00', ) # Test with non-currency values self.assertEqual( - report_tags.render_currency(1234.45, currency='USD', decimal_places=2), - '$1,234.45', + report_tags.render_currency(1234.45, currency='USD', decimal_places=5), + '$1,234.45000', ) # Test with an invalid amount @@ -542,9 +602,101 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): report_tags.render_currency(m, multiplier='quork') self.assertEqual(report_tags.render_currency(m, decimal_places='a'), exp_m) - self.assertEqual(report_tags.render_currency(m, min_decimal_places='a'), exp_m) self.assertEqual(report_tags.render_currency(m, max_decimal_places='a'), exp_m) + # Test locale override — different locales render USD differently + self.assertEqual(report_tags.render_currency(m, locale='en-us'), '$1,234.56') + self.assertEqual(report_tags.render_currency(m, locale='en-gb'), 'US$1,234.56') + self.assertEqual(report_tags.render_currency(m, locale='en-au'), 'USD1,234.56') + + # Test with custom fmt pattern + # Pattern without currency placeholder — no symbol in output + self.assertEqual(report_tags.render_currency(m, fmt='#,##0.00'), '1,234.56') + # Pattern with currency placeholder — symbol rendered per locale + self.assertEqual( + report_tags.render_currency(m, fmt='¤#,##0.0000', locale='en-us'), + '$1,234.5600', + ) + # fmt + locale: de-de uses dot thousands, comma decimal + self.assertEqual( + report_tags.render_currency(m, fmt='#,##0.00', locale='de-de'), '1.234,56' + ) + # fmt takes priority over decimal_places + self.assertEqual( + report_tags.render_currency(m, fmt='0.0000', decimal_places=2), '1234.5600' + ) + + # Test leading digits + m_small = Money(1.23, 'USD') + self.assertEqual( + report_tags.render_currency(m_small, leading=4, locale='en-us'), '$0,001.23' + ) + # leading=1 is the default — no change + self.assertEqual( + report_tags.render_currency(m_small, leading=1, locale='en-us'), '$1.23' + ) + # invalid leading falls back gracefully + self.assertEqual( + report_tags.render_currency(m_small, leading='x', locale='en-us'), '$1.23' + ) + # fmt takes priority over leading + self.assertEqual( + report_tags.render_currency(m_small, leading=6, fmt='#,##0.00'), '1.23' + ) + + # Test include_symbol + # Default (True) — symbol present + self.assertEqual(report_tags.render_currency(m, locale='en-us'), '$1,234.56') + # Explicit False — symbol suppressed + self.assertEqual( + report_tags.render_currency(m, include_symbol=False, locale='en-us'), + '1,234.56', + ) + # include_symbol=False with fmt containing ¤ — ¤ renders as empty string + self.assertEqual( + report_tags.render_currency( + m, include_symbol=False, fmt='¤#,##0.00', locale='en-us' + ), + '1,234.56', + ) + # include_symbol=False with fmt lacking ¤ — no symbol either way + self.assertEqual( + report_tags.render_currency( + m, include_symbol=False, fmt='#,##0.00', locale='en-us' + ), + '1,234.56', + ) + + def test_render_currency_locale_override(self): + """Explicit locale= kwarg takes priority over global setting and system locale.""" + m = Money(1234.56, 'USD') + + # Explicit locale overrides system LANGUAGE_CODE + with override_settings(LANGUAGE_CODE='en-au'): + self.assertEqual( + report_tags.render_currency(m, locale='en-us'), '$1,234.56' + ) + self.assertEqual( + report_tags.render_currency(m, locale='en-gb'), 'US$1,234.56' + ) + + # Invalid locale raises ValidationError regardless of other settings + with self.assertRaises(ValidationError): + report_tags.render_currency(m, locale='xx-zz') + + def test_render_currency_system_locale(self): + """render_currency uses system LANGUAGE_CODE when no explicit locale= is passed.""" + m = Money(1234.56, 'USD') + + with override_settings(LANGUAGE_CODE='en-us'): + self.assertEqual(report_tags.render_currency(m), '$1,234.56') + + with override_settings(LANGUAGE_CODE='en-gb'): + self.assertEqual(report_tags.render_currency(m), 'US$1,234.56') + + with override_settings(LANGUAGE_CODE='en-au'): + self.assertEqual(report_tags.render_currency(m), 'USD1,234.56') + def test_create_currency(self): """Test the create_currency template tag.""" m = report_tags.create_currency(1000, 'USD') @@ -616,14 +768,94 @@ class ReportTagTest(PartImageTestMixin, InvenTreeTestCase): def test_format_date(self): """Test the format_date template tag.""" - # Test with a valid date - date = timezone.datetime(year=2024, month=3, day=13) - self.assertEqual(report_tags.format_date(date), '2024-03-13') - self.assertEqual(report_tags.format_date(date, fmt='%d-%m-%y'), '13-03-24') + dt = timezone.datetime(year=2024, month=3, day=13) + self.assertEqual(report_tags.format_date(dt, locale='de-de'), '13.03.2024') + self.assertEqual(report_tags.format_date(dt, locale='en-us'), 'Mar 13, 2024') + self.assertEqual(report_tags.format_date(dt, locale='en-au'), '13 Mar 2024') + self.assertEqual(report_tags.format_date(dt, locale='fr-fr'), '13 mars 2024') + self.assertEqual(report_tags.format_date(dt, fmt='%d-%m-%y'), '13-03-24') # Test with an invalid date self.assertEqual(report_tags.format_date('abc'), 'abc') - self.assertEqual(report_tags.format_date(date, fmt='a'), 'a') + self.assertEqual(report_tags.format_date(dt, fmt='a'), 'a') + + # Explicit fmt always wins over locale + self.assertEqual( + report_tags.format_date(dt, fmt='%Y-%m-%d', locale='de-de'), '2024-03-13' + ) + + # Falls back to LANGUAGE_CODE when no locale= arg + with override_settings(LANGUAGE_CODE='en-us'): + self.assertEqual(report_tags.format_date(dt), 'Mar 13, 2024') + + # date_format controls the Babel style + self.assertEqual( + report_tags.format_date(dt, locale='en-us', date_format='short'), '3/13/24' + ) + self.assertEqual( + report_tags.format_date(dt, locale='en-us', date_format='long'), + 'March 13, 2024', + ) + self.assertEqual( + report_tags.format_date(dt, locale='en-us', date_format='full'), + 'Wednesday, March 13, 2024', + ) + + # fmt= wins over date_format= + self.assertEqual( + report_tags.format_date(dt, fmt='%Y', locale='en-us', date_format='full'), + '2024', + ) + + # Invalid locale raises ValidationError + with self.assertRaises(ValidationError): + report_tags.format_date(dt, locale='xx-zz') + + def test_format_datetime(self): + """Test that format_datetime renders locale-aware output.""" + from zoneinfo import ZoneInfo + + dt = timezone.datetime(2026, 6, 19, 15, 30, 0, tzinfo=ZoneInfo('UTC')) + + self.assertEqual( + report_tags.format_datetime(dt, locale='en-us'), + 'Jun 19, 2026, 3:30:00 PM', # noqa: RUF001 + ) + self.assertEqual( + report_tags.format_datetime(dt, locale='de-de'), '19.06.2026, 15:30:00' + ) + + # Explicit fmt still wins + self.assertEqual( + report_tags.format_datetime(dt, fmt='%Y-%m-%d', locale='de-de'), + '2026-06-19', + ) + + # Falls back to LANGUAGE_CODE when no locale= arg + with override_settings(LANGUAGE_CODE='de-de'): + self.assertEqual(report_tags.format_datetime(dt), '19.06.2026, 15:30:00') + + # date_format controls the Babel style + self.assertEqual( + report_tags.format_datetime(dt, locale='de-de', date_format='short'), + '19.06.26, 15:30', + ) + self.assertEqual( + report_tags.format_datetime(dt, locale='de-de', date_format='long'), + '19. Juni 2026, 15:30:00 UTC', # codespell:ignore "Juni" + ) + + # fmt= wins over date_format= + self.assertEqual( + report_tags.format_datetime( + dt, fmt='%H:%M', locale='en-us', date_format='full' + ), + '15:30', + ) + + # Invalid locale raises ValidationError + with self.assertRaises(ValidationError): + report_tags.format_datetime(dt, locale='xx-zz') class BarcodeTagTest(TestCase): @@ -642,7 +874,7 @@ class BarcodeTagTest(TestCase): self.assertTrue(barcode.startswith('data:image/bmp;')) # Test empty tag - with self.assertRaises(ValueError): + with self.assertRaises(ValidationError): barcode_tags.barcode('') def test_qrcode(self): @@ -662,7 +894,7 @@ class BarcodeTagTest(TestCase): self.assertEqual(len(qrcode), 309720) # Test empty tag - with self.assertRaises(ValueError): + with self.assertRaises(ValidationError): barcode_tags.qrcode('') def test_clean_barcode(self): @@ -693,7 +925,7 @@ class BarcodeTagTest(TestCase): ) # Test empty tag - with self.assertRaises(ValueError): + with self.assertRaises(ValidationError): barcode_tags.datamatrix('') # Failure cases with wrong args diff --git a/src/backend/InvenTree/report/tests.py b/src/backend/InvenTree/report/tests.py index e5474029ce..3d4f558ea4 100644 --- a/src/backend/InvenTree/report/tests.py +++ b/src/backend/InvenTree/report/tests.py @@ -1,13 +1,18 @@ """Unit testing for the various report models.""" import os +import socket +import tempfile from io import StringIO +from pathlib import Path +from unittest.mock import patch from django.apps import apps from django.conf import settings from django.core.cache import cache from django.core.files.base import ContentFile from django.core.files.storage import default_storage +from django.test import TestCase from django.urls import reverse from pypdf import PdfReader @@ -16,8 +21,9 @@ import report.models as report_models from build.models import Build from common.models import Attachment from common.settings import set_global_setting +from InvenTree.config import get_base_dir from InvenTree.unit_test import AdminTestCase, InvenTreeAPITestCase -from order.models import ReturnOrder, SalesOrder +from order.models import PurchaseOrder, ReturnOrder, SalesOrder from part.models import Part from plugin.registry import registry from report.models import LabelTemplate, ReportTemplate @@ -731,9 +737,449 @@ class TestReportTest(PrintTestMixins, ReportTest): self.run_print_test(SalesOrder, 'salesorder', label=False) +class ReportPrintPermissionTest(InvenTreeAPITestCase): + """Test that the report print endpoint checks VIEW permission on the associated model type.""" + + fixtures = [ + 'category', + 'part', + 'company', + 'location', + 'supplier_part', + 'stock', + 'order', + ] + + superuser = False + roles = [] + + def setUp(self): + """Setup for permission tests.""" + cache.clear() + apps.get_app_config('report').create_default_reports() + return super().setUp() + + def test_report_print_model_permission(self): + """A user without VIEW permission on the model type must receive 403; granting the role allows printing.""" + template = ReportTemplate.objects.filter( + enabled=True, model_type='purchaseorder' + ).first() + self.assertIsNotNone(template) + + items = PurchaseOrder.objects.all()[:2] + self.assertGreater(len(items), 0) + + url = reverse('api-report-print') + post_data = {'template': template.pk, 'items': [item.pk for item in items]} + + # No roles assigned: expect permission denied + self.post(url, data=post_data, expected_code=403) + + # Grant view access to purchase orders + self.assignRole('purchase_order.view') + cache.clear() + + # Should now succeed + self.post(url, data=post_data, expected_code=201) + + def test_report_print_disabled_template(self): + """Printing against a disabled report template must be rejected.""" + self.assignRole('purchase_order.view') + cache.clear() + + template = ReportTemplate.objects.filter( + enabled=True, model_type='purchaseorder' + ).first() + self.assertIsNotNone(template) + + items = PurchaseOrder.objects.all()[:2] + self.assertGreater(len(items), 0) + + url = reverse('api-report-print') + post_data = {'template': template.pk, 'items': [item.pk for item in items]} + + # Enabled template: should succeed + self.post(url, data=post_data, expected_code=201) + + # Disable the template and retry: should be rejected + template.enabled = False + template.save() + + self.post(url, data=post_data, expected_code=400) + + +class LabelPrintPermissionTest(InvenTreeAPITestCase): + """Test that the label print endpoint checks VIEW permission on the associated model type.""" + + fixtures = ['category', 'part', 'company', 'location', 'supplier_part', 'stock'] + + superuser = False + roles = [] + + def setUp(self): + """Setup for permission tests.""" + cache.clear() + apps.get_app_config('report').create_default_labels() + return super().setUp() + + def test_label_print_model_permission(self): + """A user without VIEW permission on the model type must receive 403; granting the role allows printing.""" + template = LabelTemplate.objects.filter(enabled=True, model_type='part').first() + self.assertIsNotNone(template) + self.assertGreater(template.width, 0) + self.assertGreater(template.height, 0) + + items = Part.objects.all()[:2] + self.assertGreater(len(items), 0) + + url = reverse('api-label-print') + post_data = {'template': template.pk, 'items': [item.pk for item in items]} + + # No roles assigned: expect permission denied + self.post(url, data=post_data, expected_code=403) + + # Grant view access to parts + self.assignRole('part.view') + cache.clear() + + # Should now succeed + self.post(url, data=post_data, expected_code=201) + + def test_label_print_disabled_template(self): + """Printing against a disabled label template must be rejected.""" + self.assignRole('part.view') + cache.clear() + + template = LabelTemplate.objects.filter(enabled=True, model_type='part').first() + self.assertIsNotNone(template) + self.assertGreater(template.width, 0) + self.assertGreater(template.height, 0) + + items = Part.objects.all()[:2] + self.assertGreater(len(items), 0) + + url = reverse('api-label-print') + post_data = {'template': template.pk, 'items': [item.pk for item in items]} + + # Enabled template: should succeed + self.post(url, data=post_data, expected_code=201) + + # Disable the template and retry: should be rejected + template.enabled = False + template.save() + + self.post(url, data=post_data, expected_code=400) + + class AdminTest(AdminTestCase): """Tests for the admin interface integration.""" def test_admin(self): """Test the admin URL.""" self.helper(model=ReportTemplate) + + +class URLFetcherE2ETest(ReportTest): + """End-to-end test: the URL fetcher blocks malicious URLs during a real PDF render. + + Extends ReportTest so that fixtures, auth, and default report templates are all + available. The print task runs synchronously in test mode (no workers), so the + render completes inline and log output is captured within the same request. + """ + + def test_file_url_blocked_in_render(self): + """A template embedding a file:// URL must still produce a PDF, but the URL must be blocked and logged.""" + from io import StringIO + + # Upload a minimal report template that embeds a malicious file:// reference. + html = ( + '' + '' + '

    Security test content

    ' + '' + ) + template_io = StringIO(html) + template_io.name = 'security_test_template.html' + + response = self.post( + reverse('api-report-template-list'), + data={ + 'name': 'Security Test', + 'description': 'Tests that file:// URLs are blocked during rendering', + 'template': template_io, + 'model_type': 'stockitem', + }, + format=None, + expected_code=201, + ) + template_pk = response.data['pk'] + + item = StockItem.objects.first() + self.assertIsNotNone(item) + + # Render the template. WeasyPrint catches the ValueError from our fetcher and + # continues, so the PDF is still generated — the blocked resource is just skipped. + with self.assertLogs('inventree', level='WARNING') as captured: + response = self.post( + reverse('api-report-print'), + {'template': template_pk, 'items': [item.pk]}, + expected_code=201, + ) + + # A PDF output should have been produced despite the blocked resource. + self.assertTrue(response.data['output'].endswith('.pdf')) + + # The fetcher must have logged a warning identifying the blocked URL. + blocked_warnings = [ + msg + for msg in captured.output + if 'blocked file://' in msg and '/etc/passwd' in msg + ] + self.assertTrue( + blocked_warnings, 'Expected a blocked file:// warning in the log output' + ) + + def test_ssrf_url_blocked_in_render(self): + """A template embedding an HTTP URL to a private/reserved address must be blocked and logged.""" + from io import StringIO + + # 127.0.0.1 is loopback — validate_url_no_ssrf rejects it regardless of port. + html = ( + '' + '' + '

    Security test content

    ' + '' + ) + template_io = StringIO(html) + template_io.name = 'ssrf_test_template.html' + + response = self.post( + reverse('api-report-template-list'), + data={ + 'name': 'SSRF Test', + 'description': 'Tests that SSRF URLs are blocked during rendering', + 'template': template_io, + 'model_type': 'stockitem', + }, + format=None, + expected_code=201, + ) + template_pk = response.data['pk'] + + item = StockItem.objects.first() + self.assertIsNotNone(item) + + # Render the template. WeasyPrint catches the ValueError from our fetcher and + # continues, so the PDF is still generated — the blocked resource is just skipped. + with self.assertLogs('inventree', level='WARNING') as captured: + response = self.post( + reverse('api-report-print'), + {'template': template_pk, 'items': [item.pk]}, + expected_code=201, + ) + + # A PDF output should have been produced despite the blocked resource. + self.assertTrue(response.data['output'].endswith('.pdf')) + + # The fetcher must have logged a warning for the blocked SSRF attempt. + blocked_warnings = [ + msg + for msg in captured.output + if 'blocked URL' in msg and '127.0.0.1' in msg + ] + self.assertTrue( + blocked_warnings, 'Expected a blocked SSRF URL warning in the log output' + ) + + def test_fetch_urls_disabled_blocks_http(self): + """When REPORT_FETCH_URLS is False, any http/https URL in a template must be blocked.""" + from io import StringIO + + from common.settings import set_global_setting + + # Use a publicly routable address so the test would reach the network if + # our guard were absent — we want to confirm it is stopped by the setting, + # not by a secondary SSRF IP check. + html = ( + '' + '' + '

    Security test content

    ' + '' + ) + template_io = StringIO(html) + template_io.name = 'fetch_disabled_test_template.html' + + response = self.post( + reverse('api-report-template-list'), + data={ + 'name': 'Fetch Disabled Test', + 'description': 'Tests that HTTP fetching is blocked when REPORT_FETCH_URLS=False', + 'template': template_io, + 'model_type': 'stockitem', + }, + format=None, + expected_code=201, + ) + template_pk = response.data['pk'] + + item = StockItem.objects.first() + self.assertIsNotNone(item) + + set_global_setting('REPORT_FETCH_URLS', False, change_user=None) + + with self.assertLogs('inventree', level='WARNING') as captured: + response = self.post( + reverse('api-report-print'), + {'template': template_pk, 'items': [item.pk]}, + expected_code=201, + ) + + self.assertTrue(response.data['output'].endswith('.pdf')) + + blocked_warnings = [ + msg + for msg in captured.output + if 'REPORT_FETCH_URLS' in msg and 'example.com' in msg + ] + self.assertTrue( + blocked_warnings, 'Expected a REPORT_FETCH_URLS warning in the log output' + ) + + +class URLFetcherTest(TestCase): + """Tests for InvenTreeURLFetcher security restrictions.""" + + def setUp(self): + """Import fetcher for each test.""" + from report.fetcher import InvenTreeURLFetcher + + self.fetcher = InvenTreeURLFetcher() + + def test_file_url_blocked(self): + """file:// URLs must always be rejected regardless of path.""" + for url in [ + 'file:///etc/passwd', + 'file:///proc/self/environ', + f'file://{settings.MEDIA_ROOT}/report/assets/anything.png', + f'file://{settings.STATIC_ROOT}/some/font.ttf', + ]: + with self.assertRaises(ValueError, msg=f'Expected block for {url}'): + self.fetcher.fetch(url) + + def test_unknown_scheme_blocked(self): + """Non-http/data/file schemes must be rejected.""" + for url in ['ftp://example.com/file.txt', 'javascript://x']: + with self.assertRaises(ValueError, msg=f'Expected block for {url}'): + self.fetcher.fetch(url) + + def test_data_uri_allowed(self): + """data: URIs must always be permitted.""" + with patch('weasyprint.urls.URLFetcher.fetch', return_value={}): + self.fetcher.fetch('data:image/png;base64,abc123') + self.fetcher.fetch('data:text/css;base64,abc123') + + def test_dns_rebind_is_blocked_at_fetch_time(self): + """A hostname that resolves safely for validation but privately for the real fetch must be blocked. + + Regression test: `validate_url_no_ssrf()` used to resolve the hostname once, + validate that result, and then discard it, so `InvenTreeURLFetcher.fetch()` + would delegate straight to WeasyPrint's own fetcher, which resolves the + hostname *again* independently. An attacker controlling DNS for their own + domain could answer the first ("check") lookup with a public IP and every + subsequent ("use") lookup with a private/internal one (DNS rebinding), so the + real request WeasyPrint made went somewhere the validator never saw. + """ + set_global_setting('REPORT_FETCH_URLS', True, change_user=None) + + public_addrinfo = [(2, 1, 6, '', ('93.184.216.34', 0))] + private_addrinfo = [(2, 1, 6, '', ('127.0.0.1', 0))] + + calls = {'n': 0} + + def rebinding_getaddrinfo(host, *args, **kwargs): + calls['n'] += 1 + return public_addrinfo if calls['n'] == 1 else private_addrinfo + + def fake_weasyprint_fetch(_self, url, headers=None): + # Simulate WeasyPrint's own fetch-time DNS resolution, performed + # independently of the validation InvenTreeURLFetcher already did. + socket.getaddrinfo('rebind.example.com', None) + return {'string': b'should never be reached'} + + import InvenTree.helpers_model as helpers_model + + with patch.object( + helpers_model, '_real_getaddrinfo', side_effect=rebinding_getaddrinfo + ): + with patch( + 'weasyprint.urls.URLFetcher.fetch', side_effect=fake_weasyprint_fetch + ): + with self.assertRaises(socket.gaierror): + self.fetcher.fetch('http://rebind.example.com/image.png') + + # The validation-time lookup (safe) and the fetch-time lookup (private) + # must both have happened for this to be a meaningful regression test. + self.assertEqual(calls['n'], 2) + + +class DefaultTemplateFileTest(TestCase): + """Unit tests for building the default report and label template files.""" + + def test_file_size_matches_bytes(self): + """file_from_template must size the ContentFile by byte length. + + Reading the template in text mode makes the size a character count, + which is smaller than the byte length for multi-byte content and breaks + uploads to S3 backends that enforce Content-Length. + """ + config = apps.get_app_config('report') + filename = 'inventree_transfer_order_report.html' + content_file = config.file_from_template('report', filename) + path = get_base_dir().joinpath('report', 'templates', 'report', filename) + self.assertEqual(content_file.size, path.stat().st_size) + + def test_file_from_template_is_encoding_agnostic(self): + """file_from_template must preserve the exact bytes for any encoding. + + A text-mode read sizes the ContentFile by character count and needs the + correct decoder, so non-English content is both mis-sized and at risk of + corruption. Reading the raw bytes keeps the file identical to what is on + disk, so the size always matches the Content-Length used for S3 uploads. + The samples below cover non-ASCII text in a few encodings, including + multi-byte content where a character count would not equal the byte + length. + """ + config = apps.get_app_config('report') + + # (encoding, text, whether the encoding uses multi-byte characters). + # The utf cases hold characters that span more than one byte, so a + # character count would not equal the byte length; latin-1 stays + # single-byte and is included to show the read is not utf-8 specific. + cases = [ + ('utf-8', 'Système de café ≤ 你好 в наявності 📦', True), + ('utf-16', 'Système de café ≤ 你好 в наявності 📦', True), + ('latin-1', 'Système de café àéîõü', False), + ] + + for encoding, text, multibyte in cases: + with self.subTest(encoding=encoding): + body = f'{text}' + raw = body.encode(encoding) + + if multibyte: + # A character count would differ from the byte length here + self.assertNotEqual(len(raw), len(body)) + + with tempfile.TemporaryDirectory() as tmp: + base = Path(tmp) + template_dir = base.joinpath('report', 'templates', 'report') + template_dir.mkdir(parents=True) + filename = f'encoding_{encoding}.html' + template_dir.joinpath(filename).write_bytes(raw) + + with patch('report.apps.get_base_dir', return_value=base): + content_file = config.file_from_template('report', filename) + + # Size and content must match the raw bytes exactly + self.assertEqual(content_file.size, len(raw)) + self.assertEqual(content_file.read(), raw) diff --git a/src/backend/InvenTree/script/update_icons.py b/src/backend/InvenTree/script/update_icons.py index ea24479456..716ffeb878 100644 --- a/src/backend/InvenTree/script/update_icons.py +++ b/src/backend/InvenTree/script/update_icons.py @@ -19,7 +19,7 @@ if __name__ == '__main__': os.mkdir(STATIC_FOLDER) print('Downloading tabler icons...') - os.system(f'npm install --prefix {TMP_FOLDER} @tabler/icons @tabler/icons-webfont') + os.system(f'npm install --prefix {TMP_FOLDER} @tabler/icons @tabler/icons-webfont') # ty:ignore[deprecated] print(f'Copying tabler icons to {STATIC_FOLDER}...') diff --git a/src/backend/InvenTree/stock/admin.py b/src/backend/InvenTree/stock/admin.py index 77f5c49fbd..d72e844cb7 100644 --- a/src/backend/InvenTree/stock/admin.py +++ b/src/backend/InvenTree/stock/admin.py @@ -77,12 +77,24 @@ class StockItemAdmin(admin.ModelAdmin): @admin.register(StockItemTracking) class StockTrackingAdmin(admin.ModelAdmin): - """Admin class for StockTracking.""" + """Admin class for StockTracking - read-only to preserve audit trail integrity.""" list_display = ('item', 'date', 'label') autocomplete_fields = ['item'] + def has_add_permission(self, request): + """Prevent addition of new tracking entries via the admin interface.""" + return False + + def has_change_permission(self, request, obj=None): + """Prevent modification of tracking entries via the admin interface.""" + return False + + def has_delete_permission(self, request, obj=None): + """Prevent deletion of tracking entries via the admin interface.""" + return False + @admin.register(StockItemTestResult) class StockItemTestResultAdmin(admin.ModelAdmin): diff --git a/src/backend/InvenTree/stock/api.py b/src/backend/InvenTree/stock/api.py index aa6548051c..994d039c85 100644 --- a/src/backend/InvenTree/stock/api.py +++ b/src/backend/InvenTree/stock/api.py @@ -18,6 +18,7 @@ from rest_framework.generics import GenericAPIView from rest_framework.response import Response from rest_framework.serializers import ValidationError +import common.filters import common.models import common.settings import InvenTree.helpers @@ -29,10 +30,15 @@ from company.models import Company, ManufacturerPart, SupplierPart from company.serializers import CompanySerializer from data_exporter.mixins import DataExportViewMixin from generic.states.api import StatusView -from InvenTree.api import BulkCreateMixin, BulkUpdateMixin, ListCreateDestroyAPIView +from InvenTree.api import ( + BulkCreateMixin, + BulkUpdateMixin, + ListCreateDestroyAPIView, + TreeMixin, + meta_path, +) from InvenTree.fields import InvenTreeOutputOption, OutputConfiguration from InvenTree.filters import ( - ORDER_FILTER, SEARCH_ORDER_FILTER, InvenTreeDateFilter, NumberOrNullFilter, @@ -137,8 +143,16 @@ class StockItemSerialize(StockItemContextMixin, CreateAPI): queryset = StockSerializers.StockItemSerializer.annotate_queryset(items) + # Apply any additional prefetching required by optional fields which end up + # included in this response (e.g. 'tags', 'tests') - mirrors what + # OutputOptionsMixin.get_queryset() does for a normal list/retrieve request, + # which this manually-constructed response bypasses + context = self.get_serializer_context() + probe_serializer = StockSerializers.StockItemSerializer(context=context) + queryset = probe_serializer.prefetch_queryset(queryset) + response = StockSerializers.StockItemSerializer( - queryset, many=True, context=self.get_serializer_context() + queryset, many=True, context=context ) return Response(response.data, status=status.HTTP_201_CREATED) @@ -167,6 +181,36 @@ class StockItemConvert(StockItemContextMixin, CreateAPI): serializer_class = StockSerializers.ConvertStockItemSerializer +@extend_schema(responses={201: StockSerializers.StockItemSerializer(many=True)}) +class StockItemDisassemble(StockItemContextMixin, CreateAPI): + """API endpoint for disassembling a stock item into its component parts. + + The components are generated based on the BOM lines provided in the request, + which must be valid BOM lines for the part associated with the stock item. + """ + + serializer_class = StockSerializers.DisassembleStockItemSerializer + pagination_class = None + + def create(self, request, *args, **kwargs): + """Disassemble the provided StockItem.""" + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + + # Perform the actual disassembly step + items = serializer.save() + + queryset = StockSerializers.StockItemSerializer.annotate_queryset( + StockItem.objects.filter(pk__in=[item.pk for item in items]) + ) + + response = StockSerializers.StockItemSerializer( + queryset, many=True, context=self.get_serializer_context() + ) + + return Response(response.data, status=status.HTTP_201_CREATED) + + class StockAdjustView(CreateAPI): """A generic class for handling stocktake actions. @@ -368,6 +412,8 @@ class StockLocationFilter(FilterSet): return queryset + tags = common.filters.TagsFilter(label=_('Tags')) + class StockLocationMixin(SerializerContextMixin): """Mixin class for StockLocation API endpoints.""" @@ -448,20 +494,33 @@ class StockLocationDetail( ) -class StockLocationTree(ListAPI): +class LocationTreeFilter(FilterSet): + """Custom filterset class for the StockLocationTree endpoint.""" + + class Meta: + """Metaclass options for this filterset.""" + + model = StockLocation + fields = ['parent', 'tree_id', 'level'] + + max_level = rest_filters.NumberFilter( + label=_('Max Level'), + method='filter_max_level', + help_text=_('Limit the depth of the category tree'), + ) + + def filter_max_level(self, queryset, name, value): + """Filter by the maximum depth of the category tree.""" + return queryset.filter(level__lte=value) + + +class StockLocationTree(TreeMixin, ListAPI): """API endpoint for accessing a list of StockLocation objects, ready for rendering as a tree.""" + model_class = StockLocation queryset = StockLocation.objects.all() serializer_class = StockSerializers.LocationTreeSerializer - - filter_backends = ORDER_FILTER - - ordering_fields = ['level', 'name', 'sublocations'] - - # Order by tree level (top levels first) and then name - ordering = ['level', 'name'] - - ordering_field_aliases = {'level': ['level', 'name'], 'name': ['name', 'level']} + filterset_class = LocationTreeFilter def get_queryset(self, *args, **kwargs): """Return annotated queryset for the StockLocationTree endpoint.""" @@ -531,6 +590,7 @@ class StockFilter(FilterSet): # Simple filter filters fields = [ 'supplier_part', + 'parent', 'belongs_to', 'build', 'customer', @@ -859,15 +919,6 @@ class StockFilter(FilterSet): return queryset.exclude(purchase_price=None) return queryset.filter(purchase_price=None) - ancestor = rest_filters.ModelChoiceFilter( - label='Ancestor', queryset=StockItem.objects.all(), method='filter_ancestor' - ) - - @extend_schema_field(OpenApiTypes.INT) - def filter_ancestor(self, queryset, name, ancestor): - """Filter based on ancestor stock item.""" - return queryset.filter(parent__in=ancestor.get_descendants(include_self=True)) - category = rest_filters.ModelChoiceFilter( label=_('Category'), queryset=PartCategory.objects.all(), @@ -911,7 +962,14 @@ class StockFilter(FilterSet): | Q(supplier_part__manufacturer_part__manufacturer=company) ).distinct() - # Update date filters + created_before = InvenTreeDateFilter( + label=_('Created before'), field_name='creation_date', lookup_expr='lt' + ) + + created_after = InvenTreeDateFilter( + label=_('Created after'), field_name='creation_date', lookup_expr='gt' + ) + updated_before = InvenTreeDateFilter( label=_('Updated before'), field_name='updated', lookup_expr='lt' ) @@ -928,6 +986,16 @@ class StockFilter(FilterSet): label=_('Stocktake After'), field_name='stocktake_date', lookup_expr='gt' ) + has_stocktake = rest_filters.BooleanFilter( + label=_('Has Stocktake Date'), method='filter_has_stocktake' + ) + + def filter_has_stocktake(self, queryset, name, value): + """Filter by whether or not the StockItem has a stocktake date.""" + if str2bool(value): + return queryset.exclude(stocktake_date=None) + return queryset.filter(stocktake_date=None) + # Stock "expiry" filters expiry_before = InvenTreeDateFilter( label=_('Expiry date before'), field_name='expiry_date', lookup_expr='lt' @@ -959,26 +1027,6 @@ class StockFilter(FilterSet): else: return queryset.exclude(stale_filter) - exclude_tree = rest_filters.NumberFilter( - method='filter_exclude_tree', - label=_('Exclude Tree'), - help_text=_( - 'Provide a StockItem PK to exclude that item and all its descendants' - ), - ) - - def filter_exclude_tree(self, queryset, name, value): - """Exclude a StockItem and all of its descendants from the queryset.""" - try: - root = StockItem.objects.get(pk=value) - pks_to_exclude = [ - item.pk for item in root.get_descendants(include_self=True) - ] - return queryset.exclude(pk__in=pks_to_exclude) - except (ValueError, StockItem.DoesNotExist): - # If the value is invalid or the object doesn't exist, do nothing. - return queryset - cascade = rest_filters.BooleanFilter( method='filter_cascade', label=_('Cascade Locations'), @@ -1019,6 +1067,8 @@ class StockFilter(FilterSet): children = loc_obj.getUniqueChildren() return queryset.filter(location__in=children) + tags = common.filters.TagsFilter(label=_('Tags')) + class StockApiMixin(SerializerContextMixin): """Mixin class for StockItem API endpoints.""" @@ -1291,6 +1341,7 @@ class StockList( 'part__IPN', 'updated', 'purchase_price', + 'creation_date', 'stocktake_date', 'expiry_date', 'packaging', @@ -1485,10 +1536,7 @@ class StockItemTestResultList( Also, check if an attachment was uploaded alongside the test result, and save it to the database if it were. """ - # Capture the user information - test_result = serializer.save() - test_result.user = self.request.user - test_result.save() + serializer.save(user=self.request.user) class StockTrackingDetail(RetrieveAPI): @@ -1637,32 +1685,6 @@ class StockTrackingList( return Response(data) - def create(self, request, *args, **kwargs): - """Create a new StockItemTracking object. - - Here we override the default 'create' implementation, - to save the user information associated with the request object. - """ - # Clean up input data - data = self.clean_data(request.data) - - serializer = self.get_serializer(data=data) - serializer.is_valid(raise_exception=True) - - # Record the user who created this Part object - item = serializer.save() - item.user = request.user - item.system = False - - # quantity field cannot be explicitly adjusted here - item.quantity = item.item.quantity - item.save() - - headers = self.get_success_headers(serializer.data) - return Response( - serializer.data, status=status.HTTP_201_CREATED, headers=headers - ) - filter_backends = SEARCH_ORDER_FILTER ordering = '-date' @@ -1679,7 +1701,11 @@ stock_api_urls = [ path('tree/', StockLocationTree.as_view(), name='api-location-tree'), # Stock location detail endpoints path( - '/', StockLocationDetail.as_view(), name='api-location-detail' + '/', + include([ + meta_path(StockLocation), + path('', StockLocationDetail.as_view(), name='api-location-detail'), + ]), ), path('', StockLocationList.as_view(), name='api-location-list'), ]), @@ -1690,8 +1716,14 @@ stock_api_urls = [ include([ path( '/', - StockLocationTypeDetail.as_view(), - name='api-location-type-detail', + include([ + meta_path(StockLocationType), + path( + '', + StockLocationTypeDetail.as_view(), + name='api-location-type-detail', + ), + ]), ), path('', StockLocationTypeList.as_view(), name='api-location-type-list'), ]), @@ -1711,8 +1743,14 @@ stock_api_urls = [ include([ path( '/', - StockItemTestResultDetail.as_view(), - name='api-stock-test-result-detail', + include([ + meta_path(StockItemTestResult), + path( + '', + StockItemTestResultDetail.as_view(), + name='api-stock-test-result-detail', + ), + ]), ), path( '', StockItemTestResultList.as_view(), name='api-stock-test-result-list' @@ -1743,7 +1781,13 @@ stock_api_urls = [ '/', include([ path('convert/', StockItemConvert.as_view(), name='api-stock-item-convert'), + path( + 'disassemble/', + StockItemDisassemble.as_view(), + name='api-stock-item-disassemble', + ), path('install/', StockItemInstall.as_view(), name='api-stock-item-install'), + meta_path(StockItem), path( 'serialize/', StockItemSerialize.as_view(), diff --git a/src/backend/InvenTree/stock/events.py b/src/backend/InvenTree/stock/events.py index 6f6efb2f62..a3eb81c811 100644 --- a/src/backend/InvenTree/stock/events.py +++ b/src/backend/InvenTree/stock/events.py @@ -15,5 +15,6 @@ class StockEvents(BaseEventEnum): ITEM_COUNTED = 'stockitem.counted' ITEM_QUANTITY_UPDATED = 'stockitem.quantityupdated' ITEM_INSTALLED_INTO_ASSEMBLY = 'stockitem.installed' + ITEM_DISASSEMBLED = 'stockitem.disassembled' ITEMS_CREATED = 'stockitem.created_items' diff --git a/src/backend/InvenTree/stock/fixtures/stock.yaml b/src/backend/InvenTree/stock/fixtures/stock.yaml index 8fd9fd97c0..6181ccaf1c 100644 --- a/src/backend/InvenTree/stock/fixtures/stock.yaml +++ b/src/backend/InvenTree/stock/fixtures/stock.yaml @@ -10,10 +10,6 @@ quantity: 4000 purchase_price: 123 purchase_price_currency: AUD - tree_id: 20 - level: 0 - lft: 1 - rght: 2 # 5,000 screws in the bathroom - model: stock.stockitem @@ -22,10 +18,6 @@ part: 1 location: 2 quantity: 5000 - tree_id: 21 - level: 0 - lft: 1 - rght: 2 # Capacitor C_22N_0805 in 'Office' - model: stock.stockitem @@ -34,10 +26,6 @@ part: 5 location: 4 quantity: 666 - tree_id: 16 - level: 0 - lft: 1 - rght: 2 # 1234 2K2 resistors in 'Drawer_1' - model: stock.stockitem @@ -46,10 +34,6 @@ part: 3 location: 5 quantity: 1234 - tree_id: 22 - level: 0 - lft: 1 - rght: 2 # Some widgets in drawer 3 - model: stock.stockitem @@ -60,10 +44,6 @@ location: 7 quantity: 10 delete_on_deplete: False - tree_id: 28 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 101 @@ -72,10 +52,6 @@ batch: "B2345" location: 7 quantity: 5 - tree_id: 27 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 102 @@ -84,10 +60,6 @@ batch: 'BCDE' location: 7 quantity: 0 - tree_id: 26 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 105 @@ -97,10 +69,6 @@ quantity: 1 serial: 1000 serial_int: 1000 - tree_id: 29 - level: 0 - lft: 1 - rght: 2 # Stock items for template / variant parts - model: stock.stockitem @@ -110,10 +78,6 @@ location: 7 quantity: 5 batch: "BBAAA" - tree_id: 2 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 501 @@ -123,10 +87,6 @@ quantity: 1 serial: 1 serial_int: 1 - tree_id: 3 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 502 @@ -136,10 +96,6 @@ quantity: 1 serial: 2 serial_int: 2 - tree_id: 4 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 503 @@ -149,10 +105,6 @@ quantity: 1 serial: 3 serial_int: 3 - tree_id: 5 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 504 @@ -162,10 +114,6 @@ quantity: 1 serial: 4 serial_int: 4 - tree_id: 6 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 505 @@ -175,10 +123,6 @@ quantity: 1 serial: 5 serial_int: 5 - tree_id: 1 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 510 @@ -188,10 +132,6 @@ quantity: 1 serial: 10 serial_int: 10 - tree_id: 24 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 511 @@ -201,10 +141,6 @@ quantity: 1 serial: 11 serial_int: 11 - tree_id: 23 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 512 @@ -214,10 +150,6 @@ quantity: 1 serial: 12 serial_int: 12 - tree_id: 25 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 520 @@ -229,10 +161,6 @@ serial_int: 20 expiry_date: "1990-10-10" barcode_hash: 9e5ae7fc20568ed4814c10967bba8b65 - tree_id: 18 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 521 @@ -244,10 +172,6 @@ serial_int: 21 status: 60 barcode_hash: 1be0dfa925825c5c6c79301449e50c2d - tree_id: 17 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 522 @@ -259,10 +183,6 @@ serial_int: 22 expiry_date: "1990-10-10" status: 70 - tree_id: 19 - level: 0 - lft: 1 - rght: 2 belongs_to: 105 # Multiple stock items for "Bob" (PK 100) @@ -272,10 +192,6 @@ part: 100 location: 1 quantity: 10 - tree_id: 9 - level: 0 - lft: 1 - rght: 4 - model: stock.stockitem pk: 1001 @@ -284,10 +200,6 @@ parent: 1000 location: 1 quantity: 11 - tree_id: 9 - level: 1 - lft: 2 - rght: 3 - model: stock.stockitem pk: 1002 @@ -295,10 +207,6 @@ part: 100 location: 1 quantity: 12 - tree_id: 8 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 1003 @@ -306,10 +214,6 @@ part: 100 location: 1 quantity: 13 - tree_id: 15 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 1004 @@ -317,10 +221,6 @@ part: 100 location: 1 quantity: 14 - tree_id: 7 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 1005 @@ -328,10 +228,6 @@ part: 100 location: 1 quantity: 15 - tree_id: 13 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 1006 @@ -339,10 +235,6 @@ part: 100 location: 1 quantity: 16 - tree_id: 12 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 1007 @@ -350,10 +242,6 @@ part: 100 location: 7 quantity: 17 - tree_id: 11 - level: 0 - lft: 1 - rght: 2 - model: stock.stockitem pk: 1008 @@ -361,7 +249,3 @@ part: 100 location: 7 quantity: 18 - tree_id: 10 - level: 0 - lft: 1 - rght: 2 diff --git a/src/backend/InvenTree/stock/migrations/0120_stockitem_creation_date.py b/src/backend/InvenTree/stock/migrations/0120_stockitem_creation_date.py new file mode 100644 index 0000000000..e4abb47560 --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0120_stockitem_creation_date.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.14 on 2026-05-26 08:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("stock", "0119_alter_stockitemtestresult_date"), + ] + + operations = [ + migrations.AddField( + model_name="stockitem", + name="creation_date", + field=models.DateTimeField( + blank=True, + help_text="Date that this stock item was created", + null=True, + verbose_name="Creation Date", + ), + ), + ] diff --git a/src/backend/InvenTree/stock/migrations/0121_auto_20260526_0849.py b/src/backend/InvenTree/stock/migrations/0121_auto_20260526_0849.py new file mode 100644 index 0000000000..d6e5087a8e --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0121_auto_20260526_0849.py @@ -0,0 +1,102 @@ +# Generated by Django 5.2.14 on 2026-05-26 08:49 + +import datetime +from tqdm import tqdm + +from django.db import migrations + + +def set_creation_date(apps, schema_editor): + """Set the creation_date field for existing StockItem entries.""" + + StockItem = apps.get_model('stock', 'StockItem') + StockItemTracking = apps.get_model('stock', 'StockItemTracking') + + # First pass - find all StockHistoryCode.CREATED entries + # Note: As of 2026-05-26, the relevant status codes were: + # CREATED = 1 + + creation_entries = StockItemTracking.objects.filter(tracking_type=1) + + items_to_update = [] + + def process_item(item): + """Process a StockItem entry for update. + + As we are iterating over a potentially large number of StockItem entries, + we periodically write updates to the database in batches to avoid memory issues. + """ + nonlocal items_to_update + + items_to_update.append(item) + + if len(items_to_update) >= 250: + StockItem.objects.bulk_update(items_to_update, ['creation_date']) + items_to_update = [] + + if creation_entries.count() > 0: + progress = tqdm(total=creation_entries.count(), desc='stock.0121: Setting creation_date for StockItem entries') + + + for entry in creation_entries: + item = StockItem.objects.filter(pk=entry.item_id).first() + if item and item.creation_date is None: + item.creation_date = entry.date + process_item(item) + + progress.update(1) + + progress.close() + + # Next: Find any StockItem entries that have a null creation_date + items = StockItem.objects.filter(creation_date__isnull=True) + + if items.count() > 0: + + progress = tqdm(total=items.count(), desc='stock.0121: Setting creation_date for remaining StockItem entries') + + for item in items: + # Source the creation_date from the stock item + earliest_entry = StockItemTracking.objects.filter(item_id=item.pk).order_by('date').first() + + # Gather potential datetime sources for the creation_date field + utc = datetime.timezone.utc + + def make_aware(dt): + """Ensure a datetime is UTC-aware for safe cross-type comparison.""" + return dt.replace(tzinfo=utc) if dt.tzinfo is None else dt.astimezone(utc) + + raw_options = [ + item.updated, + datetime.datetime(item.stocktake_date.year, item.stocktake_date.month, item.stocktake_date.day, tzinfo=utc) if item.stocktake_date else None, + earliest_entry.date if earliest_entry else None, + ] + date_options = [make_aware(d) for d in raw_options if d is not None] + + if date_options: + item.creation_date = min(date_options) + process_item(item) + + progress.update(1) + + # Update the remaining items + StockItem.objects.bulk_update(items_to_update, ['creation_date'], batch_size=250) + + +class Migration(migrations.Migration): + """This migration extracts the 'creation_date' field for each StockItem entry. + + - If a CREATED entry exists in the StockItemTracking table, this is used as the source for the creation_date field. + - If no CREATED entry exists, the creation_date is sourced from the earliest of the following + - The 'updated' field of the StockItem entry + - The 'stocktake_date' field of the StockItem entry (converted to a datetime) + - The earliest entry in the StockItemTracking table for that item + """ + + dependencies = [ + ("stock", "0120_stockitem_creation_date"), + ] + + operations = [ + migrations.RunPython(set_creation_date, reverse_code=migrations.RunPython.noop), + ] diff --git a/src/backend/InvenTree/stock/migrations/0122_alter_stockitem_creation_date.py b/src/backend/InvenTree/stock/migrations/0122_alter_stockitem_creation_date.py new file mode 100644 index 0000000000..c26c17b8b1 --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0122_alter_stockitem_creation_date.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.14 on 2026-05-26 09:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("stock", "0121_auto_20260526_0849"), + ] + + operations = [ + migrations.AlterField( + model_name="stockitem", + name="creation_date", + field=models.DateTimeField( + auto_now_add=True, + help_text="Date that this stock item was created", + null=True, + verbose_name="Creation Date", + ), + ), + ] diff --git a/src/backend/InvenTree/stock/migrations/0123_remove_stockitem_review_needed.py b/src/backend/InvenTree/stock/migrations/0123_remove_stockitem_review_needed.py new file mode 100644 index 0000000000..e81db219dd --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0123_remove_stockitem_review_needed.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.14 on 2026-06-02 06:22 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("stock", "0122_alter_stockitem_creation_date"), + ] + + operations = [ + migrations.RemoveField( + model_name="stockitem", + name="review_needed", + ), + ] diff --git a/src/backend/InvenTree/stock/migrations/0124_alter_mptt_fields.py b/src/backend/InvenTree/stock/migrations/0124_alter_mptt_fields.py new file mode 100644 index 0000000000..5b29e1a58c --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0124_alter_mptt_fields.py @@ -0,0 +1,34 @@ +# Generated by Django 5.2.15 on 2026-07-11 03:34 + +from django.db import migrations, models + + + +class Migration(migrations.Migration): + + dependencies = [ + ("stock", "0123_remove_stockitem_review_needed"), + ] + + operations = [ + migrations.AlterField( + model_name="stockitem", + name="level", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="stockitem", + name="lft", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="stockitem", + name="rght", + field=models.PositiveIntegerField(default=0), + ), + migrations.AlterField( + model_name="stockitem", + name="tree_id", + field=models.PositiveIntegerField(db_index=True, default=0), + ), + ] diff --git a/src/backend/InvenTree/stock/migrations/0125_remove_mptt_fields.py b/src/backend/InvenTree/stock/migrations/0125_remove_mptt_fields.py new file mode 100644 index 0000000000..fdb3559da9 --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0125_remove_mptt_fields.py @@ -0,0 +1,41 @@ +# Generated by Django 5.2.15 on 2026-07-11 03:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("stock", "0124_alter_mptt_fields"), + ] + + operations = [ + migrations.RemoveField( + model_name="stockitem", + name="level", + ), + migrations.RemoveField( + model_name="stockitem", + name="lft", + ), + migrations.RemoveField( + model_name="stockitem", + name="rght", + ), + migrations.RemoveField( + model_name="stockitem", + name="tree_id", + ), + migrations.AlterField( + model_name="stockitem", + name="parent", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=models.deletion.SET_NULL, + related_name="children", + to="stock.stockitem", + verbose_name="Parent Stock Item", + ), + ), + ] diff --git a/src/backend/InvenTree/stock/migrations/0126_serial_number_concurrency_guard.py b/src/backend/InvenTree/stock/migrations/0126_serial_number_concurrency_guard.py new file mode 100644 index 0000000000..e1f2295f45 --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0126_serial_number_concurrency_guard.py @@ -0,0 +1,34 @@ +# Generated by Django 5.2.16 on 2026-07-27 08:58 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("build", "0059_build_tags"), + ("company", "0080_company_tags"), + ("order", "0121_add_line_item_discount"), + ("part", "0152_alter_partpricing_currency"), + ("stock", "0125_remove_mptt_fields"), + ( + "taggit", + "0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx", + ), + ("users", "0015_alter_userprofile_type"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddConstraint( + model_name="stockitem", + constraint=models.UniqueConstraint( + condition=models.Q( + ("serial__isnull", False), models.Q(("serial", ""), _negated=True) + ), + fields=("part", "serial"), + name="stock_item_unique_part_serial", + ), + ), + ] diff --git a/src/backend/InvenTree/stock/migrations/0127_alter_stockitemtestresult_options.py b/src/backend/InvenTree/stock/migrations/0127_alter_stockitemtestresult_options.py new file mode 100644 index 0000000000..6246926911 --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0127_alter_stockitemtestresult_options.py @@ -0,0 +1,25 @@ +# Generated by Django 5.2.16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("stock", "0126_serial_number_concurrency_guard"), + ] + + operations = [ + migrations.AlterModelOptions( + name="stockitemtestresult", + options={ + "ordering": ( + "-finished_datetime", + "-started_datetime", + "-date", + "-pk", + ), + "verbose_name": "Stock Item Test Result", + }, + ), + ] diff --git a/src/backend/InvenTree/stock/models.py b/src/backend/InvenTree/stock/models.py index 040daee86e..47182b0687 100644 --- a/src/backend/InvenTree/stock/models.py +++ b/src/backend/InvenTree/stock/models.py @@ -2,7 +2,9 @@ from __future__ import annotations +import contextvars import os +from contextlib import contextmanager from datetime import timedelta from decimal import Decimal, InvalidOperation @@ -11,7 +13,7 @@ from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator from django.db import models, transaction -from django.db.models import Q, QuerySet, Sum +from django.db.models import Q, QuerySet, Sum, UniqueConstraint from django.db.models.functions import Coalesce from django.db.models.signals import post_delete, post_save from django.db.utils import IntegrityError, OperationalError @@ -23,7 +25,6 @@ import structlog from djmoney.contrib.exchange.models import convert_money from mptt.managers import TreeManager from mptt.models import TreeForeignKey -from taggit.managers import TaggableManager import build.models import common.models @@ -34,13 +35,14 @@ import InvenTree.ready import InvenTree.tasks import order.models import report.mixins -import stock.tasks from common.icons import validate_icon from common.settings import get_global_setting from company import models as CompanyModels +from generic.enums import StringEnum from generic.states import StatusCodeMixin from generic.states.fields import InvenTreeCustomStatusModelField from InvenTree.fields import InvenTreeModelMoneyField, InvenTreeURLField +from InvenTree.helpers_db import bulk_create_and_fetch from InvenTree.status_codes import ( SalesOrderStatusGroups, StockHistoryCode, @@ -125,6 +127,7 @@ class StockLocation( InvenTree.models.PluginValidationMixin, InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeBarcodeMixin, + InvenTree.models.InvenTreeTagsMixin, report.mixins.InvenTreeReportMixin, InvenTree.models.PathStringMixin, InvenTree.models.MetadataMixin, @@ -148,8 +151,6 @@ class StockLocation( verbose_name = _('Stock Location') verbose_name_plural = _('Stock Locations') - tags = TaggableManager(blank=True) - def delete(self, *args, **kwargs): """Custom model deletion routine, which updates any child locations or items. @@ -226,6 +227,7 @@ class StockLocation( ) @property + @report.mixins.report_attribute() def icon(self) -> str: """Get the current icon used for this location. @@ -324,7 +326,8 @@ class StockLocation( return self.get_stock_items(cascade).count() @property - def item_count(self): + @report.mixins.report_attribute() + def item_count(self) -> int: """Simply returns the number of stock items in this location. Required for tree view serializer. @@ -399,16 +402,37 @@ class StockItemReportContext(report.mixins.BaseReportContext): test_templates: dict[str, PartModels.PartTestTemplate] +class StockSortOrder(StringEnum): + """Enum of ORM sort fields available for stock auto-allocation.""" + + DATE_OLDEST = 'updated' + DATE_NEWEST = '-updated' + QUANTITY_ASC = 'quantity' + QUANTITY_DESC = '-quantity' + EXPIRY_SOONEST = 'expiry_date' + + +STOCK_SORT_CHOICES = [ + (StockSortOrder.DATE_OLDEST, _('Oldest stock first (FIFO)')), + (StockSortOrder.DATE_NEWEST, _('Newest stock first (LIFO)')), + (StockSortOrder.QUANTITY_ASC, _('Smallest quantity first')), + (StockSortOrder.QUANTITY_DESC, _('Largest quantity first')), + (StockSortOrder.EXPIRY_SOONEST, _('Soonest expiry date first')), +] + +STOCK_SORT_DEFAULT = StockSortOrder.DATE_OLDEST + + class StockItem( - InvenTree.models.PluginValidationMixin, InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNotesMixin, + InvenTree.models.InvenTreeTagsMixin, StatusCodeMixin, report.mixins.InvenTreeReportMixin, common.models.MetaMixin, InvenTree.models.MetadataMixin, - InvenTree.models.InvenTreeTree, + InvenTree.models.InvenTreeModel, ): """A StockItem object represents a quantity of physical instances of a part. @@ -421,11 +445,11 @@ class StockItem( batch: Batch number for this StockItem serial: Unique serial number for this StockItem link: Optional URL to link to external resource - updated: Date that this stock item was last updated (auto) + creation_date: Date that this stock item was created (auto) + updated: Date that the quantity of this stock item was last updated (auto) expiry_date: Expiry date of the StockItem (optional) stocktake_date: Date of last stocktake for this item stocktake_user: User that performed the most recent stocktake - review_needed: Flag if StockItem needs review delete_on_deplete: If True, StockItem will be deleted when the stock level gets to zero status: Status of this StockItem (ref: stock.status_codes.StockStatus) notes: Extra notes field @@ -444,6 +468,23 @@ class StockItem( """Model meta options.""" verbose_name = _('Stock Item') + constraints = [ + # Baseline, database-enforced duplicate-serial guard: a given Part + # can never have two StockItem rows sharing the same serial number. + # This alone does not cover the "unique across a Part variant tree" + # (or globally-unique) semantics controlled by the + # SERIAL_NUMBER_GLOBALLY_UNIQUE setting - see + # StockItem._lock_serial_numbers() for that; a UniqueConstraint + # cannot reference the joined Part.tree_id field. + UniqueConstraint( + fields=['part', 'serial'], + # Non-serialized StockItems may store serial as either NULL or + # '' depending on the creation path - exclude both, since + # "no serial" is not a value this constraint should govern + condition=Q(serial__isnull=False) & ~Q(serial=''), + name='stock_item_unique_part_serial', + ) + ] class MPTTMeta: """MPTT metaclass options.""" @@ -528,6 +569,9 @@ class StockItem( def delete(self, ignore_serial_check: bool = False, **kwargs): """Custom delete method for StockItem model. + Any child items are re-linked to the parent of this item, + to preserve the stock item genealogy chain. + Arguments: ignore_serial_check: If True, allow deletion of serialized stock items regardless of global setting """ @@ -537,22 +581,32 @@ class StockItem( if self.serialized: raise ValidationError(_('Serialized stock items cannot be deleted')) - super().delete(**kwargs) + with transaction.atomic(): + # Re-link any child items to the parent of this item, + # so the genealogy chain survives deletion of an intermediate item + + parent = StockItem.objects.filter(pk=self.parent_id).first() + StockItem.objects.filter(parent=self).update(parent=parent) + + super().delete(**kwargs) @staticmethod def get_api_url(): """Return API url.""" return reverse('api-stock-list') - def api_instance_filters(self): - """Custom API instance filters.""" - return {'parent': {'exclude_tree': self.pk}} - @classmethod def barcode_model_type_code(cls): """Return the associated barcode model type code for this model.""" return 'SI' + def get_children(self): + """Return a queryset of all StockItem objects which are direct children of this StockItem. + + Simply proxies the reverse foreign-key relation for the 'parent' field. + """ + return self.children.all() + def get_test_keys(self, include_installed=True): """Construct a flattened list of test 'keys' for this StockItem.""" keys = [] @@ -597,8 +651,6 @@ class StockItem( 'test_templates': self.part.getTestTemplateMap(), } - tags = TaggableManager(blank=True) - # A Query filter which will be reused in multiple places to determine if a StockItem is actually "in stock" # See also: StockItem.in_stock() method IN_STOCK_FILTER = Q( @@ -620,7 +672,68 @@ class StockItem( & Q(expiry_date__lt=InvenTree.helpers.current_date()) ) + @staticmethod + def _lock_serial_numbers(part: PartModels.Part, serials: list) -> None: + """Serialize concurrent serial number creation, and re-validate under the lock. + + Must be called from within an atomic transaction. Serial number + uniqueness is scoped by the SERIAL_NUMBER_GLOBALLY_UNIQUE setting - + either across an entire Part variant tree (the default), or globally. + That scope depends on Part.tree_id, which is not a field on + StockItem, so it cannot be expressed as a database-level + UniqueConstraint on StockItem directly (a UniqueConstraint cannot + reference a joined field). Instead, this select_for_update()s + existing rows that already represent the relevant scope - every Part + in the tree, or (for the globally-unique case, where there is no + single tree to lock) the SERIAL_NUMBER_GLOBALLY_UNIQUE setting's own + row - so concurrent creation attempts within the same scope + serialize against each other. It then re-checks for conflicts + against StockItem while holding that lock. This closes the race + where two concurrent requests both read "no conflict" before either + has committed its creation. + + Raises: + ValidationError: If any of the provided serial numbers now conflict + """ + if get_global_setting('SERIAL_NUMBER_GLOBALLY_UNIQUE', False): + # There is no single Part tree covering "globally unique" - lock + # the setting's own row instead, so all concurrent global-scope + # creation attempts serialize against each other regardless of + # which part is involved. This row is guaranteed to already + # exist: reaching this branch means the setting is currently + # True, which can only happen if it was explicitly set (and + # therefore persisted) at some point. + setting, _created = common.models.InvenTreeSetting.objects.get_or_create( + key='SERIAL_NUMBER_GLOBALLY_UNIQUE', defaults={'value': str(True)} + ) + common.models.InvenTreeSetting.objects.select_for_update().get( + pk=setting.pk + ) + else: + # Lock every Part in this variant tree (this always includes + # 'part' itself), so concurrent creation attempts for any part in + # the same tree serialize against each other + list( + PartModels.Part.objects + .select_for_update() + .filter(tree_id=part.tree_id) + .order_by('pk') + ) + + # Re-validate for conflicts now that the lock is held - any + # concurrent request for the same scope has either already committed + # (and will now show up here) or is blocked behind this lock (and + # will see this request's result once it releases) + conflicts = part.find_conflicting_serial_numbers(serials) + + if conflicts: + msg = _('The following serial numbers already exist or are invalid') + msg += ' : ' + msg += ','.join(str(x) for x in conflicts) + raise ValidationError({'serial_numbers': msg}) + @classmethod + @transaction.atomic def _create_serial_numbers(cls, serials: list, **kwargs) -> QuerySet: """Create multiple stock items with the provided serial numbers. @@ -637,8 +750,11 @@ class StockItem( This method uses bulk_create to create multiple StockItem objects in a single query, which is much more efficient than creating them one-by-one. - However, it does not perform any validation checks on the provided serial numbers, - and also does not generate any "stock tracking entries". + Concurrent calls for an overlapping set of serial numbers are + serialized against each other (see _lock_serial_numbers()), so unlike + other validation checks, this method's duplicate-serial protection is + safe even when the caller's own pre-check raced against another + request. It does not generate any "stock tracking entries". Note: This is an 'internal' function and should not be used by external code / plugins. """ @@ -687,20 +803,13 @@ class StockItem( if 'part' not in data: raise ValidationError({'part': _('Part must be specified')}) - part = data['part'] + # Serialize against any other concurrent request creating an + # overlapping set of serial numbers, and re-validate under that lock + cls._lock_serial_numbers(data['part'], serials) parent = kwargs.pop('parent', None) or data.get('parent') - tree_id = kwargs.pop('tree_id', StockItem.getNextTreeID()) - if parent: - # Override with parent's tree_id if provided - tree_id = parent.tree_id - - # Pre-calculate MPTT fields - data['parent'] = parent if parent else None - data['level'] = parent.level + 1 if parent else 0 - data['lft'] = 0 if parent else 1 - data['rght'] = 0 if parent else 2 + data['parent'] = parent # Force single quantity for each item data['quantity'] = 1 @@ -713,29 +822,17 @@ class StockItem( else: data['serial_int'] = 0 - data['tree_id'] = tree_id - - if not parent: - # No parent, this is a top-level item, so increment the tree_id - # This is because each new item is a "top-level" node in the StockItem tree - tree_id += 1 - # Construct a new StockItem from the provided dict items.append(StockItem(**data)) # Create the StockItem objects in bulk - StockItem.objects.bulk_create(items, batch_size=250) - - # We will need to rebuild the stock item tree manually, due to the bulk_create operation - if parent and parent.tree_id: - # Rebuild the tree structure for this StockItem tree - logger.info( - 'Rebuilding StockItem tree structure for tree_id: %s', parent.tree_id - ) - stock.tasks.rebuild_stock_item_tree(parent.tree_id) - - # Fetch the new StockItem objects from the database - items = StockItem.objects.filter(part=part, serial__in=serials) + # (the IntegrityError catch is a defense-in-depth backstop against + # the database-level UniqueConstraint - _lock_serial_numbers() above + # should already have ruled out any conflict) + try: + items = bulk_create_and_fetch(StockItem, items) + except IntegrityError as exc: + raise ValidationError({'serial_numbers': str(exc)}) from exc # Trigger a 'created' event for the new items # Note that instead of a single event for each item, @@ -756,24 +853,24 @@ class StockItem( # First, let any plugins convert this serial number to an integer value # If a non-null value is returned (by any plugin) we will use that + if not InvenTree.ready.isReadOnlyCommand(): + for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): + try: + serial_int = plugin.convert_serial_to_int(serial) + except Exception: + InvenTree.exceptions.log_error( + 'convert_serial_to_int', plugin=plugin.slug + ) + serial_int = None - for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): - try: - serial_int = plugin.convert_serial_to_int(serial) - except Exception: - InvenTree.exceptions.log_error( - 'convert_serial_to_int', plugin=plugin.slug - ) - serial_int = None - - # Save the first returned result - if serial_int is not None: - # Ensure that it is clipped within a range allowed in the database schema - clip = 0x7FFFFFFF - serial_int = abs(serial_int) - serial_int = min(serial_int, clip) - # Return the first non-null value - return serial_int + # Save the first returned result + if serial_int is not None: + # Ensure that it is clipped within a range allowed in the database schema + clip = 0x7FFFFFFF + serial_int = abs(serial_int) + serial_int = min(serial_int, clip) + # Return the first non-null value + return serial_int # None of the plugins provided a valid integer value if serial not in [None, '']: @@ -861,7 +958,8 @@ class StockItem( return self.get_next_serialized_item(reverse=True) @property - def status_label(self): + @report.mixins.report_attribute() + def status_label(self) -> str: """Return label.""" return StockStatus.label(self.status) @@ -899,15 +997,16 @@ class StockItem( """ from plugin import PluginMixinEnum, registry - for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): - try: - plugin.validate_batch_code(self.batch, self) - except ValidationError as exc: - raise ValidationError({'batch': exc.message}) - except Exception: - InvenTree.exceptions.log_error( - 'validate_batch_code', plugin=plugin.slug - ) + if not InvenTree.ready.isReadOnlyCommand(): + for plugin in registry.with_mixin(PluginMixinEnum.VALIDATION): + try: + plugin.validate_batch_code(self.batch, self) + except ValidationError as exc: + raise ValidationError({'batch': exc.message}) + except Exception: + InvenTree.exceptions.log_error( + 'validate_batch_code', plugin=plugin.slug + ) def clean(self): """Validate the StockItem object (separate to field validation). @@ -936,11 +1035,19 @@ class StockItem( if type(self.batch) is str: self.batch = self.batch.strip() - if not get_global_setting('STOCK_ALLOW_EDIT_SERIAL'): - deltas = self.get_field_deltas() - + if not get_global_setting('STOCK_ALLOW_EDIT_SERIAL') and self.pk: # Prevent editing of serial numbers if the item already has a serial number assigned - if 'serial' in deltas and deltas['serial']['old'] not in [None, '']: + # Note: A targeted single-column lookup is used here (rather than get_field_deltas(), + # which fetches and diffs *every* field, dereferencing every non-null FK in the + # process) since only the previous 'serial' value is actually needed. + old_serial = ( + StockItem.objects + .filter(pk=self.pk) + .values_list('serial', flat=True) + .first() + ) + + if old_serial not in [None, ''] and old_serial != self.serial: raise ValidationError({ 'serial': _( 'Editing of serial numbers is not allowed - this item has already been assigned a serial number' @@ -1041,11 +1148,11 @@ class StockItem( """Returns part name.""" return self.part.full_name - # Note: When a StockItem is deleted, a pre_delete signal handles the parent/child relationship - parent = TreeForeignKey( - 'self', + # Note: When a StockItem is deleted, child items are re-linked to its parent (see delete()) + parent = models.ForeignKey( + 'stock.StockItem', verbose_name=_('Parent Stock Item'), - on_delete=models.DO_NOTHING, + on_delete=models.SET_NULL, blank=True, null=True, related_name='children', @@ -1205,7 +1312,14 @@ class StockItem( related_name='stocktake_stock', ) - review_needed = models.BooleanField(default=False) + creation_date = models.DateTimeField( + null=True, + blank=True, + auto_now_add=True, + editable=False, + verbose_name=_('Creation Date'), + help_text=_('Date that this stock item was created'), + ) delete_on_deplete = models.BooleanField( default=default_delete_on_deplete, @@ -1358,6 +1472,7 @@ class StockItem( # Delete outstanding BuildOrder allocations self.allocations.all().delete() + @transaction.atomic def allocateToCustomer( self, customer, quantity=None, order=None, user=None, notes=None ): @@ -1374,9 +1489,20 @@ class StockItem( user: User that performed the action notes: Notes field """ - if quantity is None: + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + raise ValidationError(_('Stock item no longer exists')) + + if quantity is None or self.serialized: quantity = self.quantity + # Cannot allocate more than the available quantity + # (also ensures the recorded history matches the actual allocation) + quantity = min(quantity, self.quantity) + + if quantity <= 0: + raise ValidationError({'quantity': _('Quantity must be greater than zero')}) + if quantity >= self.quantity: item = self else: @@ -1643,6 +1769,53 @@ class StockItem( """Return the quantity of this StockItem which is *not* allocated.""" return max(self.quantity - self.allocation_count(), 0) + @staticmethod + def bulk_allocation_count(stock_items) -> dict: + """Bulk-compute the total allocated quantity (builds + sales orders + transfer orders) for a set of StockItem objects. + + Mirrors the per-instance calculation in `allocation_count()`, but resolves the whole + set in 3 aggregate queries (one per allocation type) rather than one query per + allocation type *per item* - critical for validating requests which reference many + stock items at once. + + Returns: + A {stock_item.pk: total_allocated_quantity} dict. Items with no allocations + of any kind are omitted (i.e. callers should default missing pks to zero). + """ + pks = [item.pk for item in stock_items] + + totals = {} + + def _accumulate(queryset, group_field): + rows = queryset.values(group_field).annotate( + total=Coalesce(Sum('quantity'), Decimal(0)) + ) + for row in rows: + pk = row[group_field] + totals[pk] = totals.get(pk, Decimal(0)) + row['total'] + + _accumulate( + build.models.BuildItem.objects.filter(stock_item__in=pks), 'stock_item' + ) + + _accumulate( + order.models.SalesOrderAllocation.objects.filter( + item__in=pks, + line__order__status__in=SalesOrderStatusGroups.OPEN, + shipment__shipment_date=None, + ), + 'item', + ) + + _accumulate( + order.models.TransferOrderAllocation.objects.filter( + item__in=pks, line__order__status__in=TransferOrderStatusGroups.OPEN + ), + 'item', + ) + + return totals + def can_delete(self): """Can this stock item be deleted? @@ -1651,11 +1824,25 @@ class StockItem( - Is installed inside another StockItem - It has been assigned to a SalesOrder - It has been assigned to a BuildOrder + - It has active allocations against a SalesOrder or TransferOrder + - It is referenced by a ReturnOrder line item """ if self.installed_item_count() > 0: return False - return self.sales_order is None + if self.sales_order is not None: + return False + + if self.allocations.exists(): + return False + + if self.get_sales_order_allocations(active=True).exists(): + return False + + if self.get_transfer_order_allocations(active=True).exists(): + return False + + return not self.return_order_lines.exists() def get_installed_items(self, cascade: bool = False) -> set[StockItem]: """Return all stock items which are *installed* in this one! @@ -1706,6 +1893,22 @@ class StockItem( notes: Any notes associated with the operation build: The BuildOrder to associate with the operation (optional) """ + # Lock the database row, so concurrent adjustments are serialized + if not other_item.lock_quantity(): + raise ValidationError(_('Stock item no longer exists')) + + try: + quantity = Decimal(quantity) + except (InvalidOperation, TypeError): + raise ValidationError({'quantity': _('Invalid quantity value')}) + + if quantity <= 0: + raise ValidationError({'quantity': _('Quantity must be greater than zero')}) + + # Cannot install more than the available quantity + # (also ensures the recorded history matches the actual installation) + quantity = min(quantity, other_item.quantity) + # If the quantity is less than the stock item, split the stock! stock_item = other_item.splitStock(quantity, None, user) @@ -1758,6 +1961,11 @@ class StockItem( if self.belongs_to is None: return False + if location and location.structural: + raise ValidationError({ + 'location': _('Cannot assign stock to structural location') + }) + # Add a transaction note to the parent item self.belongs_to.add_tracking_entry( StockHistoryCode.REMOVED_CHILD_ITEM, @@ -1786,10 +1994,275 @@ class StockItem( self.save() - @property - def children(self): - """Return a list of the child items which have been split from this stock item.""" - return self.get_descendants(include_self=False) + def allocate_disassembly_pricing(self, quantity, lines: list) -> list: + """Allocate the purchase price of this stock item across disassembly lines. + + Automatic cost allocation is only performed if: + - This stock item has a recorded purchase price + - None of the provided lines specify an explicit purchase price + + The total cost is apportioned across the lines pro-rata, + weighted by existing pricing data for each component part. + If pricing data is not available for *every* line, + the cost is split evenly across the generated units. + + Args: + quantity: The number of units of this stock item being disassembled + lines: A list of dict objects (see the disassemble method) + + Returns: + The list of lines, with 'purchase_price' values filled in where possible + """ + if not self.purchase_price: + return lines + + if any(line.get('purchase_price') is not None for line in lines): + # Explicit pricing has been provided - do not override + return lines + + # Calculate a relative pricing "weight" for each line + weights = [] + + for line in lines: + pricing = line['bom_item'].sub_part.pricing + + price_range = [ + price + for price in [pricing.overall_min, pricing.overall_max] + if price is not None + ] + + weight = None + + if price_range: + mid = sum(price_range[1:], price_range[0]) / len(price_range) + + if mid.amount > 0: + weight = Decimal(mid.amount) * Decimal(line['quantity']) + + weights.append(weight) + + if any(weight is None for weight in weights): + # Insufficient pricing data - fall back to an even (per unit) split + weights = [Decimal(line['quantity']) for line in lines] + + total_weight = sum(weights) + + if total_weight <= 0: + return lines + + # Total cost of the disassembled units + total_cost = self.purchase_price * quantity + + for line, weight in zip(lines, weights, strict=True): + line_quantity = Decimal(line['quantity']) + + if line_quantity > 0: + if weight is None: + # Fallback to an even split + line['purchase_price'] = total_cost / len(lines) / line_quantity + else: + line['purchase_price'] = ( + total_cost * (weight / total_weight) / line_quantity + ) + + return lines + + @transaction.atomic + def disassemble( + self, quantity, lines: list, user, location=None, notes: str = '' + ) -> list[StockItem]: + """Disassemble this stock item into its component parts. + + The provided BOM lines determine which component parts are "broken out" + of this stock item. A new stock item is created for each line, + and the quantity of this item is reduced accordingly. + + Args: + quantity: The number of units of this stock item to disassemble + lines: A list of dict objects, each containing: + bom_item: The BomItem instance defining the component to break out + quantity: The total quantity of the component to create + location: Optional destination StockLocation for the component + status: Optional StockStatus code for the component (default: OK) + purchase_price: Optional unit purchase price for the component + user: The user performing the operation + location: Default destination location for the generated components + notes: Optional transaction notes + + Returns: + A list of the component StockItem objects (created or uninstalled) + + Note: + This stock item is *retained* (with reduced quantity) even if the + quantity reaches zero, to preserve traceability of the disassembly. + + Note: + Any stock items which are *installed* within this stock item are + broken out (uninstalled) as part of the disassembly operation, + rather than creating new stock items for them. + + Note: + Traceability data is passed down from this stock item to the + generated components: the batch code and source purchase order + are copied across, while any source build order is recorded + in the stock tracking history of each component. + """ + try: + quantity = Decimal(quantity) + except (InvalidOperation, ValueError): + raise ValidationError({'quantity': _('Invalid quantity provided')}) + + if quantity <= 0: + raise ValidationError({'quantity': _('Quantity must be greater than zero')}) + + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + raise ValidationError(_('Stock item no longer exists')) + + if quantity > self.quantity: + raise ValidationError({ + 'quantity': _('Quantity must not exceed available stock quantity') + }) + + if self.serialized and quantity != self.quantity: + raise ValidationError({ + 'quantity': _( + 'Serialized stock item must be disassembled in its entirety' + ) + }) + + if len(lines) == 0: + raise ValidationError(_('No BOM lines provided')) + + # Any items installed within this stock item *must* be broken out, + # which requires that the entire quantity is disassembled + installed_items = list(self.installed_parts.all()) + + if len(installed_items) > 0 and quantity != self.quantity: + raise ValidationError({ + 'quantity': _( + 'Stock item with installed items must be disassembled in its entirety' + ) + }) + + # Cache the custom status options for the StockItem model + custom_status_values = StockItem.STATUS_CLASS.custom_values() + + items = [] + + # Match installed items against the provided BOM lines, + # so that the correct location and status values can be applied + line_map = {} + + for line in lines: + for part in line['bom_item'].get_valid_parts_for_allocation(): + line_map.setdefault(part.pk, line) + + for installed_item in installed_items: + line = line_map.get(installed_item.part.pk) + + destination = ( + (line.get('location') if line else None) or location or self.location + ) + + if line: + # The uninstalled quantity reduces the quantity of new items + # to be created against the matching BOM line + line['quantity'] = max( + Decimal(0), Decimal(line['quantity']) - installed_item.quantity + ) + + if status := line.get('status'): + installed_item.set_status( + status, custom_values=custom_status_values + ) + + # Break the installed item out into the destination location + # Note: this also saves any status change applied above + installed_item.uninstall_into_location(destination, user, notes) + + items.append(installed_item) + + # Allocate pricing data across the generated components. + # Note: Deliberately performed *after* the installed items are uninstalled, + # so that the cost is only spread across newly created stock items + lines = self.allocate_disassembly_pricing(quantity, lines) + + for line in lines: + bom_item = line['bom_item'] + line_quantity = Decimal(line['quantity']) + + if line_quantity <= 0: + continue + + destination = line.get('location') or location or self.location + + new_item = StockItem( + part=bom_item.sub_part, + quantity=line_quantity, + location=destination, + parent=self, + batch=self.batch, + purchase_order=self.purchase_order, + purchase_price=line.get('purchase_price', None), + ) + + if status := line.get('status'): + new_item.set_status(status, custom_values=custom_status_values) + + # Ensure the tree structure is observed + new_item.save(add_note=False) + + deltas = {'stockitem': self.pk, 'quantity': float(line_quantity)} + + # Record traceability links against the disassembled assembly + if self.build: + deltas['buildorder'] = self.build.pk + + if self.purchase_order: + deltas['purchaseorder'] = self.purchase_order.pk + + new_item.add_tracking_entry( + StockHistoryCode.CREATED_FROM_DISASSEMBLY, + user, + notes=notes, + deltas=deltas, + location=destination, + ) + + items.append(new_item) + + # Consume this stock item. + # Note: the item is deliberately retained (not deleted) at zero quantity, + # to preserve the disassembly history + if self.serialized: + # A serialized item cannot be reduced to zero quantity, + # so instead it is marked as "destroyed" + deltas = { + 'removed': float(quantity), + 'status': StockStatus.DESTROYED.value, + 'old_status': self.status, + } + + self.set_status(StockStatus.DESTROYED.value) + else: + deltas = { + 'removed': float(quantity), + 'quantity': float(self.quantity - quantity), + } + + self.quantity = self.quantity - quantity + + self.save(add_note=False) + + self.add_tracking_entry( + StockHistoryCode.DISASSEMBLED, user, notes=notes, deltas=deltas + ) + + trigger_event(StockEvents.ITEM_DISASSEMBLED, id=self.pk) + + return items @property def child_count(self): @@ -1894,11 +2367,8 @@ class StockItem( ): return None - # Has a location been specified? - location = kwargs.get('location') - - if location: - deltas['location'] = location.id + # Extract any additional information from the kwargs + self._apply_model_reference_fields(kwargs, deltas) # Quantity specified? quantity = kwargs.get('quantity') @@ -1906,8 +2376,11 @@ class StockItem( if quantity: deltas['quantity'] = float(quantity) + # If this item has already been deleted (e.g. depleted via delete_on_deplete), + # self.pk is None - Django refuses to save a FK pointing at an unsaved instance, + # even for a nullable/SET_NULL field, so pass None explicitly instead of self. entry = StockItemTracking( - item=self, + item=self if self.pk else None, part=self.part, tracking_type=entry_type.value, user=user, @@ -1917,7 +2390,11 @@ class StockItem( ) if commit: - entry.save() + if (batch := _tracking_batch.get()) is not None: + # A batch_tracking_entries() context is active - queue rather than save now + batch.add(entry) + else: + entry.save() return entry @@ -1962,6 +2439,10 @@ class StockItem( if quantity <= 0: raise ValidationError({'quantity': _('Quantity must be greater than zero')}) + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + raise ValidationError(_('Stock item no longer exists')) + if quantity > self.quantity: raise ValidationError({ 'quantity': _( @@ -2001,7 +2482,6 @@ class StockItem( # Set the parent ID correctly data['parent'] = self - data['tree_id'] = self.tree_id # Generate a new serial number for each item items = StockItem._create_serial_numbers(serials, **data) @@ -2009,7 +2489,18 @@ class StockItem( # Create a new tracking entry for each item history_items = [] + # Every new item shares this exact part - avoid a redundant per-item + # part_id -> Part lookup (bulk_create_and_fetch() does not preserve the + # cached FK) by seeding each item's cache with the instance we already have + part = self.part + + # Check (once) whether there are any test results to copy across, rather + # than re-querying an identical (and usually empty) result set per item + has_test_results = self.test_results.exists() + for item in items: + item.part = part + # Construct tracking entries for the new StockItem if entry := item.add_tracking_entry( StockHistoryCode.SPLIT_FROM_PARENT, @@ -2032,7 +2523,8 @@ class StockItem( history_items.append(entry) # Copy any test results from this item to the new one - item.copyTestResultsFrom(self) + if has_test_results: + item.copyTestResultsFrom(self) StockItemTracking.objects.bulk_create(history_items, batch_size=250) @@ -2179,6 +2671,40 @@ class StockItem( return True + def find_merge_target(self, location): + """Find an existing stock item at location that can absorb this item.""" + if location is None: + return None + + # This item must itself be in a state which allows merging + # (e.g. not serialized, in production, installed, or assigned to an order / customer) + if not self.can_merge(): + return None + + candidates = list( + StockItem.objects + .filter(part=self.part, location=location) + .exclude(pk=self.pk) + .order_by('pk') + ) + + if not candidates: + return None + + if self.batch: + batch_matches = [c for c in candidates if c.batch == self.batch] + search_order = batch_matches + [ + c for c in candidates if c not in batch_matches + ] + else: + search_order = candidates + + for target in search_order: + if target.can_merge(other=self, raise_error=False): + return target + + return None + @transaction.atomic def merge_stock_items(self, other_items, raise_error=False, **kwargs): """Merge another stock item into this one; the two become one! @@ -2195,12 +2721,32 @@ class StockItem( if len(other_items) == 0: return - # Keep track of the tree IDs that are being merged - tree_ids = {self.tree_id} + # Lock all database rows (in pk order, to avoid deadlocks between + # concurrent merges) and refresh the quantity of each item + items_to_merge = sorted([self, *other_items], key=lambda item: item.pk) + + locked_quantities = dict( + StockItem.objects + .select_for_update() + .filter(pk__in=[item.pk for item in items_to_merge]) + .values_list('pk', 'quantity') + ) + + for item in items_to_merge: + if item.pk not in locked_quantities: + if raise_error: + raise ValidationError(_('Stock item no longer exists')) + + logger.warning( + 'Stock item <%s> no longer exists - merge cancelled', item.pk + ) + return + + item.quantity = locked_quantities[item.pk] user = kwargs.get('user') location = kwargs.get('location', self.location) - notes = kwargs.get('notes') + notes = kwargs.get('notes') or '' parent_id = self.parent.pk if self.parent else None @@ -2211,16 +2757,21 @@ class StockItem( pricing_data.append([self.purchase_price, self.quantity]) for other in other_items: - # If the stock item cannot be merged, return - if not self.can_merge(other, raise_error=raise_error, **kwargs): + # Check the merge in both directions, so that the generic state checks + # (serialized, in production, installed, assigned to an order / customer) + # are applied to the incoming items as well as this one + if not self.can_merge( + other, raise_error=raise_error, **kwargs + ) or not other.can_merge(self, raise_error=raise_error, **kwargs): logger.warning( - 'Stock item <%s> could not be merge into <%s>', other.pk, self.pk + 'Stock item <%s> could not be merged into <%s>', other.pk, self.pk ) return - for other in other_items: - tree_ids.add(other.tree_id) + merged_quantity = Decimal(0) + for other in other_items: + merged_quantity += other.quantity self.quantity += other.quantity if other.purchase_price: @@ -2244,15 +2795,24 @@ class StockItem( other.delete() + transfer_deltas = kwargs.pop('transfer_deltas', None) + + tracking_deltas = { + 'quantity': float(self.quantity), + 'added': float(merged_quantity), + } + + self._apply_model_reference_fields(kwargs, tracking_deltas) + + if transfer_deltas: + tracking_deltas.update(transfer_deltas) + self.add_tracking_entry( StockHistoryCode.MERGED_STOCK_ITEMS, user, quantity=self.quantity, notes=notes, - deltas={ - 'location': location.pk if location else None, - 'quantity': self.quantity, - }, + deltas=tracking_deltas, ) # Update the location of the item @@ -2282,19 +2842,6 @@ class StockItem( self.save() - # Rebuild stock trees as required - rebuild_result = True - for tree_id in tree_ids: - if not stock.tasks.rebuild_stock_item_tree(tree_id, rebuild_on_fail=False): - rebuild_result = False - - if not rebuild_result: - # If the rebuild failed, offload the task to a background worker - logger.warning( - 'Failed to rebuild stock item tree during merge_stock_items operation, offloading task.' - ) - InvenTree.tasks.offload_task(stock.tasks.rebuild_stock_items, group='stock') - @transaction.atomic def splitStock(self, quantity, location=None, user=None, **kwargs): """Split this stock item into two items, in the same location. @@ -2313,9 +2860,13 @@ class StockItem( status: If provided, override the status (default = existing status) packaging: If provided, override the packaging (default = existing packaging) allow_production: If True, allow splitting of stock which is in production (default = False) + record_tracking: If False, skip tracking entries (for merge-on-transfer) + split_transfer_deltas: Optional dict to receive split tracking deltas + copy_test_results: If True, copy test results from this item to the new one (default = True) Returns: - The new StockItem object + The new StockItem object, or None if no split occurred (e.g. invalid + quantity, or this item is serialized) Raises: ValidationError: If the stock item cannot be split @@ -2323,106 +2874,97 @@ class StockItem( - The provided quantity will be subtracted from this item and given to the new one. - The new item will have a different StockItem ID, while this will remain the same. """ + # Do not split a serialized part + if self.serialized: + return None + # Run initial checks to test if the stock item can actually be "split" allow_production = kwargs.get('allow_production', False) + record_tracking = kwargs.pop('record_tracking', True) + split_transfer_deltas = kwargs.pop('split_transfer_deltas', None) # Cannot split a stock item which is in production if self.is_building and not allow_production: raise ValidationError(_('Stock item is currently in production')) - notes = kwargs.get('notes', '') - - # Do not split a serialized part - if self.serialized: - return self - try: + # Exit early if the provided quantity is invalid quantity = Decimal(quantity) except (InvalidOperation, ValueError): - return self + logger.error( + 'StockItem<%s>.split_stock - invalid quantity (%s)', self.pk, quantity + ) + InvenTree.exceptions.log_error('StockItem.split_stock') + return None # Doesn't make sense for a zero quantity if quantity <= 0: - return self + return None + + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + return None # Also doesn't make sense to split the full amount if quantity >= self.quantity: - return self + return None # Create a new StockItem object, duplicating relevant fields # Nullify the PK so a new record is created new_stock = StockItem.objects.get(pk=self.pk) new_stock.pk = None new_stock.quantity = quantity + new_stock.location = location or self.location # Update the new stock item to ensure the tree structure is observed new_stock.parent = self - new_stock.tree_id = None - - # Move to the new location if specified, otherwise use current location - if location: - new_stock.location = location - else: - new_stock.location = self.location + # Create 'deltas' dict to record changes for tracking deltas = {'stockitem': self.pk} - transferorder = kwargs.pop('transferorder', None) - if transferorder: - deltas['transferorder'] = transferorder.pk + new_stock._apply_model_reference_fields(kwargs, deltas) + + status = new_stock._resolve_status_kwarg(kwargs) + new_stock._apply_status_change(status, deltas) # Optional fields which can be supplied in a 'move' call - for field in StockItem.optional_transfer_fields(): - if field in kwargs: - # handle specific case for status deltas - if field == 'status': - status = kwargs[field] - if not new_stock.compare_status(status): - old_custom_status = new_stock.get_custom_status() - old_status_logical = new_stock.status - new_stock.set_status(status) - deltas['status'] = status # may be a custom value - deltas['status_logical'] = ( - new_stock.status - ) # always the logical value - deltas['old_status'] = ( - old_custom_status - if old_custom_status - else old_status_logical - ) - deltas['old_status_logical'] = old_status_logical - else: - setattr(new_stock, field, kwargs[field]) - deltas[field] = kwargs[field] + new_stock._apply_optional_transfer_fields(kwargs, deltas) new_stock.save(add_note=False) - # Add a stock tracking entry for the newly created item - new_stock.add_tracking_entry( - StockHistoryCode.SPLIT_FROM_PARENT, - user, - quantity=quantity, - notes=notes, - location=location, - deltas=deltas, - ) + if split_transfer_deltas is not None: + split_transfer_deltas.clear() + split_transfer_deltas.update(deltas) + + if location: + split_transfer_deltas['location'] = location.pk + + if record_tracking: + # Add a stock tracking entry for the newly created item + new_stock.add_tracking_entry( + StockHistoryCode.SPLIT_FROM_PARENT, + user, + quantity=quantity, + notes=kwargs.get('notes', ''), + location=location, + deltas=deltas, + ) # Copy the test results of this part to the new one - new_stock.copyTestResultsFrom(self) + if kwargs.get('copy_test_results', True): + new_stock.copyTestResultsFrom(self) # Remove the specified quantity from THIS stock item self.take_stock( quantity, user, code=StockHistoryCode.SPLIT_CHILD_ITEM, - notes=notes, + notes=kwargs.get('notes', ''), location=location, stockitem=new_stock, + record_tracking=record_tracking, ) - # Rebuild the tree for this parent item - stock.tasks.rebuild_stock_item_tree(self.tree_id) - # Attempt to reload the new item from the database try: new_stock.refresh_from_db() @@ -2439,6 +2981,76 @@ class StockItem( """Returns a list of optional fields for a stock transfer.""" return ['batch', 'status', 'packaging'] + @classmethod + def model_reference_fields(cls): + """Returns a list of optional 'reference' fields for a stock adjustment. + + If present, the referenced model is recorded (by pk) in the tracking deltas, + linking the resulting tracking entry back to the order which triggered it. + """ + return [ + 'stockitem', + 'stockitemlocation', + 'transferorder', + 'purchaseorder', + 'salesorder', + 'returnorder', + 'buildorder', + ] + + def _apply_model_reference_fields(self, kwargs: dict, deltas: dict) -> None: + """Pop any model reference kwargs (see model_reference_fields) and record their pk in deltas.""" + for field in StockItem.model_reference_fields(): + instance = deltas.pop(field, None) or kwargs.pop(field, None) + + if instance is None: + continue + elif hasattr(instance, 'pk'): + deltas[field] = instance.pk + else: + deltas[field] = instance + + def _resolve_status_kwarg(self, kwargs: dict): + """Pop a status value from kwargs, preferring 'status' over 'status_custom_key'. + + Returns: + The resolved status value, or None if neither key was provided (or truthy) + """ + return kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) + + def _apply_status_change(self, status, deltas: dict) -> None: + """Apply a status change to this StockItem, recording delta information. + + Args: + status: The new status value (may be a custom status key) + deltas: A dict to update with delta information (mutated in place) + """ + if not status or self.compare_status(status): + return + + old_custom_status = self.get_custom_status() + old_status_logical = self.status + self.set_status(status) + + deltas['status'] = status # may be a custom value + deltas['status_logical'] = self.status # always the logical value + deltas['old_status'] = ( + old_custom_status if old_custom_status else old_status_logical + ) + deltas['old_status_logical'] = old_status_logical + + def _apply_optional_transfer_fields(self, kwargs: dict, deltas: dict) -> None: + """Apply optional transfer fields (see optional_transfer_fields) from kwargs.""" + for field in StockItem.optional_transfer_fields(): + if field in kwargs: + setattr(self, field, kwargs[field]) + + # If the provided value is a model instance, store the primary key in the deltas dict + if hasattr(kwargs[field], 'pk'): + deltas[field] = kwargs[field].pk + else: + deltas[field] = kwargs[field] + @transaction.atomic def move(self, location, notes, user, **kwargs): """Move part to a new location. @@ -2461,6 +3073,10 @@ class StockItem( """ current_location = self.location + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + return False + try: quantity = Decimal(kwargs.pop('quantity', self.quantity)) except InvalidOperation: @@ -2488,9 +3104,11 @@ class StockItem( kwargs['notes'] = notes # Split the existing StockItem in two - self.splitStock(quantity, location, user, allow_production=True, **kwargs) + new_stock = self.splitStock( + quantity, location, user, allow_production=True, **kwargs + ) - return True + return new_stock is not None # Moving into the same location triggers a different history code same_location = location == self.location @@ -2506,28 +3124,12 @@ class StockItem( else: tracking_info['location'] = location.pk - status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) - - if status and not self.compare_status(status): - old_custom_status = self.get_custom_status() - old_status_logical = self.status - self.set_status(status) - tracking_info['status'] = status # may be a custom value - tracking_info['status_logical'] = self.status # always the logical value - tracking_info['old_status'] = ( - old_custom_status if old_custom_status else old_status_logical - ) - tracking_info['old_status_logical'] = old_status_logical - - transferorder = kwargs.pop('transferorder', None) - if transferorder: - tracking_info['transferorder'] = transferorder.pk + status = self._resolve_status_kwarg(kwargs) + self._apply_status_change(status, tracking_info) + self._apply_model_reference_fields(kwargs, tracking_info) # Optional fields which can be supplied in a 'move' call - for field in StockItem.optional_transfer_fields(): - if field in kwargs: - setattr(self, field, kwargs[field]) - tracking_info[field] = kwargs[field] + self._apply_optional_transfer_fields(kwargs, tracking_info) self.add_tracking_entry(tracking_code, user, notes=notes, deltas=tracking_info) @@ -2544,6 +3146,37 @@ class StockItem( return True + def lock_quantity(self) -> bool: + """Acquire a database row-level lock on this StockItem. + + Once the lock is held, the 'quantity' field is refreshed from the database, + so that read-modify-write adjustments operate on the current committed value + rather than a (potentially stale) in-memory copy. + + Note: Must be called from within a database transaction, + and the lock is held until that transaction completes. + + Returns: + False if this StockItem no longer exists in the database. + """ + if not self.pk: + return False + + quantity = ( + StockItem.objects + .select_for_update() + .filter(pk=self.pk) + .values_list('quantity', flat=True) + .first() + ) + + if quantity is None: + return False + + self.quantity = quantity + + return True + @transaction.atomic def updateQuantity(self, quantity): """Update stock quantity for this item. @@ -2553,18 +3186,23 @@ class StockItem( Returns: - True if the quantity was saved - False if the StockItem was deleted + - None if the provided quantity was invalid, or the item is serialized """ # Do not adjust quantity of a serialized part if self.serialized: return try: - self.quantity = Decimal(quantity) + quantity = Decimal(quantity) except (InvalidOperation, ValueError): return quantity = max(quantity, 0) + # No change if the quantity is the same as the current quantity + if self.quantity == quantity: + return + self.quantity = quantity if quantity == 0 and self.delete_on_deplete and self.can_delete(): @@ -2581,7 +3219,7 @@ class StockItem( return True @transaction.atomic - def stocktake(self, count, user, **kwargs): + def stocktake(self, count, user, **kwargs) -> None: """Perform item stocktake. Arguments: @@ -2591,60 +3229,91 @@ class StockItem( Keyword Arguments: notes: Optional notes for the stocktake status: Optionally adjust the stock status + location: Optionally set the stock location """ try: count = Decimal(count) except InvalidOperation: - return False + return if count < 0: return False + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + return False + tracking_info = {} - status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) + location = kwargs.pop('location', None) - if status and not self.compare_status(status): - old_custom_status = self.get_custom_status() - old_status_logical = self.status - self.set_status(status) - tracking_info['status'] = status # may be a custom value - tracking_info['status_logical'] = self.status # always the logical value - tracking_info['old_status'] = ( - old_custom_status if old_custom_status else old_status_logical - ) - tracking_info['old_status_logical'] = old_status_logical + if location and location != self.location: + old_location = self.location + self.location = location + tracking_info['location'] = location.pk + tracking_info['old_location'] = old_location.pk if old_location else None - if self.updateQuantity(count): - tracking_info['quantity'] = float(count) + status = self._resolve_status_kwarg(kwargs) + self._apply_status_change(status, tracking_info) + # Optional fields which can be supplied in a 'stocktake' call + self._apply_optional_transfer_fields(kwargs, tracking_info) + + # Have any fields (other than quantity) been updated? + # Must be determined *before* model reference deltas are extracted, + # as those only affect the tracking entry (not the model instance) + fields_updated = len(tracking_info) > 0 + + self._apply_model_reference_fields(kwargs, tracking_info) + + # Will updateQuantity() below actually change (and therefore save) the row? + # Mirrors updateQuantity()'s own change check - used to decide whether the + # stocktake stamp can ride along on that save, avoiding a second write. + quantity_will_change = not self.serialized and count != self.quantity + + # Stamp the stocktake metadata *before* updating the quantity, so that when + # updateQuantity() performs its own save (below), this stamp - and the status/ + # location/reference field changes already applied above - are written in that + # single query, rather than needing a second, otherwise-redundant save() after. + if fields_updated or self.serialized or quantity_will_change: self.stocktake_date = InvenTree.helpers.current_date() self.stocktake_user = user - # Optional fields which can be supplied in a 'stocktake' call - for field in StockItem.optional_transfer_fields(): - if field in kwargs: - setattr(self, field, kwargs[field]) - tracking_info[field] = kwargs[field] + raw_update_result = None if self.serialized else self.updateQuantity(count) + quantity_updated = self.serialized or raw_update_result - self.save(add_note=False) + # True only if updateQuantity() actually performed the save above + # (as opposed to: serialized item, no change, or item deleted) + update_persisted = raw_update_result is True - self.add_tracking_entry( - StockHistoryCode.STOCK_COUNT, - user, - notes=kwargs.get('notes', ''), - deltas=tracking_info, + # Record the resulting quantity, whether or not this item survived the stocktake + # (self.quantity is updated by updateQuantity() even if the item was deleted) + tracking_info['quantity'] = 1 if self.serialized else float(self.quantity) + + # Save if the quantity or any other field was changed, and updateQuantity() + # didn't already do so above. + # Note that updateQuantity() may have *deleted* the item (depleted to zero), + # in which case there is nothing left to save. + if self.pk and (quantity_updated or fields_updated): + if not update_persisted: + self.save(add_note=False) + + trigger_event( + StockEvents.ITEM_COUNTED, + id=self.id, + quantity=1 if self.serialized else float(self.quantity), ) - trigger_event( - StockEvents.ITEM_COUNTED, - 'stockitem.counted', - id=self.id, - quantity=float(self.quantity), + # Always record a tracking entry, even if the item was deleted as a result + # of this stocktake (e.g. counted to zero with delete_on_deplete set) - + # StockItemTracking.item uses SET_NULL so the history is retained regardless. + self.add_tracking_entry( + StockHistoryCode.STOCK_COUNT, + user, + notes=kwargs.get('notes', ''), + deltas=tracking_info, ) - return True - @transaction.atomic def add_stock(self, quantity, user, **kwargs): """Add a specified quantity of stock to this item. @@ -2670,32 +3339,33 @@ class StockItem( if quantity <= 0: return False + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + return False + tracking_info = {} - status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) + status = self._resolve_status_kwarg(kwargs) + self._apply_status_change(status, tracking_info) + self._apply_model_reference_fields(kwargs, tracking_info) - if status and not self.compare_status(status): - old_custom_status = self.get_custom_status() - old_status_logical = self.status - self.set_status(status) - tracking_info['status'] = status # may be a custom value - tracking_info['status_logical'] = self.status # always the logical value - tracking_info['old_status'] = ( - old_custom_status if old_custom_status else old_status_logical - ) - tracking_info['old_status_logical'] = old_status_logical + # Determine up-front whether any optional fields will actually change, + # so we can skip the second save() below when updateQuantity() (which + # already writes the full row, including the status/reference field + # changes applied above) has already persisted everything that matters. + optional_fields_changed = any( + field in kwargs for field in StockItem.optional_transfer_fields() + ) if self.updateQuantity(self.quantity + quantity): tracking_info['added'] = float(quantity) tracking_info['quantity'] = float(self.quantity) # Optional fields which can be supplied in a 'stocktake' call - for field in StockItem.optional_transfer_fields(): - if field in kwargs: - setattr(self, field, kwargs[field]) - tracking_info[field] = kwargs[field] + self._apply_optional_transfer_fields(kwargs, tracking_info) - self.save(add_note=False) + if optional_fields_changed: + self.save(add_note=False) self.add_tracking_entry( StockHistoryCode.STOCK_ADD, @@ -2718,7 +3388,10 @@ class StockItem( code: The stock history code to use notes: Optional notes for the stock removal status: Optionally adjust the stock status + record_tracking: If False, skip creating a tracking entry """ + record_tracking = kwargs.pop('record_tracking', True) + # Cannot remove items from a serialized part if self.serialized: return False @@ -2728,46 +3401,49 @@ class StockItem( except InvalidOperation: return False + # Cannot remove more than the available quantity + # (also ensures the recorded history matches the actual removal) + quantity = min(quantity, self.quantity) + if quantity <= 0: return False + # Lock the database row, so concurrent adjustments are serialized + if not self.lock_quantity(): + return False + deltas = {} - status = kwargs.pop('status', None) or kwargs.pop('status_custom_key', None) + status = self._resolve_status_kwarg(kwargs) + self._apply_status_change(status, deltas) + self._apply_model_reference_fields(kwargs, deltas) - if status and not self.compare_status(status): - old_custom_status = self.get_custom_status() - old_status_logical = self.status - self.set_status(status) - deltas['status'] = status # may be a custom value - deltas['status_logical'] = self.status # always the logical value - deltas['old_status'] = ( - old_custom_status if old_custom_status else old_status_logical - ) - deltas['old_status_logical'] = old_status_logical + # Determine up-front whether any optional fields will actually change, + # so we can skip the second save() below when updateQuantity() (which + # already writes the full row, including the status/reference field + # changes applied above) has already persisted everything that matters. + optional_fields_changed = any( + field in kwargs for field in StockItem.optional_transfer_fields() + ) - if self.updateQuantity(self.quantity - quantity): - deltas['removed'] = float(quantity) - deltas['quantity'] = float(self.quantity) + quantity_updated = self.updateQuantity(self.quantity - quantity) - if location := kwargs.get('location'): - deltas['location'] = location.pk - - if stockitem := kwargs.get('stockitem'): - deltas['stockitem'] = stockitem.pk + # Record the resulting quantity, whether or not this item survived the removal + # (self.quantity is updated by updateQuantity() even if the item was deleted) + deltas['removed'] = float(quantity) + deltas['quantity'] = float(self.quantity) + if quantity_updated: # Optional fields which can be supplied in a 'stocktake' call - for field in StockItem.optional_transfer_fields(): - if field in kwargs: - setattr(self, field, kwargs[field]) - deltas[field] = kwargs[field] + self._apply_optional_transfer_fields(kwargs, deltas) - transferorder = kwargs.pop('transferorder', None) - if transferorder: - deltas['transferorder'] = transferorder.pk - - self.save(add_note=False) + if optional_fields_changed: + self.save(add_note=False) + # Always record a tracking entry, even if the item was deleted as a result + # of this removal (e.g. depleted to zero with delete_on_deplete set) - + # StockItemTracking.item uses SET_NULL so the history is retained regardless. + if record_tracking: self.add_tracking_entry( code, user, notes=kwargs.get('notes', ''), deltas=deltas ) @@ -2917,12 +3593,43 @@ class StockItem( def after_delete_stock_item(sender, instance: StockItem, **kwargs): """Function to be executed after a StockItem object is deleted.""" from part import tasks as part_tasks + from part.models import Part if InvenTree.ready.isImportingData(): return + try: + base_part = instance.part + except Part.DoesNotExist: + return + + if not base_part: + # Base part does not exist, or has been deleted + return + if InvenTree.ready.canAppAccessDatabase(allow_test=True): # Run this check in the background + InvenTree.tasks.offload_task( + part_tasks.notify_low_stock_if_required, + base_part.pk, + group='notification', + force_async=True, + ) + + if InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING): + # Schedule an update on parent part pricing + base_part.schedule_pricing_update(create=False) + + +@receiver(post_save, sender=StockItem, dispatch_uid='stock_item_post_save_log') +def after_save_stock_item(sender, instance: StockItem, created, **kwargs): + """Hook function to be executed after StockItem object is saved/updated.""" + from part import tasks as part_tasks + + if InvenTree.ready.isImportingData() or InvenTree.ready.isRunningMigrations(): + return + + if InvenTree.ready.canAppAccessDatabase(allow_test=True): InvenTree.tasks.offload_task( part_tasks.notify_low_stock_if_required, instance.part.pk, @@ -2931,28 +3638,74 @@ def after_delete_stock_item(sender, instance: StockItem, **kwargs): ) if InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING): - # Schedule an update on parent part pricing if instance.part: - instance.part.schedule_pricing_update(create=False) + instance.part.schedule_pricing_update(create=True) -@receiver(post_save, sender=StockItem, dispatch_uid='stock_item_post_save_log') -def after_save_stock_item(sender, instance: StockItem, created, **kwargs): - """Hook function to be executed after StockItem object is saved/updated.""" - from part import tasks as part_tasks +# Context-local batch of pending StockItemTracking entries (see batch_tracking_entries()) +_tracking_batch: contextvars.ContextVar = contextvars.ContextVar( + 'tracking_batch', default=None +) - if not InvenTree.ready.isImportingData(): - if InvenTree.ready.canAppAccessDatabase(allow_test=True): - InvenTree.tasks.offload_task( - part_tasks.notify_low_stock_if_required, - instance.part.pk, - group='notification', - force_async=True, - ) - if InvenTree.ready.canAppAccessDatabase(allow_test=settings.TESTING_PRICING): - if instance.part: - instance.part.schedule_pricing_update(create=True) +class TrackingEntryBatch: + """Collects StockItemTracking entries created within a batch_tracking_entries() scope.""" + + def __init__(self): + """Initialize an empty batch.""" + self.entries: list[StockItemTracking] = [] + + def add(self, entry: StockItemTracking) -> None: + """Record a single (unsaved) tracking entry against this batch.""" + self.entries.append(entry) + + def flush(self) -> None: + """Bulk-create all entries collected so far, in a single database write.""" + entries, self.entries = self.entries, [] + + if entries: + StockItemTracking.objects.bulk_create(entries, batch_size=250) + + +@contextmanager +def batch_tracking_entries(): + """Batch StockItemTracking entries created within this scope into a single bulk_create(). + + StockItem.add_tracking_entry() saves its entry immediately by default (commit=True). + While this context is active, any such call - made directly, or indirectly via a nested + function call - is queued instead of saved immediately. The queued entries are flushed via + a single bulk_create() when the current transaction commits (or immediately, if no + transaction is active). If the transaction is instead rolled back, the queued entries are + discarded, rather than being written for a change that never happened. + + Calls that already pass commit=False to add_tracking_entry() are unaffected either way - + that contract (the caller takes ownership of saving/collecting the entry itself, as done + for example in PurchaseOrder.receive_line_items()) is unchanged. + + Nesting is not supported: a nested batch_tracking_entries() call reuses the outer batch, + and only the outermost call schedules a flush. + + This mirrors plugin.base.event.events.batch_events() - see that docstring for the + reasoning behind the on-commit flush and the context-local (rather than parameter-based) + design, which allows existing single-item entrypoints (e.g. StockItem.stocktake()) to be + reused unmodified by both single-item and bulk callers. + + Yields: + The current TrackingEntryBatch instance + """ + if _tracking_batch.get() is not None: + # Already inside a batch - extend it, rather than creating a nested one + yield _tracking_batch.get() + return + + batch = TrackingEntryBatch() + token = _tracking_batch.set(batch) + + try: + yield batch + finally: + _tracking_batch.reset(token) + transaction.on_commit(batch.flush) class StockItemTracking(InvenTree.models.InvenTreeModel): @@ -3067,6 +3820,8 @@ class StockItemTestResult(InvenTree.models.InvenTreeMetadataModel): verbose_name = _('Stock Item Test Result') + ordering = ('-finished_datetime', '-started_datetime', '-date', '-pk') + def __str__(self): """Return string representation.""" return f'{self.test_name} - {self.result}' diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py index 570b4f7e51..4e10db879a 100644 --- a/src/backend/InvenTree/stock/serializers.py +++ b/src/backend/InvenTree/stock/serializers.py @@ -31,13 +31,17 @@ import stock.status_codes from common.settings import get_global_setting from generic.states.fields import InvenTreeCustomStatusSerializerMixin from importer.registry import register_importer +from InvenTree.fields import PrefetchedPrimaryKeyRelatedField from InvenTree.mixins import DataImportExportSerializerMixin from InvenTree.serializers import ( + CustomStatusSerializerMixin, InvenTreeCurrencySerializer, InvenTreeDecimalField, OptionalField, TreePathSerializer, ) +from InvenTree.tasks import batch_offload_tasks +from plugin.base.event.events import batch_events from users.serializers import UserSerializer from .models import ( @@ -46,6 +50,7 @@ from .models import ( StockItemTracking, StockLocation, StockLocationType, + batch_tracking_entries, ) logger = structlog.get_logger('inventree') @@ -308,10 +313,12 @@ class StockItemTestResultSerializer( @register_importer() class StockItemSerializer( + CustomStatusSerializerMixin, InvenTree.serializers.FilterableSerializerMixin, DataImportExportSerializerMixin, InvenTreeCustomStatusSerializerMixin, - InvenTree.serializers.InvenTreeTagModelSerializer, + InvenTree.serializers.InvenTreeTaggitSerializer, + InvenTree.serializers.InvenTreeModelSerializer, ): """Serializer for a StockItem. @@ -371,8 +378,9 @@ class StockItemSerializer( 'SKU', 'MPN', 'barcode_hash', - 'updated', + 'creation_date', 'stocktake_date', + 'updated', 'purchase_price', 'purchase_price_currency', 'use_pack_size', @@ -395,6 +403,7 @@ class StockItemSerializer( read_only_fields = [ 'allocated', 'barcode_hash', + 'creation_date', 'stocktake_date', 'stocktake_user', 'updated', @@ -563,10 +572,6 @@ class StockItemSerializer( return queryset - status_text = serializers.CharField( - source='get_status_display', read_only=True, label=_('Status') - ) - SKU = serializers.CharField( source='supplier_part.SKU', read_only=True, @@ -808,16 +813,22 @@ class SerializeStockItemSerializer(serializers.Serializer): part=item.part, ) - return ( - item.serializeStock( - data['quantity'], - serials, - user=user, - notes=data.get('notes', ''), - location=data['destination'], + with ( + transaction.atomic(), + batch_events(), + batch_tracking_entries(), + batch_offload_tasks(), + ): + return ( + item.serializeStock( + data['quantity'], + serials, + user=user, + notes=data.get('notes', ''), + location=data['destination'], + ) + or [] ) - or [] - ) class InstallStockItemSerializer(serializers.Serializer): @@ -927,6 +938,15 @@ class UninstallStockItemSerializer(serializers.Serializer): allow_blank=True, ) + def validate_location(self, location): + """Validate the provided location.""" + if location and location.structural: + raise ValidationError( + _('Structural locations cannot be assigned stock items') + ) + + return location + def save(self): """Uninstall stock item.""" item = self.context.get('item') @@ -944,6 +964,227 @@ class UninstallStockItemSerializer(serializers.Serializer): item.uninstall_into_location(location, request.user, note) +class StockStatusCustomSerializer(serializers.ChoiceField): + """Serializer to allow annotating the schema to use int where custom values may be entered.""" + + def __init__(self, *args, **kwargs): + """Initialize the status selector.""" + if 'choices' not in kwargs: + kwargs['choices'] = stock.status_codes.StockStatus.items(custom=True) + + if 'label' not in kwargs: + kwargs['label'] = _('Status') + + if 'help_text' not in kwargs: + kwargs['help_text'] = _('Stock item status code') + + if InvenTree.ready.isGeneratingSchema(): + kwargs['help_text'] = ( + kwargs['help_text'] + + '\n\n' + + '\n'.join( + f'* `{value}` - {label}' for value, label in kwargs['choices'] + ) + + "\n\nAdditional custom status keys may be retrieved from the 'stock_status_retrieve' call." + ) + + super().__init__(*args, **kwargs) + + +class DisassemblyLineSerializer(serializers.Serializer): + """Serializer for a single component line in a stock disassembly operation.""" + + class Meta: + """Metaclass options.""" + + fields = [ + 'bom_item', + 'quantity', + 'location', + 'status', + 'purchase_price', + 'purchase_price_currency', + ] + + bom_item = serializers.PrimaryKeyRelatedField( + queryset=part_models.BomItem.objects.all(), + many=False, + required=True, + allow_null=False, + label=_('BOM Item'), + help_text=_('BOM line which defines the component part to break out'), + ) + + quantity = serializers.DecimalField( + max_digits=15, + decimal_places=5, + min_value=Decimal(0), + required=True, + label=_('Quantity'), + help_text=_('Quantity of the component part to create'), + ) + + def validate_quantity(self, quantity): + """Validation for the 'quantity' field.""" + if quantity <= 0: + raise ValidationError(_('Quantity must be greater than zero')) + + return quantity + + location = serializers.PrimaryKeyRelatedField( + queryset=StockLocation.objects.all(), + many=False, + allow_null=True, + required=False, + label=_('Location'), + help_text=_('Destination location for the component items'), + ) + + status = StockStatusCustomSerializer( + required=False, help_text=_('Status code for the component items') + ) + + purchase_price = InvenTree.serializers.InvenTreeMoneySerializer( + label=_('Purchase Price'), + required=False, + allow_null=True, + default=None, + help_text=_( + 'Unit purchase price for the component items (leave blank for automatic cost allocation)' + ), + ) + + purchase_price_currency = InvenTreeCurrencySerializer( + required=False, help_text=_('Purchase price currency') + ) + + +class DisassembleStockItemSerializer(serializers.Serializer): + """DRF serializer class for disassembling a StockItem into component parts. + + Note: The stock item being disassembled is provided via the serializer context + """ + + class Meta: + """Metaclass options.""" + + fields = ['items', 'quantity', 'location', 'notes'] + + items = DisassemblyLineSerializer(many=True) + + quantity = serializers.DecimalField( + max_digits=15, + decimal_places=5, + min_value=Decimal(0), + required=True, + label=_('Quantity'), + help_text=_('Number of assemblies to disassemble'), + ) + + def validate_quantity(self, quantity): + """Validation for the 'quantity' field.""" + item = self.context.get('item') + + if not item: + raise ValidationError(_('No stock item provided')) + + if quantity <= 0: + raise ValidationError(_('Quantity must be greater than zero')) + + if quantity > item.quantity: + raise ValidationError( + _('Quantity must not exceed available stock quantity') + + f' ({item.quantity})' + ) + + return quantity + + location = serializers.PrimaryKeyRelatedField( + queryset=StockLocation.objects.all(), + many=False, + allow_null=True, + required=False, + label=_('Location'), + help_text=_('Default destination location for the component items'), + ) + + notes = serializers.CharField( + required=False, + allow_blank=True, + label=_('Notes'), + help_text=_('Optional note field'), + ) + + def validate(self, data): + """Validate the disassembly operation. + + - The stock item must be "in stock" + - Each line must reference a valid BOM item for the part + - Each BOM item may only be referenced once + """ + data = super().validate(data) + + item = self.context.get('item') + + if not item: + raise ValidationError(_('No stock item provided')) + + if not item.in_stock: + raise ValidationError(_('Stock item is unavailable')) + + items = data.get('items', []) + + if len(items) == 0: + raise ValidationError(_('Line items must be provided')) + + # The set of valid BOM items for this part. + # Consumable BOM lines (and lines pointing to a virtual part) are excluded, + # as these components are not expected to be tracked as physical stock + bom_items = item.part.get_bom_items(include_virtual=False).filter( + part_models.BomItem.consumable_filter(consumable=False) + ) + + bom_item_pks = set() + + for line in items: + bom_item = line['bom_item'] + + if not bom_items.filter(pk=bom_item.pk).exists(): + raise ValidationError( + _('BOM item is not valid for the selected stock item') + ) + + if bom_item.pk in bom_item_pks: + raise ValidationError(_('Duplicate BOM items provided')) + + bom_item_pks.add(bom_item.pk) + + return data + + def save(self) -> list[StockItem]: + """Disassemble the provided StockItem into its component parts. + + Returns: + A list of StockItem objects created by the disassembly operation. + """ + item = self.context['item'] + request = self.context.get('request') + + data = self.validated_data + + try: + return item.disassemble( + data['quantity'], + data['items'], + request.user if request else None, + location=data.get('location', None), + notes=data.get('notes', ''), + ) + except DjangoValidationError as exc: + # Catch model errors and re-throw as DRF errors + raise ValidationError(detail=serializers.as_serializer_error(exc)) + + class ConvertStockItemSerializer(serializers.Serializer): """DRF serializer class for converting a StockItem to a valid variant part.""" @@ -1007,33 +1248,6 @@ class ConvertStockItemSerializer(serializers.Serializer): help_text='Status key, chosen from the list of StockStatus keys' ) ) -class StockStatusCustomSerializer(serializers.ChoiceField): - """Serializer to allow annotating the schema to use int where custom values may be entered.""" - - def __init__(self, *args, **kwargs): - """Initialize the status selector.""" - if 'choices' not in kwargs: - kwargs['choices'] = stock.status_codes.StockStatus.items(custom=True) - - if 'label' not in kwargs: - kwargs['label'] = _('Status') - - if 'help_text' not in kwargs: - kwargs['help_text'] = _('Stock item status code') - - if InvenTree.ready.isGeneratingSchema(): - kwargs['help_text'] = ( - kwargs['help_text'] - + '\n\n' - + '\n'.join( - f'* `{value}` - {label}' for value, label in kwargs['choices'] - ) - + "\n\nAdditional custom status keys may be retrieved from the 'stock_status_retrieve' call." - ) - - super().__init__(*args, **kwargs) - - class StockChangeStatusSerializer(serializers.Serializer): """Serializer for changing status of multiple StockItem objects.""" @@ -1159,7 +1373,18 @@ class LocationTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer): """Metaclass options.""" model = StockLocation - fields = ['pk', 'name', 'parent', 'icon', 'structural', 'sublocations'] + fields = [ + 'pk', + 'name', + 'description', + 'pathstring', + 'parent', + 'tree_id', + 'level', + 'icon', + 'structural', + 'sublocations', + ] sublocations = serializers.IntegerField(label=_('Sublocations'), read_only=True) @@ -1194,7 +1419,8 @@ class LocationDeleteSerializer(serializers.Serializer): class LocationSerializer( InvenTree.serializers.FilterableSerializerMixin, DataImportExportSerializerMixin, - InvenTree.serializers.InvenTreeTagModelSerializer, + InvenTree.serializers.InvenTreeTaggitSerializer, + InvenTree.serializers.InvenTreeModelSerializer, ): """Detailed information about a stock location.""" @@ -1635,7 +1861,7 @@ class StockAdjustmentItemSerializer(serializers.Serializer): class Meta: """Metaclass options.""" - fields = ['pk', 'quantity', 'batch', 'status', 'packaging'] + fields = ['pk', 'quantity', 'batch', 'status', 'packaging', 'merge'] def __init__(self, *args, **kwargs): """Initialize the serializer.""" @@ -1646,7 +1872,8 @@ class StockAdjustmentItemSerializer(serializers.Serializer): super().__init__(*args, **kwargs) - pk = serializers.PrimaryKeyRelatedField( + pk = PrefetchedPrimaryKeyRelatedField( + cache_key='_stockitems', queryset=StockItem.objects.all(), many=False, allow_null=False, @@ -1709,6 +1936,15 @@ class StockAdjustmentItemSerializer(serializers.Serializer): help_text=_('Packaging this stock item is stored in'), ) + merge = serializers.BooleanField( + default=False, + required=False, + label=_('Merge into existing stock'), + help_text=_( + 'Merge this item into existing stock at the destination if possible' + ), + ) + class StockAdjustmentSerializer(serializers.Serializer): """Base class for managing stock adjustment actions via the API.""" @@ -1727,6 +1963,30 @@ class StockAdjustmentSerializer(serializers.Serializer): help_text=_('Stock transaction notes'), ) + def to_internal_value(self, data): + """Bulk-fetch referenced StockItem objects before per-item validation. + + Populates the '_stockitems' context cache that PrefetchedPrimaryKeyRelatedField + looks up against, avoiding one .get() query per item in the 'items' list. + """ + pks = set() + + for item in data.get('items', []): + try: + pks.add(int(item.get('pk'))) + except (TypeError, ValueError): + pass + + if pks: + self.context['_stockitems'] = { + obj.pk: obj + for obj in StockItem.objects.filter(pk__in=pks).select_related( + 'part', 'location' + ) + } + + return super().to_internal_value(data) + def validate(self, data): """Make sure items are provided.""" super().validate(data) @@ -1736,12 +1996,39 @@ class StockAdjustmentSerializer(serializers.Serializer): if len(items) == 0: raise ValidationError(_('A list of stock items must be provided')) + # Process items in stable (pk) order, so that concurrent multi-item + # requests acquire database row locks in the same order (deadlock avoidance) + data['items'] = sorted(items, key=lambda entry: entry['pk'].pk) + return data class StockCountSerializer(StockAdjustmentSerializer): """Serializer for counting stock items.""" + class Meta: + """Metaclass options.""" + + fields = ['items', 'notes', 'location'] + + location = serializers.PrimaryKeyRelatedField( + queryset=StockLocation.objects.filter(), + many=False, + required=False, + allow_null=True, + label=_('Location'), + help_text=_('Set stock location for counted items (optional)'), + ) + + def validate_location(self, location): + """Validate the provided location.""" + if location and location.structural: + raise ValidationError( + _('Structural locations cannot be assigned stock items') + ) + + return location + def save(self): """Count stock.""" request = self.context['request'] @@ -1749,8 +2036,14 @@ class StockCountSerializer(StockAdjustmentSerializer): data = self.validated_data items = data['items'] notes = data.get('notes', '') + location = data.get('location', None) - with transaction.atomic(): + with ( + transaction.atomic(), + batch_events(), + batch_tracking_entries(), + batch_offload_tasks(), + ): for item in items: stock_item = item['pk'] quantity = item['quantity'] @@ -1762,6 +2055,9 @@ class StockCountSerializer(StockAdjustmentSerializer): if field_value := item.get(field_name, None): extra[field_name] = field_value + if location is not None: + extra['location'] = location + stock_item.stocktake(quantity, request.user, notes=notes, **extra) @@ -1775,7 +2071,12 @@ class StockAddSerializer(StockAdjustmentSerializer): data = self.validated_data notes = data.get('notes', '') - with transaction.atomic(): + with ( + transaction.atomic(), + batch_events(), + batch_tracking_entries(), + batch_offload_tasks(), + ): for item in data['items']: stock_item = item['pk'] quantity = item['quantity'] @@ -1804,7 +2105,12 @@ class StockRemoveSerializer(StockAdjustmentSerializer): data = self.validated_data notes = data.get('notes', '') - with transaction.atomic(): + with ( + transaction.atomic(), + batch_events(), + batch_tracking_entries(), + batch_offload_tasks(), + ): for item in data['items']: stock_item = item['pk'] quantity = item['quantity'] @@ -1834,7 +2140,7 @@ class StockTransferSerializer(StockAdjustmentSerializer): items = StockAdjustmentItemSerializer(many=True, require_non_zero=True) location = serializers.PrimaryKeyRelatedField( - queryset=StockLocation.objects.filter(structural=False), + queryset=StockLocation.objects.filter(), many=False, required=True, allow_null=False, @@ -1842,6 +2148,15 @@ class StockTransferSerializer(StockAdjustmentSerializer): help_text=_('Destination stock location'), ) + def validate_location(self, location): + """Validate the provided location.""" + if location and location.structural: + raise ValidationError( + _('Structural locations cannot be assigned stock items') + ) + + return location + def save(self): """Transfer stock.""" request = self.context['request'] @@ -1852,11 +2167,17 @@ class StockTransferSerializer(StockAdjustmentSerializer): notes = data.get('notes', '') location = data['location'] - with transaction.atomic(): + with ( + transaction.atomic(), + batch_events(), + batch_tracking_entries(), + batch_offload_tasks(), + ): for item in items: # Required fields stock_item = item['pk'] quantity = item['quantity'] + merge = item.get('merge', False) # Optional fields kwargs = {} @@ -1865,6 +2186,51 @@ class StockTransferSerializer(StockAdjustmentSerializer): if field_value := item.get(field_name, None): kwargs[field_name] = field_value + if merge: + target = stock_item.find_merge_target(location) + + if target: + merge_kwargs = { + 'location': location, + 'notes': notes, + 'user': request.user, + **kwargs, + } + + if quantity < stock_item.quantity: + transfer_deltas = {} + + piece = stock_item.splitStock( + quantity, + location, + request.user, + notes=notes, + allow_production=True, + record_tracking=False, + split_transfer_deltas=transfer_deltas, + **kwargs, + ) + + if not piece: + continue + + merge_kwargs['transfer_deltas'] = transfer_deltas + target.merge_stock_items([piece], **merge_kwargs) + else: + transfer_deltas = {'stockitem': stock_item.pk} + + if location: + transfer_deltas['location'] = location.pk + + for field_name in StockItem.optional_transfer_fields(): + if field_name in kwargs: + transfer_deltas[field_name] = kwargs[field_name] + + merge_kwargs['transfer_deltas'] = transfer_deltas + target.merge_stock_items([stock_item], **merge_kwargs) + + continue + stock_item.move( location, notes, request.user, quantity=quantity, **kwargs ) @@ -1883,7 +2249,7 @@ class StockReturnSerializer(StockAdjustmentSerializer): ) location = serializers.PrimaryKeyRelatedField( - queryset=StockLocation.objects.filter(structural=False), + queryset=StockLocation.objects.filter(), many=False, required=True, allow_null=False, @@ -1891,6 +2257,15 @@ class StockReturnSerializer(StockAdjustmentSerializer): help_text=_('Destination stock location'), ) + def validate_location(self, location): + """Validate the provided location.""" + if location and location.structural: + raise ValidationError( + _('Structural locations cannot be assigned stock items') + ) + + return location + merge = serializers.BooleanField( default=False, required=False, diff --git a/src/backend/InvenTree/stock/status_codes.py b/src/backend/InvenTree/stock/status_codes.py index 50cad87a90..8f92a630b8 100644 --- a/src/backend/InvenTree/stock/status_codes.py +++ b/src/backend/InvenTree/stock/status_codes.py @@ -75,6 +75,10 @@ class StockHistoryCode(StatusCode): # Stock merging operations MERGED_STOCK_ITEMS = 45, _('Merged stock items') + # Stock disassembly operations + DISASSEMBLED = 46, _('Disassembled into components') + CREATED_FROM_DISASSEMBLY = 47, _('Created from disassembly') + # Convert stock item to variant CONVERTED_TO_VARIANT = 48, _('Converted to variant') diff --git a/src/backend/InvenTree/stock/tasks.py b/src/backend/InvenTree/stock/tasks.py index d8b647152f..d56fed9630 100644 --- a/src/backend/InvenTree/stock/tasks.py +++ b/src/backend/InvenTree/stock/tasks.py @@ -6,71 +6,12 @@ import structlog from opentelemetry import trace from common.settings import get_global_setting -from InvenTree.tasks import ScheduledTask, offload_task, scheduled_task +from InvenTree.tasks import ScheduledTask, scheduled_task tracer = trace.get_tracer(__name__) logger = structlog.get_logger('inventree') -@tracer.start_as_current_span('rebuild_stock_items') -def rebuild_stock_items(): - """Rebuild the entire StockItem tree structure. - - This may be necessary if the tree structure has become corrupted or inconsistent. - """ - from InvenTree.exceptions import log_error - from InvenTree.sentry import report_exception - from stock.models import StockItem - - logger.info('Rebuilding StockItem tree structure') - - try: - StockItem.objects.rebuild() - except Exception as e: - # This is a critical error, explicitly report to sentry - report_exception(e) - - log_error('rebuild_stock_items') - logger.exception('Failed to rebuild StockItem tree: %s', e) - - -def rebuild_stock_item_tree(tree_id: int, rebuild_on_fail: bool = True) -> bool: - """Rebuild the stock tree structure. - - Arguments: - tree_id (int): The ID of the StockItem tree to rebuild. - rebuild_on_fail (bool): If True, will attempt to rebuild the entire StockItem tree if the partial rebuild fails. - - Returns: - bool: True if the partial tree rebuild was successful, False otherwise. - - - If the rebuild fails, schedule a rebuild of the entire StockItem tree. - """ - from InvenTree.exceptions import log_error - from InvenTree.sentry import report_exception - from stock.models import StockItem - - if tree_id: - try: - StockItem.objects.partial_rebuild(tree_id) - logger.info('Rebuilt StockItem tree for tree_id: %s', tree_id) - return True - except Exception as e: - # This is a critical error, explicitly report to sentry - report_exception(e) - - log_error('rebuild_stock_item_tree') - logger.warning('Failed to rebuild StockItem tree for tree_id: %s', tree_id) - # If the partial rebuild fails, rebuild the entire tree - if rebuild_on_fail: - offload_task(rebuild_stock_items, group='stock') - return False - else: - # No tree_id provided, so rebuild the entire tree - StockItem.objects.rebuild() - return True - - @tracer.start_as_current_span('delete_old_stock_tracking') @scheduled_task(ScheduledTask.DAILY) def delete_old_stock_tracking(): diff --git a/src/backend/InvenTree/stock/test_api.py b/src/backend/InvenTree/stock/test_api.py index 38903f968a..6cf57bd2c5 100644 --- a/src/backend/InvenTree/stock/test_api.py +++ b/src/backend/InvenTree/stock/test_api.py @@ -6,6 +6,7 @@ from datetime import datetime, timedelta from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError +from django.test.utils import override_settings from django.urls import reverse import pytest @@ -14,10 +15,15 @@ from rest_framework import status import build.models import company.models +import order.models import part.models from common.models import InvenTreeCustomUserStateModel, InvenTreeSetting from common.settings import set_global_setting -from InvenTree.unit_test import InvenTreeAPIPerformanceTestCase, InvenTreeAPITestCase +from InvenTree.unit_test import ( + InvenTreeAPIPerformanceTestCase, + InvenTreeAPITestCase, + findOffloadedEvent, +) from part.models import Part, PartTestTemplate from stock.models import ( StockItem, @@ -51,6 +57,7 @@ class StockAPITestCase(InvenTreeAPITestCase): 'stock_location.add', 'stock_location.delete', 'stock.delete', + 'part.view', ] @@ -72,6 +79,71 @@ class StockLocationTest(StockAPITestCase): for ordering in ['name', 'pathstring', 'level', 'tree_id']: self.run_ordering_test(self.list_url, ordering) + def test_bulk_set_parent(self): + """Test that bulk re-parenting of locations correctly rebuilds the tree. + + Re-parenting multiple locations in a single 'bulk update' API call must + leave the tree structure and the 'pathstring' values fully consistent. + + Ref: https://github.com/inventree/InvenTree/issues/12394 + """ + parent_a = StockLocation.objects.create(name='Parent A') + parent_b = StockLocation.objects.create(name='Parent B') + + # Create a number of sub-locations under 'Parent A', + # some of which have their own child locations + locations = [] + + for i in range(25): + location = StockLocation.objects.create(name=f'Sub{i:02d}', parent=parent_a) + locations.append(location) + + if i % 5 == 0: + child = StockLocation.objects.create( + name=f'Sub{i:02d}-child', parent=location + ) + StockLocation.objects.create( + name=f'Sub{i:02d}-grandchild', parent=child + ) + + # Move all sub-locations to 'Parent B' in a single bulk update. + # The query count must scale linearly with the number of items. + # Note: when the background worker is not running (e.g. in tests), each + # item save runs the (de-duplicated) tree rebuild task synchronously + self.patch( + self.list_url, + {'items': [location.pk for location in locations], 'parent': parent_b.pk}, + expected_code=200, + max_query_count=60 * len(locations), + ) + + for location in locations: + location.refresh_from_db() + self.assertEqual(location.parent, parent_b) + + parent_a.refresh_from_db() + parent_b.refresh_from_db() + + # Check *all* locations in the affected trees + # (fixture data outside these trees does not have pathstring values set) + affected_trees = StockLocation.objects.filter( + tree_id__in=[parent_a.tree_id, parent_b.tree_id] + ) + + for location in affected_trees: + # The stored pathstring must match the 'parent' chain for the node + chain = [] + node = location + + while node is not None: + chain.insert(0, node) + node = node.parent + + self.assertEqual(location.pathstring, '/'.join(node.name for node in chain)) + + # The MPTT tree data must match the 'parent' chain, too + self.assertEqual(list(location.get_ancestors()), chain[:-1]) + def test_list(self): """Test the StockLocationList API endpoint.""" test_cases = [ @@ -545,6 +617,62 @@ class StockItemListTest(StockAPITestCase): for ordering in ['part', 'location', 'stock', 'status', 'IPN', 'MPN', 'SKU']: self.run_ordering_test(self.list_url, ordering) + def test_creation_date_filter_and_ordering(self): + """Test created_before / created_after filters and ordering by creation_date.""" + import datetime + + part = Part.objects.first() + location = StockLocation.objects.first() + + # Create items with known, spread-out creation_dates via UPDATE after insert + dates = [ + datetime.date(2020, 1, 1), + datetime.date(2021, 6, 15), + datetime.date(2023, 3, 30), + ] + pks = [] + for d in dates: + item = StockItem.objects.create(part=part, location=location, quantity=1) + StockItem.objects.filter(pk=item.pk).update(creation_date=d) + pks.append(item.pk) + + # created_after=2020-12-31 should exclude the 2020 item + result_pks = [r['pk'] for r in self.get_stock(created_after='2020-12-31')] + self.assertNotIn(pks[0], result_pks) + self.assertIn(pks[1], result_pks) + self.assertIn(pks[2], result_pks) + + # created_before=2022-01-01 should exclude the 2023 item + result_pks = [r['pk'] for r in self.get_stock(created_before='2022-01-01')] + self.assertIn(pks[0], result_pks) + self.assertIn(pks[1], result_pks) + self.assertNotIn(pks[2], result_pks) + + # combined: only the 2021 item falls in the window + result_pks = [ + r['pk'] + for r in self.get_stock( + created_after='2020-12-31', created_before='2022-01-01' + ) + ] + self.assertNotIn(pks[0], result_pks) + self.assertIn(pks[1], result_pks) + self.assertNotIn(pks[2], result_pks) + + # ordering=creation_date: our three items must appear in ascending date order + results = self.get( + self.list_url, {'ordering': 'creation_date'}, expected_code=200 + ).data + ordered_pks = [r['pk'] for r in results if r['pk'] in pks] + self.assertEqual(ordered_pks, pks) + + # ordering=-creation_date: descending + results = self.get( + self.list_url, {'ordering': '-creation_date'}, expected_code=200 + ).data + ordered_pks = [r['pk'] for r in results if r['pk'] in pks] + self.assertEqual(ordered_pks, list(reversed(pks))) + def test_pagination(self): """Test that pagination boundaries are observed correctly. @@ -560,17 +688,7 @@ class StockItemListTest(StockAPITestCase): item.delete() for idx in range(1000): - items.append( - StockItem( - part=part, - location=location, - quantity=idx % 10, - level=0, - lft=0, - rght=0, - tree_id=0, - ) - ) + items.append(StockItem(part=part, location=location, quantity=idx % 10)) StockItem.objects.bulk_create(items, batch_size=250) @@ -662,6 +780,49 @@ class StockItemListTest(StockAPITestCase): response = self.get_stock(part=10004) self.assertEqual(len(response), 3) + def test_filter_by_part_include_variants(self): + """Filter StockItem list by part, with / without including variants. + + Regression test for https://github.com/inventree/InvenTree/issues/12232 + - The 'Install Stock Item' form relies on 'include_variants=false' to avoid + surfacing variant stock which the BOM does not allow + """ + category = part.models.PartCategory.objects.get(pk=3) + + master_part = part.models.Part.objects.create( + name='Master Variant Part', + description='Master part which has variants', + category=category, + is_template=True, + ) + + variant_part = part.models.Part.objects.create( + name='Variant Part', + description='A variant of the master part', + category=category, + variant_of=master_part, + ) + + StockItem.objects.create(part=master_part, quantity=5) + StockItem.objects.create(part=variant_part, quantity=3) + + # By default, 'include_variants' defaults to True - stock for both parts is returned + response = self.get_stock(part=master_part.pk) + self.assertEqual(len(response), 2) + + response = self.get_stock(part=master_part.pk, include_variants=True) + self.assertEqual(len(response), 2) + + # Exclude variants - only stock for the exact part is returned + response = self.get_stock(part=master_part.pk, include_variants=False) + self.assertEqual(len(response), 1) + self.assertEqual(response[0]['part'], master_part.pk) + + # Filtering directly on the variant part is unaffected by 'include_variants' + response = self.get_stock(part=variant_part.pk, include_variants=False) + self.assertEqual(len(response), 1) + self.assertEqual(response[0]['part'], variant_part.pk) + def test_filter_by_ipn(self): """Filter StockItem by IPN reference.""" response = self.get_stock(IPN='R.CH') @@ -681,13 +842,6 @@ class StockItemListTest(StockAPITestCase): response = self.get_stock(location=7) self.assertEqual(len(response), 18) - def test_filter_by_exclude_tree(self): - """Filter StockItem by excluding a StockItem tree.""" - response = self.get_stock(exclude_tree=1000) - for item in response: - self.assertNotEqual(item['pk'], 1000) - self.assertNotEqual(item['parent'], 1000) - def test_filter_by_depleted(self): """Filter StockItem by depleted status.""" response = self.get_stock(depleted=1) @@ -987,15 +1141,7 @@ class StockItemListTest(StockAPITestCase): part = parts[idx % N_PARTS] location = locations[idx % N_LOCATIONS] - item = StockItem( - part=part, - location=location, - quantity=10, - level=0, - tree_id=0, - lft=0, - rght=0, - ) + item = StockItem(part=part, location=location, quantity=10) stock_items.append(item) idx += 1 @@ -1111,8 +1257,7 @@ class StockItemListTest(StockAPITestCase): prt = Part.objects.first() StockItem.objects.bulk_create([ - StockItem(part=prt, quantity=1, level=0, tree_id=0, lft=0, rght=0) - for _ in range(100) + StockItem(part=prt, quantity=1) for _ in range(100) ]) # List *all* stock items @@ -1192,7 +1337,7 @@ class StockItemListTest(StockAPITestCase): parent_item.refresh_from_db() # Check that the parent item has 5 child items - self.assertEqual(parent_item.get_descendants(include_self=False).count(), 5) + self.assertEqual(parent_item.get_children().count(), 5) self.assertEqual(my_part.stock_items.count(), 6) # Fetch stock list via API @@ -1355,6 +1500,78 @@ class CustomStockItemStatusTest(StockAPITestCase): self.assertEqual(status['value'], self.status.key) self.assertEqual(status['display_name'], self.status.label) + def test_custom_status_query_count(self): + """Test that listing StockItems with custom statuses does not cause N+1 queries. + + Ensures that resolving 'status_text' for custom status values is O(1) + in database queries, not O(N) relative to the number of results. + """ + stock_content_type = ContentType.objects.get(model='stockitem') + + # 10 custom status values - different keys, labels, and logical_keys + logical_keys = [ + StockStatus.OK.value, + StockStatus.ATTENTION.value, + StockStatus.DAMAGED.value, + StockStatus.DESTROYED.value, + StockStatus.REJECTED.value, + StockStatus.LOST.value, + StockStatus.QUARANTINED.value, + StockStatus.RETURNED.value, + StockStatus.OK.value, + StockStatus.ATTENTION.value, + ] + + custom_statuses = [ + InvenTreeCustomUserStateModel.objects.create( + key=2000 + i, + name=f'StockCustomStatus{i}', + label=f'Stock Custom Status Label {i}', + color='secondary', + logical_key=logical_keys[i], + model=stock_content_type, + reference_status='StockStatus', + ) + for i in range(10) + ] + + part = Part.objects.filter(active=True, virtual=False).first() + + # Create 500 stock items, cycling through the 10 custom statuses + StockItem.objects.bulk_create([ + StockItem( + part=part, + quantity=1, + status=custom_statuses[i % 10].logical_key, + status_custom_key=custom_statuses[i % 10].key, + ) + for i in range(500) + ]) + + # Lookup: custom_key -> custom_status_object, for quick per-row assertions + custom_lookup = {cs.key: cs for cs in custom_statuses} + + # Query count must stay below the fixed threshold regardless of limit. + # An N+1 bug would push limit=100 or limit=500 well over the threshold. + for limit in [50, 100, 500]: + response = self.get( + self.list_url, + data={'limit': limit}, + expected_code=200, + max_query_count=50, + ) + + for result in response.data['results']: + cs = custom_lookup.get(result['status_custom_key']) + + if cs is None: + # Item from fixtures - no custom status assigned + continue + + self.assertEqual(result['status'], cs.logical_key) + self.assertEqual(result['status_custom_key'], cs.key) + self.assertEqual(result['status_text'], cs.label) + class StockItemTest(StockAPITestCase): """Series of API tests for the StockItem API.""" @@ -1421,7 +1638,12 @@ class StockItemTest(StockAPITestCase): """Test creation of a StockItem via the API.""" # POST with an empty part reference - response = self.client.post(self.list_url, data={'quantity': 10, 'location': 1}) + response = self.post( + self.list_url, + data={'quantity': 10, 'location': 1}, + max_query_count=2250, + expected_code=400, + ) self.assertContains( response, @@ -1431,8 +1653,11 @@ class StockItemTest(StockAPITestCase): # POST with an invalid part reference - response = self.client.post( - self.list_url, data={'quantity': 10, 'location': 1, 'part': 10000000} + response = self.post( + self.list_url, + data={'quantity': 10, 'location': 1, 'part': 10000000}, + max_query_count=2250, + expected_code=400, ) self.assertContains( @@ -1454,6 +1679,79 @@ class StockItemTest(StockAPITestCase): data={'part': 1, 'location': 1, 'quantity': 10}, expected_code=201, ) + # creation_date must be populated on the newly created item + item = StockItem.objects.get(pk=response.data[0]['pk']) + self.assertIsNotNone(item.creation_date) + + def test_creation_date_is_readonly(self): + """creation_date must not be modifiable via the API.""" + item = StockItem.objects.create( + part=Part.objects.get(pk=1), + location=StockLocation.objects.get(pk=1), + quantity=1, + ) + original_date = item.creation_date + self.assertIsNotNone(original_date) + + url = reverse('api-stock-detail', kwargs={'pk': item.pk}) + self.patch( + url, data={'creation_date': '2000-01-01T00:00:00Z'}, expected_code=200 + ) + # Field is read-only; the DB value must be unchanged + item.refresh_from_db() + self.assertEqual(item.creation_date, original_date) + + def test_creation_date_set_on_serialize(self): + """creation_date must be set on items produced by the serialize endpoint.""" + # Stock item 100: part 25 (trackable), quantity 10, location 7 + item = StockItem.objects.get(pk=100) + url = reverse('api-stock-item-serialize', kwargs={'pk': item.pk}) + + self.post( + url, + data={ + 'quantity': 3, + 'serial_numbers': '901,902,903', + 'destination': item.location.pk, + }, + expected_code=201, + ) + new_items = StockItem.objects.filter( + part=item.part, serial__in=['901', '902', '903'] + ) + self.assertEqual(new_items.count(), 3) + for new_item in new_items: + self.assertIsNotNone(new_item.creation_date) + + def test_bulk_serialize_benchmark(self): + """Benchmark: measure the number of DB queries required to serialize 100 stock items at once.""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + part = Part.objects.create( + name='Bulk serialize benchmark part', + description='Created for the stock serialize query-count benchmark', + trackable=True, + ) + + location = StockLocation.objects.create( + name='Bulk serialize benchmark location' + ) + + item = StockItem.objects.create(part=part, location=location, quantity=100) + + url = reverse('api-stock-item-serialize', kwargs={'pk': item.pk}) + + data = {'quantity': 100, 'serial_numbers': '1-100', 'destination': location.pk} + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + response = self.post( + url, data, max_query_count=150, benchmark=True, format='json' + ) + + self.assertEqual(response.status_code, 201) + self.assertEqual(len(response.data), 100) def test_stock_item_create_with_supplier_part(self): """Test creation of a StockItem via the API, including SupplierPart data.""" @@ -1597,6 +1895,7 @@ class StockItemTest(StockAPITestCase): # Item location should have been set automatically self.assertIsNotNone(item.location) self.assertIn(item.serial, serials) + self.assertIsNotNone(item.creation_date) # There now should be 10 unique stock entries for this part self.assertEqual(trackable_part.stock_entries().count(), 10) @@ -1733,6 +2032,28 @@ class StockItemTest(StockAPITestCase): ], ) + def test_part_detail_permissions(self): + """Test that the part_detail output option is only available to users with permission.""" + url = reverse('api-stock-detail', kwargs={'pk': 1}) + + # User has permission to view parts + response = self.get(url, {'part_detail': True}, expected_code=200) + + self.assertIn('pk', response.data) + self.assertIn('part', response.data) + self.assertIn('part_detail', response.data) + + # Remove 'part view' permission from user + self.clearRoles() + response = self.get(url, {'part_detail': True}, expected_code=403) + + self.assignRole('stock.view') + + response = self.get(url, {'part_detail': True}, expected_code=200) + self.assertIn('pk', response.data) + self.assertIn('part', response.data) + self.assertNotIn('part_detail', response.data) + def test_install(self): """Test that stock item can be installed into another item, via the API.""" # Select the "parent" stock item @@ -1791,6 +2112,20 @@ class StockItemTest(StockAPITestCase): url = reverse('api-stock-item-uninstall', kwargs={'pk': sub_item.pk}) + # An uninstalled item cannot be moved into a structural location + structural = StockLocation.objects.create( + name='Structural location', structural=True + ) + + response = self.post(url, {'location': structural.pk}, expected_code=400) + + self.assertIn( + 'Structural locations cannot be assigned stock items', str(response.data) + ) + + sub_item.refresh_from_db() + self.assertEqual(sub_item.belongs_to, item) + self.post(url, {'location': 1}, expected_code=201) sub_item.refresh_from_db() @@ -2027,7 +2362,7 @@ class StockItemTest(StockAPITestCase): data = response.data - self.assertEqual(data['success'], 'Updated 10 items') + self.assertEqual(data['success'], 'Updated multiple items') self.assertEqual(len(data['items']), 10) for item in data['items']: @@ -2039,6 +2374,487 @@ class StockItemTest(StockAPITestCase): self.assertEqual(item.batch, 'NEW-BATCH-CODE') +class StockItemDisassembleTest(StockAPITestCase): + """Series of API tests for the StockItem disassembly endpoint.""" + + def setUp(self): + """Create a stock item of an assembly part, ready for disassembly.""" + super().setUp() + + # Part 100 ("Bob") is an assembly with 4 BOM lines + self.assembly = part.models.Part.objects.get(pk=100) + + self.item = StockItem.objects.create( + part=self.assembly, + quantity=10, + location=StockLocation.objects.get(pk=1), + purchase_price=Money(100, 'USD'), + ) + + self.url = reverse('api-stock-item-disassemble', kwargs={'pk': self.item.pk}) + + def test_validation(self): + """Test validation checks for the disassembly endpoint.""" + # Empty request + response = self.post(self.url, {}, expected_code=400) + + self.assertIn('This field is required', str(response.data['items'])) + self.assertIn('This field is required', str(response.data['quantity'])) + + # No line items provided + response = self.post(self.url, {'items': [], 'quantity': 1}, expected_code=400) + + self.assertIn('Line items must be provided', str(response.data)) + + # Quantity exceeds available stock + response = self.post( + self.url, + {'items': [{'bom_item': 1, 'quantity': 10}], 'quantity': 100}, + expected_code=400, + ) + + self.assertIn( + 'Quantity must not exceed available stock quantity', str(response.data) + ) + + # BOM item which points to a different part (BomItem pk=5 -> part 1) + response = self.post( + self.url, + {'items': [{'bom_item': 5, 'quantity': 1}], 'quantity': 1}, + expected_code=400, + ) + + self.assertIn( + 'BOM item is not valid for the selected stock item', str(response.data) + ) + + # Duplicated BOM items + response = self.post( + self.url, + { + 'items': [ + {'bom_item': 1, 'quantity': 10}, + {'bom_item': 1, 'quantity': 5}, + ], + 'quantity': 1, + }, + expected_code=400, + ) + + self.assertIn('Duplicate BOM items provided', str(response.data)) + + def test_consumable_and_virtual_excluded(self): + """Consumable BOM lines, and lines pointing to a virtual part, cannot be disassembled.""" + # BOM line marked as consumable directly + consumable_line = part.models.BomItem.objects.create( + part=self.assembly, + sub_part=part.models.Part.objects.get(pk=2), + quantity=1, + consumable=True, + ) + + # BOM line whose sub_part is marked as consumable + consumable_part = part.models.Part.objects.get(pk=3) + consumable_part.consumable = True + consumable_part.save() + + # BOM line whose sub_part is marked as virtual + virtual_part = part.models.Part.objects.get(pk=5) + virtual_part.virtual = True + virtual_part.save() + + for bom_item_pk in [consumable_line.pk, 2, 3]: + response = self.post( + self.url, + {'items': [{'bom_item': bom_item_pk, 'quantity': 1}], 'quantity': 1}, + expected_code=400, + ) + + self.assertIn( + 'BOM item is not valid for the selected stock item', str(response.data) + ) + + def test_disassemble(self): + """Test a valid disassembly operation, using a subset of the BOM lines.""" + n = StockItem.objects.count() + + # Disassemble 4 assemblies, but only break out 2 of the 4 BOM lines + # The second line specifies a custom location and status + response = self.post( + self.url, + { + 'items': [ + {'bom_item': 1, 'quantity': 40}, + { + 'bom_item': 4, + 'quantity': 12, + 'location': 2, + 'status': StockStatus.DAMAGED.value, + }, + ], + 'quantity': 4, + 'notes': 'Breaking apart', + }, + expected_code=201, + ) + + self.assertEqual(len(response.data), 2) + self.assertEqual(StockItem.objects.count(), n + 2) + + self.item.refresh_from_db() + self.assertEqual(self.item.quantity, 6) + + items = {entry['part']: entry for entry in response.data} + + # Check the generated component items + item_1 = StockItem.objects.get(pk=items[1]['pk']) + item_50 = StockItem.objects.get(pk=items[50]['pk']) + + self.assertEqual(item_1.quantity, 40) + self.assertEqual(item_50.quantity, 12) + + # Components inherit the location of the disassembled item by default + self.assertEqual(item_1.location, self.item.location) + self.assertEqual(item_1.status, StockStatus.OK.value) + + # A custom location and status can be specified per line + self.assertEqual(item_50.location.pk, 2) + self.assertEqual(item_50.status, StockStatus.DAMAGED.value) + + # Components are linked to the disassembled item + self.assertEqual(item_1.parent.pk, self.item.pk) + self.assertEqual(item_50.parent.pk, self.item.pk) + + # Total cost (4 x 100 USD) is allocated evenly across 52 units + self.assertAlmostEqual(float(item_1.purchase_price.amount), 400 / 52, places=4) + self.assertAlmostEqual(float(item_50.purchase_price.amount), 400 / 52, places=4) + self.assertEqual(str(item_1.purchase_price.currency), 'USD') + + # Check stock tracking entries have been created + self.assertTrue( + self.item.tracking_info.filter( + tracking_type=StockHistoryCode.DISASSEMBLED.value + ).exists() + ) + + for item in [item_1, item_50]: + entry = item.tracking_info.filter( + tracking_type=StockHistoryCode.CREATED_FROM_DISASSEMBLY.value + ).first() + + self.assertIsNotNone(entry) + self.assertEqual(entry.deltas['stockitem'], self.item.pk) + + def test_full_disassembly(self): + """Test that a fully disassembled item is retained at zero quantity.""" + self.post( + self.url, + {'items': [{'bom_item': 2, 'quantity': 400}], 'quantity': 10}, + expected_code=201, + ) + + self.item.refresh_from_db() + + self.assertEqual(self.item.quantity, 0) + self.assertFalse(self.item.in_stock) + + def test_traceability_inheritance(self): + """Test that traceability data is passed down to the generated components.""" + po = order.models.PurchaseOrder.objects.create( + supplier=company.models.Company.objects.get(pk=1), reference='PO-9999' + ) + + bo = build.models.Build.objects.create( + part=self.assembly, quantity=10, reference='BO-9999' + ) + + self.item.batch = 'ABC-123' + self.item.purchase_order = po + self.item.build = bo + self.item.save() + + response = self.post( + self.url, + {'items': [{'bom_item': 1, 'quantity': 10}], 'quantity': 1}, + expected_code=201, + ) + + component = StockItem.objects.get(pk=response.data[0]['pk']) + + # Batch code and source purchase order are inherited directly + self.assertEqual(component.batch, 'ABC-123') + self.assertEqual(component.purchase_order, po) + + # The source build order cannot be copied across (the component is not + # an output of the build) - instead it is recorded in the stock history + self.assertIsNone(component.build) + + entry = component.tracking_info.filter( + tracking_type=StockHistoryCode.CREATED_FROM_DISASSEMBLY.value + ).first() + + self.assertIsNotNone(entry) + self.assertEqual(entry.deltas['buildorder'], bo.pk) + self.assertEqual(entry.deltas['purchaseorder'], po.pk) + + def test_explicit_pricing(self): + """Test that automatic cost allocation is skipped if explicit pricing is provided.""" + response = self.post( + self.url, + { + 'items': [ + { + 'bom_item': 1, + 'quantity': 10, + 'purchase_price': 5, + 'purchase_price_currency': 'NZD', + }, + {'bom_item': 4, 'quantity': 3}, + ], + 'quantity': 1, + }, + expected_code=201, + ) + + prices = {entry['part']: entry['purchase_price'] for entry in response.data} + + self.assertAlmostEqual(prices[1], 5, places=3) + self.assertIsNone(prices[50]) + + def install_item(self, part_pk: int, quantity, **kwargs) -> StockItem: + """Install a new stock item into the assembly under test.""" + return StockItem.objects.create( + part=part.models.Part.objects.get(pk=part_pk), + quantity=quantity, + belongs_to=self.item, + location=None, + **kwargs, + ) + + def test_installed_items_partial(self): + """Installed items are uninstalled, and only the remainder is created afresh.""" + sub_1 = self.install_item(1, 12) + sub_2 = self.install_item(1, 8) + + n = StockItem.objects.count() + + # Disassemble all 10 assemblies - the line requires 100 units in total + response = self.post( + self.url, + {'items': [{'bom_item': 1, 'quantity': 100}], 'quantity': 10}, + expected_code=201, + ) + + # Two uninstalled items, plus a single new item for the remainder + self.assertEqual(len(response.data), 3) + self.assertEqual(StockItem.objects.count(), n + 1) + + pks = {entry['pk'] for entry in response.data} + self.assertIn(sub_1.pk, pks) + self.assertIn(sub_2.pk, pks) + + for sub in [sub_1, sub_2]: + sub.refresh_from_db() + self.assertIsNone(sub.belongs_to) + self.assertEqual(sub.location, self.item.location) + + new_item = StockItem.objects.get(pk=(pks - {sub_1.pk, sub_2.pk}).pop()) + self.assertEqual(new_item.part.pk, 1) + self.assertEqual(new_item.quantity, 80) + + # Uninstalled items are updated, not created afresh + self.assertTrue( + sub_1.tracking_info.filter( + tracking_type=StockHistoryCode.REMOVED_FROM_ASSEMBLY.value + ).exists() + ) + self.assertFalse( + sub_1.tracking_info.filter( + tracking_type=StockHistoryCode.CREATED_FROM_DISASSEMBLY.value + ).exists() + ) + self.assertTrue( + self.item.tracking_info.filter( + tracking_type=StockHistoryCode.REMOVED_CHILD_ITEM.value + ).exists() + ) + self.assertTrue( + new_item.tracking_info.filter( + tracking_type=StockHistoryCode.CREATED_FROM_DISASSEMBLY.value + ).exists() + ) + + def test_installed_items_full_coverage(self): + """No new stock item is created for a line fully covered by installed items.""" + sub = self.install_item(1, 120, purchase_price=Money(3, 'USD')) + + n = StockItem.objects.count() + + response = self.post( + self.url, + { + 'items': [ + {'bom_item': 1, 'quantity': 100}, + {'bom_item': 4, 'quantity': 30}, + ], + 'quantity': 10, + }, + expected_code=201, + ) + + # The first line is fully covered by the uninstalled item + self.assertEqual(len(response.data), 2) + self.assertEqual(StockItem.objects.count(), n + 1) + + sub.refresh_from_db() + self.assertIsNone(sub.belongs_to) + + # The uninstalled item retains its own purchase price + self.assertEqual(sub.purchase_price, Money(3, 'USD')) + + # The total cost (10 x 100 USD) is spread only across newly created units + new_item = StockItem.objects.get(part=50, parent=self.item) + self.assertEqual(new_item.quantity, 30) + self.assertAlmostEqual( + float(new_item.purchase_price.amount), 1000 / 30, places=4 + ) + + def test_installed_items_leftover(self): + """Installed items which do not match a BOM line are still uninstalled.""" + # Part 2 is not a component of the assembly + sub = self.install_item(2, 5, status=StockStatus.ATTENTION.value) + + response = self.post( + self.url, + { + 'items': [{'bom_item': 2, 'quantity': 400}], + 'quantity': 10, + 'location': 2, + }, + expected_code=201, + ) + + self.assertEqual(len(response.data), 2) + + sub.refresh_from_db() + self.assertIsNone(sub.belongs_to) + + # Uninstalled to the top-level destination, retaining its own status + self.assertEqual(sub.location.pk, 2) + self.assertEqual(sub.status, StockStatus.ATTENTION.value) + + # The BOM line quantity is not reduced by the unmatched item + new_item = StockItem.objects.get(part=3, parent=self.item) + self.assertEqual(new_item.quantity, 400) + + def test_installed_items_require_full_disassembly(self): + """Partial disassembly is rejected while items are installed.""" + self.install_item(1, 1) + + response = self.post( + self.url, + {'items': [{'bom_item': 1, 'quantity': 50}], 'quantity': 5}, + expected_code=400, + ) + + self.assertIn('must be disassembled in its entirety', str(response.data)) + + def test_installed_items_status_and_location(self): + """Explicit per-line status and location values are applied to uninstalled items.""" + sub_1 = self.install_item(1, 10) + sub_2 = self.install_item(50, 4, status=StockStatus.ATTENTION.value) + + self.post( + self.url, + { + 'items': [ + { + 'bom_item': 1, + 'quantity': 100, + 'location': 2, + 'status': StockStatus.DAMAGED.value, + }, + {'bom_item': 4, 'quantity': 30}, + ], + 'quantity': 10, + }, + expected_code=201, + ) + + sub_1.refresh_from_db() + self.assertEqual(sub_1.location.pk, 2) + self.assertEqual(sub_1.status, StockStatus.DAMAGED.value) + + # No explicit status provided for the second line - item status is retained + sub_2.refresh_from_db() + self.assertEqual(sub_2.location, self.item.location) + self.assertEqual(sub_2.status, StockStatus.ATTENTION.value) + + def test_installed_items_variants_and_substitutes(self): + """Installed variant and substitute parts are matched against BOM lines.""" + # Designate part 2 as a substitute for BOM line 4 + part.models.BomItemSubstitute.objects.create( + bom_item=part.models.BomItem.objects.get(pk=4), + part=part.models.Part.objects.get(pk=2), + ) + + # New BOM line against a template part, allowing variants + bom_line = part.models.BomItem.objects.create( + part=self.assembly, + sub_part=part.models.Part.objects.get(pk=10000), + quantity=5, + allow_variants=True, + ) + + substitute_item = self.install_item(2, 10) + variant_item = self.install_item(10001, 20) + + response = self.post( + self.url, + { + 'items': [ + {'bom_item': 4, 'quantity': 30}, + {'bom_item': bom_line.pk, 'quantity': 50}, + ], + 'quantity': 10, + }, + expected_code=201, + ) + + self.assertEqual(len(response.data), 4) + + for sub in [substitute_item, variant_item]: + sub.refresh_from_db() + self.assertIsNone(sub.belongs_to) + + # Line quantities are reduced by the matched installed items + new_50 = StockItem.objects.get(part=50, parent=self.item) + self.assertEqual(new_50.quantity, 20) + + new_chair = StockItem.objects.get(part=10000, parent=self.item) + self.assertEqual(new_chair.quantity, 30) + + def test_serialized(self): + """Test disassembly of a serialized stock item.""" + item = StockItem.objects.create( + part=self.assembly, quantity=1, serial='SN-DISASSEMBLE-1' + ) + + url = reverse('api-stock-item-disassemble', kwargs={'pk': item.pk}) + + self.post( + url, + {'items': [{'bom_item': 1, 'quantity': 10}], 'quantity': 1}, + expected_code=201, + ) + + item.refresh_from_db() + + # A serialized item cannot be "depleted" - it is marked as destroyed instead + self.assertEqual(item.status, StockStatus.DESTROYED.value) + self.assertFalse(item.in_stock) + + class StocktakeTest(StockAPITestCase): """Series of tests for the Stocktake API.""" @@ -2113,6 +2929,32 @@ class StocktakeTest(StockAPITestCase): self.assertEqual(response.data['items'][0]['pk'], 1234) self.assertEqual(response.data['items'][0]['quantity'], target[endpoint]) + def test_count_serialized(self): + """Test that counting a serialized stock item correctly updates stocktake_date.""" + import datetime + + # Fixture item pk=501 is a serialized item (serial=1) + item = StockItem.objects.get(pk=501) + self.assertTrue(item.serialized) + self.assertEqual(item.quantity, 1) + + # Clear any existing stocktake date so we can verify it gets set + item.stocktake_date = None + item.save() + + url = reverse('api-stock-count') + + # Count the serialized item — quantity must be 1 + data = {'items': [{'pk': item.pk, 'quantity': 1}]} + response = self.post(url, data, expected_code=201) + + self.assertEqual(response.data['items'][0]['pk'], item.pk) + self.assertEqual(response.data['items'][0]['quantity'], '1.00000') + + # stocktake_date must have been set to today + item.refresh_from_db() + self.assertEqual(item.stocktake_date, datetime.date.today()) + def test_transfer(self): """Test stock transfers.""" stock_item = StockItem.objects.get(pk=1234) @@ -2153,6 +2995,508 @@ class StocktakeTest(StockAPITestCase): status_code=status.HTTP_400_BAD_REQUEST, ) + def test_count_with_location(self): + """Test that the stock count endpoint correctly handles the optional location field.""" + url = reverse('api-stock-count') + + # Stock item pk=1234 starts at location 5; pk=1 starts at location 3 + item_a = StockItem.objects.get(pk=1234) + item_b = StockItem.objects.get(pk=1) + + self.assertEqual(item_a.location.pk, 5) + self.assertEqual(item_b.location.pk, 3) + + # --- location is updated when provided (single item) --- + response = self.post( + url, + {'items': [{'pk': item_a.pk, 'quantity': 10}], 'location': 1}, + expected_code=201, + ) + self.assertEqual(response.data['items'][0]['pk'], item_a.pk) + + item_a.refresh_from_db() + self.assertEqual(item_a.location.pk, 1) + + # Tracking entry records the location change + entry = StockItemTracking.objects.filter( + item=item_a, tracking_type=StockHistoryCode.STOCK_COUNT + ).latest('date') + self.assertEqual(entry.deltas.get('location'), 1) + self.assertEqual(entry.deltas.get('old_location'), 5) + + # --- location is updated for multiple items simultaneously --- + response = self.post( + url, + { + 'items': [ + {'pk': item_a.pk, 'quantity': 5}, + {'pk': item_b.pk, 'quantity': 20}, + ], + 'location': 2, + }, + expected_code=201, + ) + self.assertEqual(len(response.data['items']), 2) + + item_a.refresh_from_db() + item_b.refresh_from_db() + self.assertEqual(item_a.location.pk, 2) + self.assertEqual(item_b.location.pk, 2) + + # Both items have a tracking entry with the new location + for item, old_loc in [(item_a, 1), (item_b, 3)]: + entry = StockItemTracking.objects.filter( + item=item, tracking_type=StockHistoryCode.STOCK_COUNT + ).latest('date') + self.assertEqual(entry.deltas.get('location'), 2) + self.assertEqual(entry.deltas.get('old_location'), old_loc) + + # --- location is unchanged when not provided --- + response = self.post( + url, {'items': [{'pk': item_a.pk, 'quantity': 7}]}, expected_code=201 + ) + + item_a.refresh_from_db() + # Location should still be 2 (unchanged from the previous count) + self.assertEqual(item_a.location.pk, 2) + + # Tracking entry has no location delta when location was not provided + entry = StockItemTracking.objects.filter( + item=item_a, tracking_type=StockHistoryCode.STOCK_COUNT + ).latest('date') + self.assertNotIn('location', entry.deltas) + self.assertNotIn('old_location', entry.deltas) + + # --- structural location is rejected --- + structural = StockLocation.objects.create(name='Structural', structural=True) + + response = self.post( + url, + {'items': [{'pk': item_a.pk, 'quantity': 1}], 'location': structural.pk}, + expected_code=400, + ) + self.assertIn( + 'Structural locations cannot be assigned stock items', + str(response.data['location']), + ) + + def test_count_unchanged_quantity_saves_field_changes(self): + """Location / status changes are saved even if the counted quantity is unchanged. + + Regression test: counting an item to its *existing* quantity used to skip + the model save entirely, losing any location / status change while still + recording the change in stock history. + """ + item = StockItem.objects.get(pk=1234) + + quantity = item.quantity + self.assertEqual(item.location.pk, 5) + self.assertEqual(item.status, StockStatus.OK.value) + + # Clear any existing stocktake date so we can verify it gets set + item.stocktake_date = None + item.save() + + self.post( + reverse('api-stock-count'), + { + 'items': [ + { + 'pk': item.pk, + 'quantity': float(quantity), + 'status': StockStatus.DAMAGED.value, + } + ], + 'location': 1, + }, + expected_code=201, + ) + + item.refresh_from_db() + + # Quantity is unchanged, but the location and status changes must be saved + self.assertEqual(item.quantity, quantity) + self.assertEqual(item.location.pk, 1) + self.assertEqual(item.status, StockStatus.DAMAGED.value) + self.assertIsNotNone(item.stocktake_date) + + # The stock history entry must agree with the saved state + entry = StockItemTracking.objects.filter( + item=item, tracking_type=StockHistoryCode.STOCK_COUNT + ).latest('date') + self.assertEqual(entry.deltas.get('quantity'), float(quantity)) + self.assertEqual(entry.deltas.get('location'), 1) + self.assertEqual(entry.deltas.get('old_location'), 5) + self.assertEqual(entry.deltas.get('status'), StockStatus.DAMAGED.value) + self.assertEqual(entry.deltas.get('old_status'), StockStatus.OK.value) + + def test_bulk_count_query_benchmark(self): + """Benchmark: measure the number of DB queries required to count 100 stock items at once.""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + part = Part.objects.create( + name='Bulk count benchmark part', + description='Created for the stock count query-count benchmark', + ) + + location = StockLocation.objects.create(name='Bulk count benchmark location') + + items = [ + StockItem.objects.create(part=part, location=location, quantity=idx + 1) + for idx in range(100) + ] + + url = reverse('api-stock-count') + + data = { + 'items': [ + {'pk': item.pk, 'quantity': idx + 100} for idx, item in enumerate(items) + ] + } + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + response = self.post( + url, data, max_query_count=950, benchmark=True, format='json' + ) + + self.assertEqual(response.status_code, 201) + self.assertEqual(len(response.data['items']), 100) + + def test_bulk_add_query_benchmark(self): + """Benchmark: measure the number of DB queries required to add stock to 100 items at once.""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + part = Part.objects.create( + name='Bulk add benchmark part', + description='Created for the stock add query-count benchmark', + ) + + location = StockLocation.objects.create(name='Bulk add benchmark location') + + items = [ + StockItem.objects.create(part=part, location=location, quantity=idx + 1) + for idx in range(100) + ] + + url = reverse('api-stock-add') + + data = {'items': [{'pk': item.pk, 'quantity': 5} for item in items]} + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + response = self.post( + url, data, max_query_count=950, benchmark=True, format='json' + ) + + self.assertEqual(response.status_code, 201) + self.assertEqual(len(response.data['items']), 100) + + def test_bulk_remove_query_benchmark(self): + """Benchmark: measure the number of DB queries required to remove stock from 100 items at once.""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + part = Part.objects.create( + name='Bulk remove benchmark part', + description='Created for the stock remove query-count benchmark', + ) + + location = StockLocation.objects.create(name='Bulk remove benchmark location') + + items = [ + StockItem.objects.create(part=part, location=location, quantity=idx + 100) + for idx in range(100) + ] + + url = reverse('api-stock-remove') + + data = {'items': [{'pk': item.pk, 'quantity': 5} for item in items]} + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + response = self.post( + url, data, max_query_count=950, benchmark=True, format='json' + ) + + self.assertEqual(response.status_code, 201) + self.assertEqual(len(response.data['items']), 100) + + def test_bulk_move_query_benchmark(self): + """Benchmark: measure the number of DB queries required to move 100 stock items at once.""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + part = Part.objects.create( + name='Bulk move benchmark part', + description='Created for the stock move query-count benchmark', + ) + + source = StockLocation.objects.create(name='Bulk move benchmark source') + destination = StockLocation.objects.create( + name='Bulk move benchmark destination' + ) + + items = [ + StockItem.objects.create(part=part, location=source, quantity=idx + 1) + for idx in range(100) + ] + + url = reverse('api-stock-transfer') + + data = { + 'items': [{'pk': item.pk, 'quantity': item.quantity} for item in items], + 'location': destination.pk, + } + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + response = self.post( + url, data, max_query_count=850, benchmark=True, format='json' + ) + + self.assertEqual(response.status_code, 201) + self.assertEqual(len(response.data['items']), 100) + + +class StockTransferMergeTest(StockAPITestCase): + """Tests for optional merge-on-transfer behavior.""" + + def setUp(self): + """Set up stock items for merge transfer tests.""" + super().setUp() + + self.part = Part.objects.get(pk=1) + self.dest = StockLocation.objects.get(pk=2) + self.source_loc = StockLocation.objects.get(pk=5) + self.url = reverse('api-stock-transfer') + + # Remove fixture stock at the destination so merge targets are deterministic + StockItem.objects.filter(part=self.part, location=self.dest).delete() + + def test_transfer_without_merge_creates_separate_lot(self): + """Transfer without merge leaves multiple stock rows at destination.""" + existing = StockItem.objects.create( + part=self.part, location=self.dest, quantity=100 + ) + incoming = StockItem.objects.create( + part=self.part, location=self.source_loc, quantity=50 + ) + + self.post( + self.url, + { + 'items': [{'pk': incoming.pk, 'quantity': 50, 'merge': False}], + 'location': self.dest.pk, + }, + expected_code=201, + ) + + self.assertEqual( + StockItem.objects.filter(part=self.part, location=self.dest).count(), 2 + ) + + existing.refresh_from_db() + self.assertEqual(existing.quantity, 100) + + def test_transfer_with_merge_combines_lots(self): + """Transfer with merge combines into an existing compatible lot.""" + existing = StockItem.objects.create( + part=self.part, location=self.dest, quantity=100 + ) + incoming = StockItem.objects.create( + part=self.part, location=self.source_loc, quantity=50 + ) + + self.post( + self.url, + { + 'items': [{'pk': incoming.pk, 'quantity': 50, 'merge': True}], + 'location': self.dest.pk, + }, + expected_code=201, + ) + + self.assertEqual( + StockItem.objects.filter(part=self.part, location=self.dest).count(), 1 + ) + + existing.refresh_from_db() + self.assertEqual(existing.quantity, 150) + self.assertFalse(StockItem.objects.filter(pk=incoming.pk).exists()) + + def test_transfer_mixed_merge_per_item(self): + """Each transfer line can merge or move independently.""" + existing = StockItem.objects.create( + part=self.part, location=self.dest, quantity=100 + ) + merge_incoming = StockItem.objects.create( + part=self.part, location=self.source_loc, quantity=30 + ) + separate_incoming = StockItem.objects.create( + part=self.part, location=self.source_loc, quantity=20 + ) + + self.post( + self.url, + { + 'items': [ + {'pk': merge_incoming.pk, 'quantity': 30, 'merge': True}, + {'pk': separate_incoming.pk, 'quantity': 20, 'merge': False}, + ], + 'location': self.dest.pk, + }, + expected_code=201, + ) + + self.assertEqual( + StockItem.objects.filter(part=self.part, location=self.dest).count(), 2 + ) + + existing.refresh_from_db() + self.assertEqual(existing.quantity, 130) + self.assertFalse(StockItem.objects.filter(pk=merge_incoming.pk).exists()) + self.assertTrue(StockItem.objects.filter(pk=separate_incoming.pk).exists()) + + def test_transfer_merge_does_not_copy_source_tracking(self): + """Transfer merge keeps destination history and adds a single merge entry.""" + # Track total number of tracking entries created + N_TRACKING_ENTRIES = StockItemTracking.objects.count() + + existing = StockItem.objects.create( + part=self.part, location=self.dest, quantity=100 + ) + incoming = StockItem.objects.create( + part=self.part, location=self.source_loc, quantity=50 + ) + + incoming.add_tracking_entry( + StockHistoryCode.STOCK_UPDATE, self.user, notes='Source tracking entry' + ) + + incoming_pk = incoming.pk + tracking_count = existing.tracking_info.count() + + self.post( + self.url, + { + 'items': [{'pk': incoming.pk, 'quantity': 50, 'merge': True}], + 'location': self.dest.pk, + }, + expected_code=201, + ) + + existing.refresh_from_db() + + self.assertFalse( + existing.tracking_info.filter(notes='Source tracking entry').exists() + ) + self.assertEqual(existing.tracking_info.count(), tracking_count + 1) + merge_entry = existing.tracking_info.filter( + tracking_type=StockHistoryCode.MERGED_STOCK_ITEMS + ).first() + self.assertIsNotNone(merge_entry) + self.assertEqual(merge_entry.deltas['added'], 50.0) + self.assertEqual(merge_entry.deltas['quantity'], 150.0) + self.assertEqual(merge_entry.deltas['stockitem'], incoming_pk) + self.assertEqual(merge_entry.deltas['location'], self.dest.pk) + + self.assertEqual(StockItemTracking.objects.count(), N_TRACKING_ENTRIES + 4) + + # Ensure tracking entries were bulk created in the correct order + entries = list(StockItemTracking.objects.order_by('-pk')[:4])[::-1] + + for idx, tt in enumerate([ + StockHistoryCode.CREATED, + StockHistoryCode.CREATED, + StockHistoryCode.STOCK_UPDATE, + StockHistoryCode.MERGED_STOCK_ITEMS, + ]): + self.assertEqual( + entries[idx].tracking_type, + tt, + f'Entry {idx} has unexpected tracking type {entries[idx].tracking_type}', + ) + + def test_transfer_merge_partial_reuses_split_transfer_deltas(self): + """Partial merge reuses split transfer deltas on the merge tracking entry.""" + existing = StockItem.objects.create( + part=self.part, location=self.dest, quantity=100 + ) + incoming = StockItem.objects.create( + part=self.part, location=self.source_loc, quantity=100 + ) + + self.post( + self.url, + { + 'items': [{'pk': incoming.pk, 'quantity': 30, 'merge': True}], + 'location': self.dest.pk, + }, + expected_code=201, + ) + + incoming.refresh_from_db() + self.assertEqual(incoming.quantity, 70) + + merge_entry = existing.tracking_info.filter( + tracking_type=StockHistoryCode.MERGED_STOCK_ITEMS + ).first() + self.assertEqual(merge_entry.deltas['stockitem'], incoming.pk) + self.assertEqual(merge_entry.deltas['location'], self.dest.pk) + self.assertFalse( + incoming.tracking_info.filter( + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM + ).exists() + ) + + def test_transfer_merge_skips_protected_source(self): + """Merge-on-transfer must not absorb items in a protected state. + + Regression test: only the *target* item used to be validated, so a + transfer with merge=True could absorb (and delete) an in-production + build output. Such items must be moved as a separate lot instead. + """ + existing = StockItem.objects.create( + part=self.part, location=self.dest, quantity=100 + ) + + # An "in production" build output + self.part.assembly = True + self.part.save() + + bo = build.models.Build.objects.create( + reference='BO-9999', part=self.part, title='Merge test build', quantity=50 + ) + + building = StockItem.objects.create( + part=self.part, + location=self.source_loc, + quantity=50, + build=bo, + is_building=True, + ) + + self.post( + self.url, + { + 'items': [{'pk': building.pk, 'quantity': 50, 'merge': True}], + 'location': self.dest.pk, + }, + expected_code=201, + ) + + # The build output must survive - transferred as a separate lot instead + building.refresh_from_db() + self.assertTrue(building.is_building) + self.assertEqual(building.location, self.dest) + self.assertEqual(building.quantity, 50) + + existing.refresh_from_db() + self.assertEqual(existing.quantity, 100) + class StockItemDeletionTest(StockAPITestCase): """Tests for stock item deletion via the API.""" @@ -2417,12 +3761,21 @@ class StockTestResultTest(StockAPITestCase): # Check that an attachment has been uploaded self.assertIsNotNone(response.data['attachment']) + @override_settings( + TESTING_TABLE_EVENTS=True, + PLUGIN_TESTING_EVENTS=True, + PLUGIN_TESTING_EVENTS_ASYNC=True, + ) def test_bulk_delete(self): """Test that the BulkDelete endpoint works for this model.""" + from django_q.models import OrmQ + n = StockItemTestResult.objects.count() tests = [] + set_global_setting('ENABLE_PLUGINS_EVENTS', True) + url = reverse('api-stock-test-result-list') stock_item = StockItem.objects.get(pk=1) @@ -2462,11 +3815,32 @@ class StockTestResultTest(StockAPITestCase): # Attempt a delete without providing items self.delete(url, {}, expected_code=400) + OrmQ.objects.all().delete() + # Now, let's delete all the newly created items with a single API request - response = self.delete(url, {'items': tests}, expected_code=200) + response = self.delete( + url, + {'items': tests}, + expected_code=200, + max_query_count=100, + benchmark=True, + max_query_time=0.5, + ) self.assertEqual(StockItemTestResult.objects.count(), n) + self.assertGreaterEqual(OrmQ.objects.count(), len(tests)) + + # Ensure that an associated 'deleted' event has been offloaded + for test in tests: + self.assertIsNotNone( + findOffloadedEvent( + 'stock_stockitemtestresult.deleted', matching_kwargs={'id': test} + ) + ) + + set_global_setting('ENABLE_PLUGINS_EVENTS', False) + def test_value_choices(self): """Test that the 'value' field is correctly validated.""" url = reverse('api-stock-test-result-list') @@ -2811,6 +4185,58 @@ class StockMergeTest(StockAPITestCase): self.assertEqual(StockItem.objects.filter(part=self.part).count(), n - 2) +class StockMetadataAPITest(InvenTreeAPITestCase): + """Unit tests for the various metadata endpoints of API.""" + + fixtures = [ + 'category', + 'part', + 'test_templates', + 'bom', + 'company', + 'location', + 'supplier_part', + 'stock', + 'stock_tests', + ] + + roles = ['stock.change', 'stock_location.change'] + + def metatester(self, raw_url: str, model): + """Generic tester.""" + modeldata = model.objects.first() + + # Useless test unless a model object is found + self.assertIsNotNone(modeldata) + + url = raw_url.format(pk=modeldata.pk) + + # Metadata is initially null + self.assertIsNone(modeldata.metadata) + + numstr = f'12{len(raw_url)}' + target_key = f'abc-{numstr}' + target_value = f'xyz-{raw_url}-{numstr}' + + # Create / update metadata entry (first try via old addresses) + data = {'metadata': {target_key: target_value}} + rsp = self.patch(url, data, expected_code=301) + self.patch(rsp.url, data, expected_code=200) + + # Refresh and check that metadata has been updated + modeldata.refresh_from_db() + self.assertEqual(modeldata.get_metadata(target_key), target_value) + + def test_metadata(self): + """Test all endpoints.""" + for raw_url, model in { + '/api/stock/location/{pk}/metadata/': StockLocation, + '/api/stock/test/{pk}/metadata/': StockItemTestResult, + '/api/stock/{pk}/metadata/': StockItem, + }.items(): + self.metatester(raw_url, model) + + class StockApiPerformanceTest(StockAPITestCase, InvenTreeAPIPerformanceTestCase): """Performance tests for the Stock API.""" diff --git a/src/backend/InvenTree/stock/test_migrations.py b/src/backend/InvenTree/stock/test_migrations.py index 7901239951..c5372b7204 100644 --- a/src/backend/InvenTree/stock/test_migrations.py +++ b/src/backend/InvenTree/stock/test_migrations.py @@ -189,7 +189,7 @@ class TestTestResultMigration(MigratorTestCase): for jj in range(4): si = StockItem.objects.create( part=child, - serial=str(1 + ii * jj), + serial=str(1 + jj), quantity=1, tree_id=0, level=0, @@ -415,3 +415,258 @@ class TestStockItemTrackingMigration(MigratorTestCase): ) self.assertIn('salesorder', item.deltas) self.assertEqual(item.deltas['salesorder'], 1) + + +class TestCreationDateMigration(MigratorTestCase): + """Test the backfill data migration for StockItem.creation_date (stock.0121). + + The migration has two passes: + - Pass 1: items with a CREATED (tracking_type=1) entry get creation_date from that entry. + - Pass 2: remaining nulls get min(updated, stocktake_date, earliest_tracking_entry). + + Six scenarios are exercised to cover every meaningful code path. + """ + + migrate_from = ('stock', '0119_alter_stockitemtestresult_date') + migrate_to = ('stock', '0122_alter_stockitem_creation_date') + + def prepare(self): + """Create StockItem entries with varied data to exercise all backfill paths.""" + import datetime + + from django.db import connection + + Part = self.old_state.apps.get_model('part', 'part') + StockItemTracking = self.old_state.apps.get_model('stock', 'stockitemtracking') + + utc = datetime.timezone.utc + + part = Part.objects.create( + name='Migration Test Part', level=0, tree_id=1, lft=0, rght=0 + ) + + def make_item(stocktake_date=None): + """Insert a StockItem row via raw SQL, bypassing the duplicate-column ORM bug. + + The historical model at migration 0119 has status_custom_key enumerated twice + (once from contribute_to_class on the status field, once from migration 0113's + explicit AddField), so ORM-generated INSERTs fail with + 'column specified more than once'. Raw SQL avoids the ORM field list entirely. + Raw SQL also leaves updated=NULL (no DB-level default for auto_now), which + makes Scenario 6 a clean "no date sources available" case. + """ + with connection.cursor() as cursor: + cursor.execute( + """ + INSERT INTO stock_stockitem + (part_id, quantity, level, tree_id, lft, rght, + status, delete_on_deplete, review_needed, is_building, + link, serial_int, barcode_data, barcode_hash) + VALUES (%s, 1, 0, 0, 0, 0, 10, false, false, false, '', 0, '', '') + RETURNING id + """, + [part.pk], + ) + pk = cursor.fetchone()[0] + if stocktake_date is not None: + cursor.execute( + 'UPDATE stock_stockitem SET stocktake_date = %s WHERE id = %s', + [stocktake_date, pk], + ) + return pk + + def add_tracking(pk, tracking_type, date): + """Create a tracking entry, then override its auto_now_add date.""" + entry = StockItemTracking.objects.create( + item_id=pk, tracking_type=tracking_type + ) + # auto_now_add prevents setting date on INSERT; use UPDATE to set a historical value + StockItemTracking.objects.filter(pk=entry.pk).update(date=date) + + # --- Scenario 1 --- + # Item with a single CREATED (type=1) tracking entry. + # Pass 1 should set creation_date = that entry's date. + pk = make_item() + add_tracking(pk, 1, datetime.datetime(2022, 1, 15, 10, 0, 0, tzinfo=utc)) + self.pk_s1 = pk + self.expected_s1 = datetime.datetime(2022, 1, 15, 10, 0, 0, tzinfo=utc) + + # --- Scenario 2 --- + # Item with a CREATED entry (newer date) AND an older non-CREATED entry. + # Pass 1 sets creation_date = CREATED entry date; older entry is ignored. + # This verifies pass 1 wins over pass 2's min() logic. + pk = make_item() + add_tracking( + pk, 1, datetime.datetime(2023, 6, 1, 0, 0, 0, tzinfo=utc) + ) # CREATED, newer + add_tracking( + pk, 2, datetime.datetime(2018, 3, 10, 0, 0, 0, tzinfo=utc) + ) # non-CREATED, older + self.pk_s2 = pk + self.expected_s2 = datetime.datetime(2023, 6, 1, 0, 0, 0, tzinfo=utc) + self.rejected_s2 = datetime.date(2018, 3, 10) + + # --- Scenario 3 --- + # Item with only non-CREATED tracking entries. + # Pass 2 uses min(earliest_entry_date), so earliest entry wins. + pk = make_item() + add_tracking( + pk, 2, datetime.datetime(2021, 7, 20, 0, 0, 0, tzinfo=utc) + ) # later + add_tracking( + pk, 3, datetime.datetime(2020, 2, 14, 0, 0, 0, tzinfo=utc) + ) # earliest + self.pk_s3 = pk + self.expected_s3 = datetime.datetime(2020, 2, 14, 0, 0, 0, tzinfo=utc) + + # --- Scenario 4 --- + # Item with only stocktake_date set; no tracking entries. + # Pass 2 uses stocktake_as_datetime (in the past) as the date. + pk = make_item(stocktake_date=datetime.date(2019, 11, 5)) + self.pk_s4 = pk + self.expected_s4_date = datetime.date(2019, 11, 5) + + # --- Scenario 5 --- + # Item with stocktake_date AND a non-CREATED tracking entry where the tracking + # entry is older than stocktake_date. + # Pass 2 uses min(stocktake, tracking); tracking wins. + pk = make_item(stocktake_date=datetime.date(2021, 4, 1)) + add_tracking(pk, 2, datetime.datetime(2017, 8, 22, 0, 0, 0, tzinfo=utc)) + self.pk_s5 = pk + self.expected_s5 = datetime.datetime(2017, 8, 22, 0, 0, 0, tzinfo=utc) + + # --- Scenario 6 --- + # Item inserted via raw SQL with no stocktake_date and no tracking entries, + # so updated=NULL. No date sources exist → creation_date stays NULL after migration. + pk = make_item() + self.pk_s6 = pk + + def test_migration(self): + """Verify creation_date is correctly backfilled for each scenario.""" + import datetime + + StockItem = self.new_state.apps.get_model('stock', 'stockitem') + utc = datetime.timezone.utc + + def at_utc(dt): + """Normalise to UTC and strip sub-second precision for comparison.""" + return dt.astimezone(utc).replace(microsecond=0) + + # Scenario 1: CREATED tracking entry → creation_date = entry date + item = StockItem.objects.get(pk=self.pk_s1) + self.assertIsNotNone(item.creation_date) + self.assertEqual(at_utc(item.creation_date), self.expected_s1) + + # Scenario 2: CREATED entry (newer) wins over older non-CREATED entry + item = StockItem.objects.get(pk=self.pk_s2) + self.assertIsNotNone(item.creation_date) + self.assertEqual(at_utc(item.creation_date), self.expected_s2) + # Explicitly confirm the older non-CREATED date was NOT chosen + self.assertNotEqual(item.creation_date.astimezone(utc).date(), self.rejected_s2) + + # Scenario 3: Earliest non-CREATED tracking entry wins (pass 2 min()) + item = StockItem.objects.get(pk=self.pk_s3) + self.assertIsNotNone(item.creation_date) + self.assertEqual(at_utc(item.creation_date), self.expected_s3) + + # Scenario 4: stocktake_date (past) wins over auto_now 'updated' (now) + item = StockItem.objects.get(pk=self.pk_s4) + self.assertIsNotNone(item.creation_date) + self.assertEqual( + item.creation_date.astimezone(utc).date(), self.expected_s4_date + ) + + # Scenario 5: Oldest tracking entry wins over stocktake_date (pass 2 min()) + item = StockItem.objects.get(pk=self.pk_s5) + self.assertIsNotNone(item.creation_date) + self.assertEqual(at_utc(item.creation_date), self.expected_s5) + + # Scenario 6: updated=NULL, no stocktake, no tracking → creation_date stays NULL + item = StockItem.objects.get(pk=self.pk_s6) + self.assertIsNone(item.creation_date) + + +class TestRemoveMpttFieldsMigration(MigratorTestCase): + """Test data migration which removes MPTT fields (level, lft, rght, tree_id) from StockItem. + + The 'parent' field itself is untouched by this migration - only the MPTT + bookkeeping fields are removed. This test ensures that parent-child + relationships between StockItem objects survive the migration boundary. + """ + + migrate_from = ('stock', '0123_remove_stockitem_review_needed') + migrate_to = ('stock', '0125_remove_mptt_fields') + + def prepare(self): + """Create a tree of StockItem objects with parent-child relationships.""" + from django.db import connection + + Part = self.old_state.apps.get_model('part', 'part') + StockItem = self.old_state.apps.get_model('stock', 'stockitem') + + part = Part.objects.create( + name='Migration Test Part', level=0, tree_id=0, lft=0, rght=0 + ) + + def make_item(quantity, parent_id=None): + """Insert via raw SQL to avoid duplicate status_custom_key ORM bug.""" + with connection.cursor() as cursor: + cursor.execute( + """ + INSERT INTO stock_stockitem + (part_id, quantity, level, tree_id, lft, rght, + status, delete_on_deplete, is_building, + link, serial_int, barcode_data, barcode_hash, parent_id) + VALUES (%s, %s, 0, 0, 0, 0, 10, false, false, '', 0, '', '', %s) + RETURNING id + """, + [part.pk, quantity, parent_id], + ) + return cursor.fetchone()[0] + + # Root stock item, with no parent + root_pk = make_item(100) + + # A set of child items, parented to the root item + child_pks = [make_item(10, root_pk) for _ in range(3)] + + # A grandchild item, parented to the first child item + grandchild_pk = make_item(1, child_pks[0]) + + # An unrelated top-level item, with no parent + orphan_pk = make_item(5) + + self.root_pk = root_pk + self.child_pks = child_pks + self.grandchild_pk = grandchild_pk + self.orphan_pk = orphan_pk + + self.assertEqual(StockItem.objects.count(), 6) + + def test_migration(self): + """Test that parent associations are preserved after MPTT fields are removed.""" + StockItem = self.new_state.apps.get_model('stock', 'stockitem') + + self.assertEqual(StockItem.objects.count(), 6) + + # The MPTT bookkeeping fields should no longer exist on the model + field_names = {field.name for field in StockItem._meta.get_fields()} + for removed_field in ['level', 'lft', 'rght', 'tree_id']: + self.assertNotIn(removed_field, field_names) + + # The root item still has no parent + root = StockItem.objects.get(pk=self.root_pk) + self.assertIsNone(root.parent_id) + + # Each child item is still correctly parented to the root item + for pk in self.child_pks: + child = StockItem.objects.get(pk=pk) + self.assertEqual(child.parent_id, self.root_pk) + + # The grandchild item is still correctly parented to the first child item + grandchild = StockItem.objects.get(pk=self.grandchild_pk) + self.assertEqual(grandchild.parent_id, self.child_pks[0]) + + # The orphan item still has no parent + orphan = StockItem.objects.get(pk=self.orphan_pk) + self.assertIsNone(orphan.parent_id) diff --git a/src/backend/InvenTree/stock/tests.py b/src/backend/InvenTree/stock/tests.py index 9495432366..fe8d3926bb 100644 --- a/src/backend/InvenTree/stock/tests.py +++ b/src/backend/InvenTree/stock/tests.py @@ -1,12 +1,19 @@ """Tests for stock app.""" import datetime +import threading +from unittest import mock +from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError +from django.db import connection, transaction from django.db.models import Sum -from django.test import override_settings +from django.test import TransactionTestCase, override_settings, skipUnlessDBFeature +from django.urls import reverse +from django_q.models import OrmQ from djmoney.money import Money +from rest_framework.test import APIClient from build.models import Build from common.models import InvenTreeSetting @@ -14,6 +21,8 @@ from company.models import Company from InvenTree.unit_test import AdminTestCase, InvenTreeTestCase from order.models import SalesOrder from part.models import Part, PartTestTemplate +from plugin.base.event.events import batch_events +from stock.events import StockEvents from stock.status_codes import StockHistoryCode, StockStatus from .models import ( @@ -22,6 +31,7 @@ from .models import ( StockItemTracking, StockLocation, StockLocationType, + batch_tracking_entries, ) @@ -346,6 +356,311 @@ class StockTest(StockTestBase): stock.splitStock(stock.quantity, None, self.user) self.assertEqual(StockItem.objects.filter(part=3).count(), n + 1) + def test_split_stock_tracking_deltas(self): + """The parent's SPLIT_CHILD_ITEM tracking entry must reference the new child item.""" + parent = StockItem.objects.get(id=1234) + child = parent.splitStock(100, None, self.user) + + parent_entry = parent.tracking_info.filter( + tracking_type=StockHistoryCode.SPLIT_CHILD_ITEM.value + ).first() + + self.assertIsNotNone(parent_entry) + self.assertEqual(parent_entry.deltas.get('stockitem'), child.pk) + + def test_delete_reparents_children(self): + """Test that deleting an intermediate item re-links children to the grandparent.""" + grandparent = StockItem.objects.get(id=1234) + + parent = grandparent.splitStock(200, None, self.user) + child_a = parent.splitStock(50, None, self.user) + child_b = parent.splitStock(50, None, self.user) + + self.assertEqual(parent.parent, grandparent) + self.assertEqual(child_a.parent, parent) + self.assertEqual(child_b.parent, parent) + + # Deleting the intermediate item grafts its children onto the grandparent + parent.delete() + + child_a.refresh_from_db() + child_b.refresh_from_db() + + self.assertEqual(child_a.parent, grandparent) + self.assertEqual(child_b.parent, grandparent) + + # Deleting a top-level item leaves its children with no parent + grandparent.delete() + + child_a.refresh_from_db() + child_b.refresh_from_db() + + self.assertIsNone(child_a.parent) + self.assertIsNone(child_b.parent) + + def test_implicit_delete_reparents_children(self): + """Test child re-linking when items are deleted by depletion or merging.""" + grandparent = StockItem.objects.get(id=1234) + + # An item depleted to zero with delete_on_deplete set is deleted + parent = grandparent.splitStock(200, None, self.user) + child = parent.splitStock(50, None, self.user) + + parent.delete_on_deplete = True + parent.save() + + self.assertTrue(parent.take_stock(150, self.user, notes='Deplete')) + self.assertFalse(StockItem.objects.filter(pk=parent.pk).exists()) + + child.refresh_from_db() + self.assertEqual(child.parent, grandparent) + + # An item absorbed by a merge is also deleted + source = grandparent.splitStock(100, None, self.user) + kid = source.splitStock(25, None, self.user) + + target = StockItem.objects.create( + part=grandparent.part, + supplier_part=grandparent.supplier_part, + quantity=10, + location=grandparent.location, + ) + + target.merge_stock_items([source], raise_error=True, user=self.user) + + self.assertFalse(StockItem.objects.filter(pk=source.pk).exists()) + + kid.refresh_from_db() + self.assertEqual(kid.parent, grandparent) + + def test_over_adjustment_quantities(self): + """Stock adjustments are clamped to the available stock quantity. + + Regression test: take_stock / allocateToCustomer / installStockItem + previously recorded the *requested* quantity in the stock history, + even when less stock was actually removed / allocated / installed. + """ + part = Part.objects.create( + name='Clamp part', + description='A part for quantity clamping tests', + salable=True, + component=True, + ) + + # --- take_stock: remove more than available --- + item = StockItem.objects.create(part=part, quantity=10, delete_on_deplete=False) + + self.assertTrue(item.take_stock(25, self.user, notes='over-remove')) + + item.refresh_from_db() + self.assertEqual(item.quantity, 0) + + # History records the quantity which was *actually* removed + entry = item.tracking_info.latest('pk') + self.assertEqual(entry.deltas['removed'], 10.0) + self.assertEqual(entry.deltas['quantity'], 0.0) + + # Removing stock from an empty item fails, and adds no history + n = item.tracking_info.count() + self.assertFalse(item.take_stock(5, self.user)) + self.assertEqual(item.tracking_info.count(), n) + + # --- allocateToCustomer: allocate more than available --- + customer = Company.objects.create(name='Clamp customer', is_customer=True) + + item = StockItem.objects.create(part=part, quantity=10) + + allocated = item.allocateToCustomer(customer, quantity=25, user=self.user) + + # The whole item is allocated (no split occurs) + self.assertEqual(allocated.pk, item.pk) + self.assertEqual(allocated.customer, customer) + + # History records the quantity which was *actually* allocated + entry = allocated.tracking_info.latest('pk') + self.assertEqual(entry.deltas['quantity'], 10.0) + + # A zero quantity is rejected outright + item = StockItem.objects.create(part=part, quantity=10) + + with self.assertRaises(ValidationError): + item.allocateToCustomer(customer, quantity=0, user=self.user) + + # --- installStockItem: install more than available --- + assembly = Part.objects.create( + name='Clamp assembly', + description='An assembly for quantity clamping tests', + assembly=True, + ) + + parent_item = StockItem.objects.create(part=assembly, quantity=1) + component = StockItem.objects.create(part=part, quantity=10) + + parent_item.installStockItem(component, 25, self.user, 'over-install') + + component.refresh_from_db() + self.assertEqual(component.belongs_to, parent_item) + self.assertEqual(component.quantity, 10) + + # Both history entries record the quantity which was *actually* installed + entry = component.tracking_info.filter( + tracking_type=StockHistoryCode.INSTALLED_INTO_ASSEMBLY + ).latest('pk') + self.assertEqual(entry.deltas['quantity'], 10.0) + + entry = parent_item.tracking_info.filter( + tracking_type=StockHistoryCode.INSTALLED_CHILD_ITEM + ).latest('pk') + self.assertEqual(entry.deltas['quantity'], 10.0) + + # A zero quantity is rejected outright + other = StockItem.objects.create(part=part, quantity=5) + + with self.assertRaises(ValidationError): + parent_item.installStockItem(other, 0, self.user, 'bad install') + + def test_uninstall_into_structural_location(self): + """Test that an item cannot be uninstalled into a structural location.""" + parent = StockItem.objects.get(pk=1) + + item = StockItem.objects.get(pk=2) + item.belongs_to = parent + item.save() + + n_entries = item.tracking_info.count() + n_parent_entries = parent.tracking_info.count() + + structural = StockLocation.objects.create( + name='Structural location', structural=True + ) + + with self.assertRaises(ValidationError): + item.uninstall_into_location(structural, self.user, 'Uninstalling') + + # The item remains installed, with no location change or tracking entries + item.refresh_from_db() + self.assertEqual(item.belongs_to, parent) + self.assertNotEqual(item.location, structural) + self.assertEqual(item.tracking_info.count(), n_entries) + self.assertEqual(parent.tracking_info.count(), n_parent_entries) + + # Uninstalling into a non-structural location is still permitted + item.uninstall_into_location(self.drawer2, self.user, 'Uninstalling') + + item.refresh_from_db() + self.assertIsNone(item.belongs_to) + self.assertEqual(item.location, self.drawer2) + + def test_child_items(self): + """Test the 'children' reverse relation and 'child_count' property. + + Regression test: StockItem previously defined a 'children' property + (shadowed by the reverse FK accessor, and referencing a method which no + longer exists on the model). The property has been removed - 'children' + must resolve to the reverse foreign-key manager for the 'parent' field. + """ + part = Part.objects.create( + name='Child test part', description='A part for child item testing' + ) + + parent = StockItem.objects.create(part=part, quantity=100) + + self.assertEqual(parent.children.count(), 0) + self.assertEqual(parent.child_count, 0) + self.assertEqual(parent.get_children().count(), 0) + + # Split off two child items + child_1 = parent.splitStock(10, None, self.user) + child_2 = parent.splitStock(20, None, self.user) + + parent.refresh_from_db() + self.assertEqual(parent.quantity, 70) + + children = parent.children.all() + + self.assertEqual(children.count(), 2) + self.assertEqual(parent.child_count, 2) + self.assertIn(child_1, children) + self.assertIn(child_2, children) + + # get_children() proxies the same relation + self.assertEqual( + list(parent.get_children().order_by('pk')), list(children.order_by('pk')) + ) + + # Only *direct* children are included + grandchild = child_1.splitStock(5, None, self.user) + + self.assertEqual(parent.child_count, 2) + self.assertEqual(child_1.child_count, 1) + self.assertIn(grandchild, child_1.children.all()) + self.assertNotIn(grandchild, parent.children.all()) + + def test_adjustment_stale_quantity(self): + """Stock adjustments operate on database quantities, not stale in-memory copies. + + Simulates concurrent adjustment operations, where each worker holds + its own (stale) in-memory copy of the same StockItem. + """ + item = StockItem.objects.get(pk=1234) + self.assertEqual(item.quantity, 1234) + + # Remove stock via two independent in-memory copies + item_a = StockItem.objects.get(pk=item.pk) + item_b = StockItem.objects.get(pk=item.pk) + + self.assertTrue(item_a.take_stock(100, self.user)) + self.assertTrue(item_b.take_stock(200, self.user)) + + item.refresh_from_db() + self.assertEqual(item.quantity, 934) + + # Add stock via a stale copy + item_c = StockItem.objects.get(pk=item.pk) + item.take_stock(34, self.user) + + self.assertTrue(item_c.add_stock(100, self.user)) + + item.refresh_from_db() + self.assertEqual(item.quantity, 1000) + + # Split stock via a stale copy + item_d = StockItem.objects.get(pk=item.pk) + item.take_stock(500, self.user) + + child = item_d.splitStock(300, None, self.user) + + item.refresh_from_db() + self.assertEqual(item.quantity, 200) + self.assertEqual(child.quantity, 300) + + # A full-quantity move via a stale copy must not resurrect removed stock + item_e = StockItem.objects.get(pk=item.pk) + item.take_stock(50, self.user) + + self.assertTrue(item_e.move(self.diningroom, 'Move', self.user)) + + item.refresh_from_db() + self.assertEqual(item.quantity, 150) + self.assertEqual(item.location, self.diningroom) + + def test_merge_stale_quantity(self): + """Merging stock items uses database quantities, not stale in-memory values.""" + part = Part.objects.get(pk=3) + + target = StockItem.objects.create(part=part, quantity=100) + source = StockItem.objects.create(part=part, quantity=50) + + # Hold a stale copy of the target, and adjust the real row underneath it + stale_target = StockItem.objects.get(pk=target.pk) + target.take_stock(60, self.user) + + stale_target.merge_stock_items([source], user=self.user) + + target.refresh_from_db() + self.assertEqual(target.quantity, 90) + self.assertFalse(StockItem.objects.filter(pk=source.pk).exists()) + def test_stocktake(self): """Test stocktake function.""" # Perform stocktake @@ -378,16 +693,84 @@ class StockTest(StockTestBase): self.assertEqual(it.status, StockStatus.OK.value) # Next, perform a valid stocktake - self.assertTrue( - it.stocktake( - 100, None, notes='test stocktake', status=StockStatus.DAMAGED.value - ) + it.stocktake( + 100, None, notes='test stocktake', status=StockStatus.DAMAGED.value ) it.refresh_from_db() self.assertEqual(it.quantity, 100) self.assertEqual(it.status, StockStatus.DAMAGED.value) + def get_counted_events(self): + """Helper: return queued OrmQ tasks corresponding to a StockEvents.ITEM_COUNTED event. + + stocktake() also fires an ITEM_QUANTITY_UPDATED event (via updateQuantity()) and may + offload a (deduped) low-stock notification task, so tests filter down to just the + ITEM_COUNTED entries they care about, rather than asserting the raw queue total. + """ + return [ + task + for task in OrmQ.objects.all().order_by('id') + if task.args() == (StockEvents.ITEM_COUNTED,) + ] + + def test_stocktake_batch_events(self): + """Test that batch_events() collapses per-item stocktake() events into one bulk write. + + StockItem.stocktake() always calls trigger_event() exactly as it does when called + standalone (see test_stocktake_events_outside_batch below) - a bulk caller wraps its + loop in batch_events() to collapse those N individual event offloads into a single + bulk_trigger_event() call, fired when the enclosing transaction commits. + """ + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + part = Part.objects.create( + name='Batch stocktake part', description='For batch stocktake testing' + ) + + items = [ + StockItem.objects.create(part=part, location=self.home, quantity=idx + 1) + for idx in range(10) + ] + + OrmQ.objects.all().delete() + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + # All 10 ITEM_COUNTED events should be queued via a single bulk write, + # fired when the transaction commits (captured here via captureOnCommitCallbacks) + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), batch_events(): + for idx, item in enumerate(items): + item.stocktake(100 + idx, self.user, notes='Batch stocktake') + + counted_tasks = self.get_counted_events() + self.assertEqual(len(counted_tasks), 10) + + for idx, (task, item) in enumerate(zip(counted_tasks, items, strict=True)): + self.assertEqual(task.func(), 'plugin.base.event.events.register_event') + self.assertEqual(task.kwargs(), {'id': item.id, 'quantity': 100.0 + idx}) + + def test_stocktake_events_outside_batch(self): + """Test that stocktake() still fires events immediately when called outside batch_events().""" + InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None) + + item = StockItem.objects.get(pk=2) + + OrmQ.objects.all().delete() + + with self.settings( + PLUGIN_TESTING_EVENTS=True, PLUGIN_TESTING_EVENTS_ASYNC=True + ): + item.stocktake(42, self.user, notes='Single stocktake') + + # No batch_events() context was active, so the event was queued immediately - + # no transaction commit or captureOnCommitCallbacks is required to see it + counted_tasks = self.get_counted_events() + self.assertEqual(len(counted_tasks), 1) + self.assertEqual(counted_tasks[0].kwargs(), {'id': item.id, 'quantity': 42.0}) + def test_add_stock(self): """Test adding stock.""" it = StockItem.objects.get(pk=2) @@ -729,6 +1112,13 @@ class StockTest(StockTestBase): self.assertEqual(s1.quantity, 60) self.assertIsNone(s1.purchase_price) + merge_entry = s1.tracking_info.filter( + tracking_type=StockHistoryCode.MERGED_STOCK_ITEMS + ).first() + self.assertIsNotNone(merge_entry) + self.assertEqual(merge_entry.deltas['added'], 50.0) + self.assertEqual(merge_entry.deltas['quantity'], 60.0) + part.stock_items.all().delete() # Create some stock items with pricing information @@ -766,6 +1156,54 @@ class StockTest(StockTestBase): # Final purchase price should be the weighted average self.assertAlmostEqual(s1.purchase_price.amount, 16.875, places=3) + def test_merge_protected_items(self): + """Stock items in a protected state cannot be absorbed by a merge. + + Regression test: merge_stock_items() used to run the generic state checks + (in production, assigned to customer, etc.) against the *target* item only, + allowing e.g. a build output to be merged away and deleted. + """ + part = Part.objects.first() + part.stock_items.all().delete() + + target = StockItem.objects.create(part=part, quantity=10) + + # The incoming item is "in production" (a build output) + part.assembly = True + part.save() + + bo = Build.objects.create( + reference='BO-9998', part=part, title='Merge test build', quantity=20 + ) + + building = StockItem.objects.create( + part=part, quantity=20, build=bo, is_building=True + ) + + # Without raise_error, the merge is refused silently + target.merge_stock_items([building]) + + target.refresh_from_db() + building.refresh_from_db() + + self.assertEqual(part.stock_items.count(), 2) + self.assertEqual(target.quantity, 10) + self.assertEqual(building.quantity, 20) + + # With raise_error, the merge raises a ValidationError + with self.assertRaises(ValidationError): + target.merge_stock_items([building], raise_error=True) + + # An item assigned to a customer is likewise protected + customer = Company.objects.create(name='MergeCust', is_customer=True) + assigned = StockItem.objects.create(part=part, quantity=5, customer=customer) + + target.merge_stock_items([assigned]) + + target.refresh_from_db() + self.assertEqual(target.quantity, 10) + self.assertTrue(StockItem.objects.filter(pk=assigned.pk).exists()) + def test_notify_low_stock(self): """Test that the 'notify_low_stock' task is triggered correctly.""" FUNC_NAME = 'part.tasks.notify_low_stock_if_required' @@ -827,6 +1265,130 @@ class StockTest(StockTestBase): self.assertEqual(item.purchase_price_currency, 'GBP') +class TrackingEntryBatchTests(StockTestBase): + """Unit tests for the batch_tracking_entries() context manager.""" + + def test_entries_queued_and_flushed_on_commit(self): + """Tracking entries created inside batch_tracking_entries() are bulk-created on commit.""" + item = StockItem.objects.get(pk=2) + + n = StockItemTracking.objects.count() + + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), batch_tracking_entries(): + for idx in range(10): + item.add_tracking_entry( + StockHistoryCode.STOCK_COUNT, + self.user, + deltas={'quantity': idx}, + notes=f'Batch entry {idx}', + ) + + # Nothing should be written yet - the batch only flushes on commit + self.assertEqual(StockItemTracking.objects.count(), n) + + entries = StockItemTracking.objects.filter(item=item).order_by('id')[:10] + self.assertEqual(StockItemTracking.objects.count(), n + 10) + + for idx, entry in enumerate(entries): + self.assertEqual(entry.tracking_type, StockHistoryCode.STOCK_COUNT) + self.assertEqual(entry.deltas.get('quantity'), idx) + self.assertEqual(entry.notes, f'Batch entry {idx}') + + def test_entries_discarded_on_rollback(self): + """Tracking entries queued in a batch are discarded if the transaction rolls back.""" + item = StockItem.objects.get(pk=2) + + n = StockItemTracking.objects.count() + + with self.captureOnCommitCallbacks(execute=True): + try: + with transaction.atomic(), batch_tracking_entries(): + item.add_tracking_entry( + StockHistoryCode.STOCK_COUNT, self.user, deltas={'quantity': 1} + ) + raise ValueError('boom') + except ValueError: + pass + + self.assertEqual(StockItemTracking.objects.count(), n) + + def test_entries_outside_batch_fire_immediately(self): + """Tracking entries created outside any batch are unaffected - saved immediately.""" + item = StockItem.objects.get(pk=2) + + n = StockItemTracking.objects.count() + + item.add_tracking_entry( + StockHistoryCode.STOCK_COUNT, self.user, deltas={'quantity': 1} + ) + + # No transaction commit or captureOnCommitCallbacks needed - it was never queued + self.assertEqual(StockItemTracking.objects.count(), n + 1) + + def test_nested_batch_share_one_flush(self): + """A nested batch_tracking_entries() call reuses the outer batch, rather than flushing twice.""" + item = StockItem.objects.get(pk=2) + + n = StockItemTracking.objects.count() + + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), batch_tracking_entries(): + item.add_tracking_entry( + StockHistoryCode.STOCK_COUNT, self.user, deltas={'quantity': 1} + ) + with batch_tracking_entries(): + item.add_tracking_entry( + StockHistoryCode.STOCK_COUNT, self.user, deltas={'quantity': 2} + ) + self.assertEqual(StockItemTracking.objects.count(), n) + + self.assertEqual(StockItemTracking.objects.count(), n + 2) + + def test_commit_false_is_unaffected_by_batch(self): + """commit=False callers keep manual ownership of the entry, even inside a batch.""" + item = StockItem.objects.get(pk=2) + + n = StockItemTracking.objects.count() + + with transaction.atomic(), batch_tracking_entries(): + entry = item.add_tracking_entry( + StockHistoryCode.STOCK_COUNT, + self.user, + deltas={'quantity': 1}, + commit=False, + ) + + # The entry was returned uncommitted - the batch never saw it, so it was never written + self.assertIsNotNone(entry) + self.assertIsNone(entry.pk) + self.assertEqual(StockItemTracking.objects.count(), n) + + def test_stocktake_batch_tracking_entries(self): + """Integration test: batching stocktake() tracking entries via the StockCountSerializer path.""" + part = Part.objects.create( + name='Batch tracking part', description='For batch tracking testing' + ) + + items = [ + StockItem.objects.create(part=part, location=self.home, quantity=idx + 1) + for idx in range(10) + ] + + n = StockItemTracking.objects.count() + + with self.captureOnCommitCallbacks(execute=True): + with transaction.atomic(), batch_tracking_entries(): + for idx, item in enumerate(items): + item.stocktake(100 + idx, self.user, notes='Batch stocktake') + + entries = StockItemTracking.objects.filter( + item__in=items, tracking_type=StockHistoryCode.STOCK_COUNT + ).order_by('id') + self.assertEqual(entries.count(), 10) + self.assertEqual(StockItemTracking.objects.count(), n + 10) + + class StockBarcodeTest(StockTestBase): """Run barcode tests for the stock app.""" @@ -934,7 +1496,6 @@ class VariantTest(StockTestBase): # Attempt to create the same serial number but for a variant (should fail!) # Reset the primary key and tree_id values item.pk = None - item.tree_id = None item.part = Part.objects.get(pk=10004) with self.assertRaises(ValidationError): @@ -1149,187 +1710,6 @@ class StockLocationTreeTest(StockTestBase): self.assertEqual(C22.get_ancestors().count(), 1) -class StockTreeTest(StockTestBase): - """Unit test for StockItem tree structure.""" - - def test_stock_split(self): - """Test that stock splitting works correctly.""" - part = Part.objects.create(name='My part', description='My part description') - location = StockLocation.objects.create(name='Test Location') - - # Create an initial stock item - item = StockItem.objects.create(part=part, quantity=1000, location=location) - - # Test that the initial MPTT values are correct - self.assertEqual(item.level, 0) - self.assertEqual(item.lft, 1) - self.assertEqual(item.rght, 2) - - children = [] - - self.assertEqual(item.get_descendants(include_self=False).count(), 0) - self.assertEqual(item.get_descendants(include_self=True).count(), 1) - - # Create child items by splitting stock - for idx in range(10): - child = item.splitStock(50, None, None) - children.append(child) - - # Check that the child item has been correctly created - self.assertEqual(child.parent.pk, item.pk) - self.assertEqual(child.tree_id, item.tree_id) - self.assertEqual(child.level, 1) - - item.refresh_from_db() - self.assertEqual(item.get_children().count(), idx + 1) - self.assertEqual(item.get_descendants(include_self=True).count(), idx + 2) - - item.refresh_from_db() - n = item.get_descendants(include_self=True).count() - - for child in children: - # Create multiple sub-childs - for _idx in range(3): - sub_child = child.splitStock(10, None, None) - self.assertEqual(sub_child.parent.pk, child.pk) - self.assertEqual(sub_child.tree_id, child.tree_id) - self.assertEqual(sub_child.level, 2) - - self.assertEqual(sub_child.get_ancestors(include_self=True).count(), 3) - - child.refresh_from_db() - self.assertEqual(child.get_descendants(include_self=True).count(), 4) - - item.refresh_from_db() - self.assertEqual(item.get_descendants(include_self=True).count(), n + 30) - - def test_tree_rebuild(self): - """Test that tree rebuild works correctly.""" - part = Part.objects.create(name='My part', description='My part description') - location = StockLocation.objects.create(name='Test Location') - - N = StockItem.objects.count() - - # Create an initial stock item - item = StockItem.objects.create(part=part, quantity=1000, location=location) - - # Split out ten child items - for _idx in range(10): - item.splitStock(10) - - item.refresh_from_db() - - self.assertEqual(StockItem.objects.count(), N + 11) - self.assertEqual(item.get_children().count(), 10) - self.assertEqual(item.get_descendants(include_self=True).count(), 11) - - # Split the first child item - child = item.get_children().first() - - self.assertEqual(child.parent, item) - self.assertEqual(child.tree_id, item.tree_id) - self.assertEqual(child.level, 1) - - # Split out three grandchildren - for _ in range(3): - child.splitStock(2) - - item.refresh_from_db() - child.refresh_from_db() - - self.assertEqual(child.get_descendants(include_self=True).count(), 4) - self.assertEqual(child.get_children().count(), 3) - - # Check tree structure for grandchildren - grandchildren = child.get_children() - - for gc in grandchildren: - self.assertEqual(gc.parent, child) - self.assertEqual(gc.parent.parent, item) - self.assertEqual(gc.tree_id, item.tree_id) - self.assertEqual(gc.level, 2) - self.assertGreater(gc.lft, child.lft) - self.assertLess(gc.rght, child.rght) - - self.assertEqual(item.get_children().count(), 10) - self.assertEqual(item.get_descendants(include_self=True).count(), 14) - - # Now, delete the child node - # We expect that the grandchildren will be re-parented to the parent node - child.delete() - - for gc in grandchildren: - gc.refresh_from_db() - - # Check that the grandchildren have been re-parented to the top-level - self.assertEqual(gc.parent, item) - self.assertEqual(gc.tree_id, item.tree_id) - self.assertEqual(gc.level, 1) - self.assertGreater(gc.lft, item.lft) - self.assertLess(gc.rght, item.rght) - - item.refresh_from_db() - - self.assertEqual(item.get_children().count(), 12) - self.assertEqual(item.get_descendants(include_self=True).count(), 13) - - def test_serialize(self): - """Test that StockItem serialization maintains tree structure.""" - part = Part.objects.create( - name='My part', description='My part description', trackable=True - ) - - N = StockItem.objects.count() - - # Create an initial stock item - item_1 = StockItem.objects.create(part=part, quantity=1000) - item_2 = item_1.splitStock(750) - - item_1.refresh_from_db() - - self.assertEqual(StockItem.objects.count(), N + 2) - self.assertEqual(item_1.get_children().count(), 1) - self.assertEqual(item_2.parent, item_1) - - loc = StockLocation.objects.filter(structural=False).first() - - # Serialize the secondary item - serials = [str(i) for i in range(20)] - items = item_2.serializeStock(20, serials, location=loc) - - self.assertEqual(len(items), 20) - self.assertEqual(StockItem.objects.count(), N + 22) - - item_1.refresh_from_db() - item_2.refresh_from_db() - - self.assertEqual(item_1.get_children().count(), 1) - self.assertEqual(item_2.get_children().count(), 20) - - for child in items: - self.assertEqual(child.tree_id, item_2.tree_id) - self.assertEqual(child.level, 2) - self.assertEqual(child.parent, item_2) - self.assertGreater(child.lft, item_2.lft) - self.assertLess(child.rght, item_2.rght) - self.assertEqual(child.location, loc) - self.assertIsNotNone(child.location) - self.assertEqual(child.tracking_info.count(), 2) - - # Delete item_2 : we expect that all children will be re-parented to item_1 - item_2.delete() - - for child in items: - child.refresh_from_db() - - # Check that the children have been re-parented to item_1 - self.assertEqual(child.parent, item_1) - self.assertEqual(child.tree_id, item_1.tree_id) - self.assertEqual(child.level, 1) - self.assertGreater(child.lft, item_1.lft) - self.assertLess(child.rght, item_1.rght) - - class TestResultTest(StockTestBase): """Tests for the StockItemTestResult model.""" @@ -1591,3 +1971,385 @@ class AdminTest(AdminTestCase): def test_admin(self): """Test the admin URL.""" self.helper(model=StockLocationType) + + +@skipUnlessDBFeature('has_select_for_update') +class StockItemSerialConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for StockItem._create_serial_numbers(). + + Uses two real threads (each with its own database connection) to reproduce + the reported race: two concurrent requests to create a StockItem with the + *same* serial number for the same Part could both check for conflicts + before either had committed its bulk_create - producing two StockItem rows + sharing one (part, serial) pair. + + _create_serial_numbers() now locks (select_for_update, on the Part rows + covering the relevant scope - see StockItem._lock_serial_numbers()) and + re-validates for conflicts under that lock before creating anything, and + a database-level UniqueConstraint on (part, serial) backstops it, so only + one of two concurrent requests for the same serial number may succeed. + """ + + fixtures = ['users'] + + def setUp(self): + """Create a single trackable Part to create serialized stock against.""" + super().setUp() + + self.part = Part.objects.create( + name='Concurrency serial part', + description='Part for serial creation concurrency test', + trackable=True, + ) + + def test_concurrent_creation_does_not_duplicate_serial(self): + """Two concurrent requests for the same serial number must not both succeed.""" + start_barrier = threading.Barrier(2, timeout=5) + errors = [] + results = [] + + # Wrap StockItem._lock_serial_numbers() so both threads reach the + # (real, database-level) row lock at the same time - one wins the + # lock and proceeds, the other blocks until the winner's transaction + # completes. + original_lock_serial_numbers = StockItem._lock_serial_numbers + + def synced_lock_serial_numbers(part, serials): + start_barrier.wait(timeout=5) + return original_lock_serial_numbers(part, serials) + + def create(): + try: + StockItem._create_serial_numbers(['SN-RACE'], part=self.part) + results.append('ok') + except ValidationError: + results.append('rejected') + except Exception as exc: # pragma: no cover - surfaced via errors list + errors.append(exc) + finally: + connection.close() + + thread_a = threading.Thread(target=create) + thread_b = threading.Thread(target=create) + + with mock.patch.object( + StockItem, '_lock_serial_numbers', synced_lock_serial_numbers + ): + thread_a.start() + thread_b.start() + + thread_a.join(timeout=5) + thread_b.join(timeout=5) + + self.assertFalse(thread_a.is_alive()) + self.assertFalse(thread_b.is_alive()) + self.assertEqual(errors, []) + + # Exactly one request must have been rejected as a duplicate + self.assertEqual(sorted(results), ['ok', 'rejected']) + + # The serial number must only have been created once + self.assertEqual( + StockItem.objects.filter(part=self.part, serial='SN-RACE').count(), 1 + ) + + +@skipUnlessDBFeature('has_select_for_update') +class StockItemSerialBatchConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for overlapping batch serial creation. + + Extends the single-serial race in StockItemSerialConcurrencyTest to the + more realistic case of *bulk* serial number creation: three concurrent + requests, each creating 10 serial numbers, with the requested ranges + overlapping pairwise (but not all three sharing any single serial): + + A: 1-10 + B: 6-15 (overlaps A on 6-10, and C on 11-15) + C: 11-20 + + Since _create_serial_numbers() creates its whole batch atomically (a + conflict anywhere in the batch aborts the batch entirely), and A and C do + not share any serial with each other, exactly one of the following must + occur: + + - B is rejected, and A and C both succeed in full, or + - B succeeds in full, and both A and C are rejected + + In neither case can two of the three batches both succeed, and in neither + case can any serial number be created more than once. Since all three + batches target the same Part, StockItem._lock_serial_numbers() locks the + same Part rows for each of them (rather than locking anything specific to + the requested serials), so the three requests are fully serialized + against each other regardless of which serials they overlap on. + """ + + fixtures = ['users'] + + def setUp(self): + """Create a single trackable Part to create serialized stock against.""" + super().setUp() + + self.part = Part.objects.create( + name='Concurrency batch serial part', + description='Part for batch serial creation concurrency test', + trackable=True, + ) + + def test_concurrent_overlapping_batches_do_not_duplicate_serials(self): + """Three concurrent, partially-overlapping batch creation requests must stay consistent.""" + start_barrier = threading.Barrier(3, timeout=10) + errors = [] + results = {} + results_lock = threading.Lock() + + # Wrap StockItem._lock_serial_numbers() so all three threads reach the + # (real, database-level) row locks at the same time, maximising + # contention across the overlapping sets of serial numbers. + original_lock_serial_numbers = StockItem._lock_serial_numbers + + def synced_lock_serial_numbers(part, serials): + start_barrier.wait(timeout=10) + return original_lock_serial_numbers(part, serials) + + batches = { + 'a': [str(i) for i in range(1, 11)], # 1-10 + 'b': [str(i) for i in range(6, 16)], # 6-15 + 'c': [str(i) for i in range(11, 21)], # 11-20 + } + + def create(name, serials): + try: + StockItem._create_serial_numbers(serials, part=self.part) + with results_lock: + results[name] = 'ok' + except ValidationError: + with results_lock: + results[name] = 'rejected' + except Exception as exc: # pragma: no cover - surfaced via errors list + with results_lock: + errors.append(exc) + finally: + connection.close() + + threads = [ + threading.Thread(target=create, args=(name, serials)) + for name, serials in batches.items() + ] + + with mock.patch.object( + StockItem, '_lock_serial_numbers', synced_lock_serial_numbers + ): + for thread in threads: + thread.start() + + for thread in threads: + thread.join(timeout=10) + + for thread in threads: + self.assertFalse(thread.is_alive()) + self.assertEqual(errors, []) + self.assertEqual(set(results.keys()), {'a', 'b', 'c'}) + + # Batch 'b' overlaps both 'a' and 'c', which do not overlap each + # other - so either 'b' alone wins, or both 'a' and 'c' win, never + # any other combination + ok = {name for name, outcome in results.items() if outcome == 'ok'} + self.assertIn(ok, [{'b'}, {'a', 'c'}]) + + # No serial number was created more than once + created_serials = list( + StockItem.objects.filter(part=self.part).values_list('serial', flat=True) + ) + self.assertEqual(len(created_serials), len(set(created_serials))) + + # The created serials are exactly the union of the winning batches - + # each successful batch's serials all exist, and (since a rejected + # batch creates nothing at all) nothing beyond that union exists + expected_serials = set() + for name in ok: + expected_serials.update(batches[name]) + + self.assertEqual(set(created_serials), expected_serials) + + +@skipUnlessDBFeature('has_select_for_update') +class StockItemSerialGloballyUniqueConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test for the globally-unique locking path. + + Reproduces the same race as StockItemSerialConcurrencyTest, but with + SERIAL_NUMBER_GLOBALLY_UNIQUE enabled and the two concurrent requests + targeting *different* parts (in different variant trees). There is no + single Part tree covering this scope, so StockItem._lock_serial_numbers() + instead locks the SERIAL_NUMBER_GLOBALLY_UNIQUE setting's own row - this + verifies that still serializes the two requests correctly. + """ + + fixtures = ['users'] + + def setUp(self): + """Create two unrelated trackable Parts (in different variant trees).""" + super().setUp() + + InvenTreeSetting.set_setting('SERIAL_NUMBER_GLOBALLY_UNIQUE', True, None) + self.addCleanup( + InvenTreeSetting.set_setting, 'SERIAL_NUMBER_GLOBALLY_UNIQUE', False, None + ) + + self.part_a = Part.objects.create( + name='Globally-unique concurrency part A', + description='Part A for globally-unique serial concurrency test', + trackable=True, + ) + self.part_b = Part.objects.create( + name='Globally-unique concurrency part B', + description='Part B for globally-unique serial concurrency test', + trackable=True, + ) + + def test_concurrent_creation_across_parts_does_not_duplicate_serial(self): + """Two concurrent requests for different parts must not both succeed.""" + start_barrier = threading.Barrier(2, timeout=5) + errors = [] + results = {} + results_lock = threading.Lock() + + original_lock_serial_numbers = StockItem._lock_serial_numbers + + def synced_lock_serial_numbers(part, serials): + start_barrier.wait(timeout=5) + return original_lock_serial_numbers(part, serials) + + def create(name, part): + try: + StockItem._create_serial_numbers(['SN-RACE'], part=part) + with results_lock: + results[name] = 'ok' + except ValidationError: + with results_lock: + results[name] = 'rejected' + except Exception as exc: # pragma: no cover - surfaced via errors list + with results_lock: + errors.append(exc) + finally: + connection.close() + + thread_a = threading.Thread(target=create, args=('a', self.part_a)) + thread_b = threading.Thread(target=create, args=('b', self.part_b)) + + with mock.patch.object( + StockItem, '_lock_serial_numbers', synced_lock_serial_numbers + ): + thread_a.start() + thread_b.start() + + thread_a.join(timeout=5) + thread_b.join(timeout=5) + + self.assertFalse(thread_a.is_alive()) + self.assertFalse(thread_b.is_alive()) + self.assertEqual(errors, []) + + # Exactly one request must have been rejected as a duplicate, even + # though the two parts are unrelated + self.assertEqual(sorted(results.values()), ['ok', 'rejected']) + + # The serial number must only have been created once, across both parts + self.assertEqual( + StockItem.objects.filter( + part__in=[self.part_a, self.part_b], serial='SN-RACE' + ).count(), + 1, + ) + + +@skipUnlessDBFeature('has_select_for_update') +class StockItemSerialAPIConcurrencyTest(TransactionTestCase): + """Genuine cross-transaction regression test driven through the real StockItem creation API. + + Same race as StockItemSerialConcurrencyTest, but issued as five + concurrent HTTP POST requests against the 'api-stock-list' endpoint + (stock.api.StockList.create()) rather than calling + StockItem._create_serial_numbers() directly - this exercises the full + view/serializer stack (permission checks, serial number extraction, + pre-validation) under concurrency, not just the locking primitive itself. + """ + + fixtures = ['users'] + + def setUp(self): + """Create a superuser and a single trackable Part to create serialized stock against.""" + super().setUp() + + self.user = get_user_model().objects.get(username='sue_the_superuser') + + self.part = Part.objects.create( + name='API concurrency serial part', + description='Part for API serial creation concurrency test', + trackable=True, + ) + + def test_concurrent_api_creation_does_not_duplicate_serial(self): + """Five concurrent API requests for the same serial number must not all succeed.""" + n_threads = 5 + start_barrier = threading.Barrier(n_threads, timeout=10) + errors = [] + results = [] + results_lock = threading.Lock() + + url = reverse('api-stock-list') + + # Wrap StockItem._lock_serial_numbers() so all five threads reach the + # (real, database-level) row lock at the same time, regardless of how + # long each request takes to reach that point. + original_lock_serial_numbers = StockItem._lock_serial_numbers + + def synced_lock_serial_numbers(part, serials): + start_barrier.wait(timeout=10) + return original_lock_serial_numbers(part, serials) + + def create(): + client = APIClient() + client.force_authenticate(user=self.user) + + try: + response = client.post( + url, + { + 'part': self.part.pk, + 'quantity': 1, + 'serial_numbers': 'SN-API-RACE', + }, + format='json', + ) + with results_lock: + results.append(response.status_code) + except Exception as exc: # pragma: no cover - surfaced via errors list + with results_lock: + errors.append(exc) + finally: + connection.close() + + threads = [threading.Thread(target=create) for _ in range(n_threads)] + + with mock.patch.object( + StockItem, '_lock_serial_numbers', synced_lock_serial_numbers + ): + for thread in threads: + thread.start() + + for thread in threads: + thread.join(timeout=15) + + for thread in threads: + self.assertFalse(thread.is_alive()) + self.assertEqual(errors, []) + + # Exactly one request must have succeeded; the rest must have been + # rejected as duplicates + self.assertEqual(results.count(201), 1) + self.assertEqual(results.count(400), n_threads - 1) + + # The serial number must only have been created once + self.assertEqual( + StockItem.objects.filter(part=self.part, serial='SN-API-RACE').count(), 1 + ) diff --git a/src/backend/InvenTree/users/admin.py b/src/backend/InvenTree/users/admin.py index cea0f9305e..ff6a84ef9c 100644 --- a/src/backend/InvenTree/users/admin.py +++ b/src/backend/InvenTree/users/admin.py @@ -118,10 +118,8 @@ class InvenTreeGroupAdminForm(forms.ModelForm): class InvenTreeUserAdmin(UserAdmin): """Custom admin page for the User model. - Hides the "permissions" view as this is now handled - entirely by groups and RuleSets. - - (And it's confusing!) + - Restrict user creation and editing to superuser accounts + - Hides the "permissions" view as this is handled by RuleSets """ list_display = ( @@ -132,6 +130,7 @@ class InvenTreeUserAdmin(UserAdmin): 'is_staff', 'last_login', ) # display last connection for each user in user admin panel. + fieldsets = ( (None, {'fields': ('username', 'password')}), (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}), @@ -142,6 +141,15 @@ class InvenTreeUserAdmin(UserAdmin): (_('Important dates'), {'fields': ('last_login', 'date_joined')}), ) + def get_readonly_fields(self, request, obj=None): + """Make all fields read-only for non-superusers.""" + fields = super().get_readonly_fields(request, obj) + + if not request.user.is_superuser: + fields += ('is_staff', 'is_superuser') + + return fields + @admin.register(Owner) class OwnerAdmin(admin.ModelAdmin): diff --git a/src/backend/InvenTree/users/api.py b/src/backend/InvenTree/users/api.py index fb2a2fc0b5..74df95bfe9 100644 --- a/src/backend/InvenTree/users/api.py +++ b/src/backend/InvenTree/users/api.py @@ -33,6 +33,7 @@ from InvenTree.mixins import ( SerializerContextMixin, UpdateAPI, ) +from InvenTree.schema import exclude_from_schema from InvenTree.settings import FRONTEND_URL_BASE from users.models import ApiToken, Owner, RuleSet, UserProfile from users.serializers import ( @@ -247,6 +248,24 @@ class MeUserDetail(RetrieveUpdateAPI, UserDetail): """ return None + @extend_schema( + parameters=[ + OpenApiParameter( + name='roles', + type=bool, + location=OpenApiParameter.QUERY, + description='Include the roles and permissions associated with the current user in the response', + ) + ] + ) + def get(self, request, *args, **kwargs): + """Retrieve details for the current user. + + Pass '?roles=true' to also include the user's roles and permissions + (previously only available via the separate '/user/me/roles/' endpoint). + """ + return super().get(request, *args, **kwargs) + class UserList(ListCreateAPI): """List endpoint for detail on all users. @@ -289,7 +308,7 @@ class GroupMixin(SerializerContextMixin): queryset = Group.objects.all() serializer_class = GroupSerializer - permission_classes = [InvenTree.permissions.IsStaffOrReadOnlyScope] + permission_classes = [InvenTree.permissions.StaffRolePermissionOrReadOnly] class GroupOutputOptions(OutputConfiguration): @@ -326,7 +345,7 @@ class RuleSetMixin: queryset = RuleSet.objects.all() serializer_class = RuleSetSerializer - permission_classes = [InvenTree.permissions.IsStaffOrReadOnlyScope] + permission_classes = [InvenTree.permissions.StaffRolePermissionOrReadOnly] class RuleSetList(RuleSetMixin, ListAPI): @@ -501,6 +520,25 @@ class UserProfileDetail(RetrieveUpdateAPI): user_urls = [ + # Legacy endpoints (to avoid breaking existing API clients) + # TODO @matmair - remove these legacy endpoints in the next breaking release + path( + 'roles/', + exclude_from_schema(RoleDetails, '/api/user/me/roles/').as_view(), + name='api-user-roles_legacy', + ), + path( + 'token/', + ensure_csrf_cookie( + exclude_from_schema(GetAuthToken, '/api/user/me/token/').as_view() + ), + name='api-token_legacy', + ), + path( + 'profile/', + exclude_from_schema(UserProfileDetail, '/api/user/me/profile/').as_view(), + name='api-user-profile_legacy', + ), # Individual user endpoints path( 'me/', diff --git a/src/backend/InvenTree/users/authentication.py b/src/backend/InvenTree/users/authentication.py index d9ccbafb5c..973e1ba92f 100644 --- a/src/backend/InvenTree/users/authentication.py +++ b/src/backend/InvenTree/users/authentication.py @@ -34,8 +34,10 @@ class ApiTokenAuthentication(TokenAuthentication): if token.last_seen != datetime.date.today(): # Update the last-seen date + # Note: Use update_fields to avoid clobbering concurrent changes to + # other fields on this token (e.g. a concurrent revocation) token.last_seen = datetime.date.today() - token.save() + token.save(update_fields=['last_seen']) return (user, token) diff --git a/src/backend/InvenTree/users/models.py b/src/backend/InvenTree/users/models.py index 54fb8ae2da..0e6e1eb316 100644 --- a/src/backend/InvenTree/users/models.py +++ b/src/backend/InvenTree/users/models.py @@ -47,9 +47,7 @@ User.add_to_class('__str__', user_model_str) # Overriding User.__str__ if settings.LDAP_AUTH: - from django_auth_ldap.backend import ( # type: ignore[unresolved-import] - populate_user, - ) + from django_auth_ldap.backend import populate_user # ty: ignore[unresolved-import] @receiver(populate_user) def create_email_address(user, **kwargs): diff --git a/src/backend/InvenTree/users/serializers.py b/src/backend/InvenTree/users/serializers.py index 417a863ae3..6b13f4577c 100644 --- a/src/backend/InvenTree/users/serializers.py +++ b/src/backend/InvenTree/users/serializers.py @@ -78,37 +78,47 @@ class RoleSerializer(InvenTreeModelSerializer): def get_roles(self, user: User) -> dict: """Roles associated with the user.""" - roles = {} - - # Cache the 'groups' queryset for the user - groups = prefetch_rule_sets(user) - - for ruleset in RULESET_CHOICES: - role, _text = ruleset - - permissions = [] - - for permission in RULESET_PERMISSIONS: - if check_user_role(user, role, permission, groups=groups): - permissions.append(permission) - - if len(permissions) > 0: - roles[role] = permissions - else: - roles[role] = None # pragma: no cover - - return roles + return get_user_roles(user) def get_permissions(self, user: User) -> dict: """Permissions associated with the user.""" - if user.is_superuser: - permissions = Permission.objects.all() - else: - permissions = Permission.objects.filter( - Q(user=user) | Q(group__user=user) - ).distinct() + return get_user_permissions(user) - return generate_permission_dict(permissions) + +def get_user_roles(user: User) -> dict: + """Return a dict of the roles associated with the given user.""" + roles = {} + + # Cache the 'groups' queryset for the user + groups = prefetch_rule_sets(user) + + for ruleset in RULESET_CHOICES: + role, _text = ruleset + + permissions = [] + + for permission in RULESET_PERMISSIONS: + if check_user_role(user, role, permission, groups=groups): + permissions.append(permission) + + if len(permissions) > 0: + roles[role] = permissions + else: + roles[role] = None # pragma: no cover + + return roles + + +def get_user_permissions(user: User) -> dict: + """Return a dict of the permissions associated with the given user.""" + if user.is_superuser: + permissions = Permission.objects.all() + else: + permissions = Permission.objects.filter( + Q(user=user) | Q(group__user=user) + ).distinct() + + return generate_permission_dict(permissions) def generate_permission_dict(permissions) -> dict: @@ -390,7 +400,7 @@ class UserSetPasswordSerializer(serializers.Serializer): ) -class MeUserSerializer(ExtendedUserSerializer): +class MeUserSerializer(FilterableSerializerMixin, ExtendedUserSerializer): """API serializer specifically for the 'me' endpoint.""" class Meta(ExtendedUserSerializer.Meta): @@ -401,7 +411,11 @@ class MeUserSerializer(ExtendedUserSerializer): """ # Remove the 'group_ids' field, as this is not relevant for the 'me' endpoint - fields = [f for f in ExtendedUserSerializer.Meta.fields if f != 'group_ids'] + fields = [ + *(f for f in ExtendedUserSerializer.Meta.fields if f != 'group_ids'), + 'roles', + 'permissions', + ] read_only_fields = [ *ExtendedUserSerializer.Meta.read_only_fields, @@ -412,6 +426,31 @@ class MeUserSerializer(ExtendedUserSerializer): profile = UserProfileSerializer(many=False, read_only=True) + # Roles and permissions are only computed (and included) when the + # request explicitly asks for them via '?roles=true' - they require + # extra queries, and most callers of this endpoint only want basic + # user details. Shares a filter_name so both come back together, since + # they were previously served as a single '/user/me/roles/' response. + roles = OptionalField( + serializer_class=serializers.SerializerMethodField, + serializer_kwargs={'read_only': True}, + filter_name='roles', + ) + + permissions = OptionalField( + serializer_class=serializers.SerializerMethodField, + serializer_kwargs={'allow_null': True, 'read_only': True}, + filter_name='roles', + ) + + def get_roles(self, user: User) -> dict: + """Roles associated with the user.""" + return get_user_roles(user) + + def get_permissions(self, user: User) -> dict: + """Permissions associated with the user.""" + return get_user_permissions(user) + # Redefine the fields from ExtendedUserSerializer, to ensure they are marked as read-only is_staff = serializers.BooleanField( label=_('Staff'), diff --git a/src/backend/InvenTree/users/test_api.py b/src/backend/InvenTree/users/test_api.py index 20cd9488d8..dc8fdfeb51 100644 --- a/src/backend/InvenTree/users/test_api.py +++ b/src/backend/InvenTree/users/test_api.py @@ -1,6 +1,7 @@ """API tests for various user / auth API endpoints.""" import datetime +from unittest import mock from django.contrib.auth.models import Group, User from django.urls import reverse @@ -473,6 +474,44 @@ class UserTokenTests(InvenTreeAPITestCase): self.client.get(me, expected_code=200) + def test_token_last_seen_no_clobber(self): + """Regression test: updating token.last_seen must overwrite other fields. + + Simulates a revoke landing in the window between this request's token + lookup and its last_seen save, by revoking the token (directly against + the database) from inside a patched ApiToken.save(). + """ + token_key = self.get( + url=reverse('api-token'), data={'name': 'race'}, expected_code=200 + ).data['token'] + + token = ApiToken.objects.get(key=token_key) + + # Force last_seen to be 'stale' so the auth backend attempts to update it + ApiToken.objects.filter(pk=token.pk).update( + last_seen=datetime.date.today() - datetime.timedelta(days=1) + ) + + original_save = ApiToken.save + + def revoke_then_save(self, *args, **kwargs): + # Simulate a concurrent request revoking this token, via a direct + # DB write, right before this request's last_seen save lands + ApiToken.objects.filter(pk=self.pk).update(revoked=True) + return original_save(self, *args, **kwargs) + + self.client.logout() + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token_key) + + with mock.patch.object(ApiToken, 'save', revoke_then_save): + self.client.get(reverse('api-user-me'), expected_code=200) + + token.refresh_from_db() + self.assertTrue( + token.revoked, + 'Concurrent revoke must not be clobbered by the last_seen update', + ) + def test_token_api(self): """Test the token API.""" url = reverse('api-token-list') @@ -547,3 +586,82 @@ class GroupDetailTests(InvenTreeAPITestCase): response = self.get(url, {'permission_detail': 'false'}, expected_code=200) self.assertNotIn('permissions', response.data) + + +class RuleSetPermissionTests(InvenTreeAPITestCase): + """Tests for permission enforcement on the Group / RuleSet API endpoints. + + Regression tests for a privilege-escalation bug where a *staff* user + (without the 'admin' role) was able to write to these endpoints - in + particular, granting themselves 'admin' RuleSet permissions via the + RuleSet API, despite not holding the 'admin' role themselves. + """ + + def test_group_write_requires_admin_role(self): + """A staff-only user (without the 'admin' role) cannot write to the Group API.""" + url = reverse('api-group-detail', kwargs={'pk': self.group.pk}) + + # Sanity check - the default test user is staff, but has no assigned roles + self.assertTrue(self.user.is_staff) + + # Read access is still permitted + self.get(url, expected_code=200) + + # Write access is rejected, as the user does not have the 'admin' role + self.patch(url, {'name': 'renamed-group'}, expected_code=403) + + self.group.refresh_from_db() + self.assertNotEqual(self.group.name, 'renamed-group') + + # Once the 'admin' role is granted, the write succeeds + self.assignRole('admin.change') + self.patch(url, {'name': 'renamed-group'}, expected_code=200) + + self.group.refresh_from_db() + self.assertEqual(self.group.name, 'renamed-group') + + def test_ruleset_write_requires_admin_role(self): + """A staff-only user cannot self-escalate permissions via the RuleSet API.""" + admin_ruleset = self.group.rule_sets.get(name='admin') + url = reverse('api-ruleset-detail', kwargs={'pk': admin_ruleset.pk}) + + # Sanity check - the default test user is staff, but has no assigned roles + self.assertTrue(self.user.is_staff) + self.assertFalse(admin_ruleset.can_change) + + # Read access is still permitted + self.get(url, expected_code=200) + + # Attempt to self-escalate to full 'admin' ruleset permissions + self.patch( + url, + {'can_view': True, 'can_add': True, 'can_change': True, 'can_delete': True}, + expected_code=403, + ) + + admin_ruleset.refresh_from_db() + self.assertFalse(admin_ruleset.can_change) + + # Granting the 'admin' role directly (not via the API) allows the write + self.assignRole('admin.change') + self.patch(url, {'can_delete': True}, expected_code=200) + + admin_ruleset.refresh_from_db() + self.assertTrue(admin_ruleset.can_delete) + + def test_non_staff_user_read_only(self): + """A non-staff, non-admin authenticated user retains read-only access.""" + self.user.is_staff = False + self.user.save() + + group_url = reverse('api-group-detail', kwargs={'pk': self.group.pk}) + ruleset_url = reverse( + 'api-ruleset-detail', + kwargs={'pk': self.group.rule_sets.get(name='admin').pk}, + ) + + self.get(group_url, expected_code=200) + self.get(ruleset_url, expected_code=200) + + self.patch(group_url, {'name': 'renamed-group'}, expected_code=403) + self.patch(ruleset_url, {'can_change': True}, expected_code=403) diff --git a/src/backend/InvenTree/web/tests.py b/src/backend/InvenTree/web/tests.py index 04a25b73a1..41190526dc 100644 --- a/src/backend/InvenTree/web/tests.py +++ b/src/backend/InvenTree/web/tests.py @@ -30,7 +30,7 @@ class TemplateTagTest(InvenTreeTestCase): shipped_js = resp.split('
    {{ item.part.full_name }}{{ item.quantity }}